一、简介
- 全自动容器部署工具–持续部署
- 谷歌的开源工具,开发运维一体化的标准化工具
- Kubernetes:
k8s–k和s直接有8个字母(国际化)
kube
二、集群方案
方案一:使用三台物理机或VMware虚拟机来搭建集群环境,一台主控服务器,两台工作节点服务器。
调整 VMware 虚拟机的内存和 cpu:
方案二:如果资源有限也可以去掉一个工作节点,使用两台服务器。这里主控服务器也当作节点
三、k8s安装准备
1 集群搭建开源工具
-
一键安装
项目 https://github.com/easzlab/kubeasz极大的简化了k8s集群的安装过程,他提供的工具可以轻松安装和管理k8s集群。 -
手把手,手动安装
2 准备主控服务器
主控服务器 ip:192.168.64.191 命名k1 设置内存2G
文件下载准备:
链接:https://pan.baidu.com/s/1QZNCbDmPtj6AyKqK6qhKvQ 提取码:uvi4
- images.gz传到/root/
- 解压 kubeasz-3.1.0.zip 文件
- 解压的ezdown传到/root/
- 解压的kubeasz文件夹传到/etc/
下载离线文件,安装Docker
在主控服务器上下载安装环境初始化脚本工具 ezdown
export release=3.1.0
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/ezdown
# 前面已经上传了ezdown文件夹,可以省略上面两个步骤
chmod +x ./ezdown
使用工具脚本下载离线文件,并安装Docker
默认下载最新推荐k8s/docker等版本(更多关于ezdown的参数,运行./ezdown 查看)
./ezdown -D
回到/root目录,导入 docker 镜像,后面使用这些镜像用来测试 k8s:
docker load -i images.gz
可选下载离线系统包 (适用于无法使用yum/apt仓库情形) ./ezdown -P
上述脚本运行成功后,所有文件(kubeasz代码、二进制、离线镜像)均已整理好放入目录/etc/kubeasz
/etc/kubeasz 包含 kubeasz 版本为 ${release} 的发布代码
/etc/kubeasz/bin 包含 k8s/etcd/docker/cni 等二进制文件
/etc/kubeasz/down 包含集群安装时需要的离线容器镜像
/etc/kubeasz/down/packages 包含集群安装时需要的系统基础软件
安装 python、pip、ansible
ansible
是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
kubeasz 使用 ansible 来自动安装配置集群,所以这里先要安装 ansible
。
yum install python -y
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py
python get-pip.py
python -m pip install --upgrade "pip < 21.0"
pip install ansible -i https://mirrors.aliyun.com/pypi/simple/
3 工作节点
在工作节点服务器上
k2-ip: 192.168.64.192
k3-ip:192.168.64.193
重复以上所有操作。
如果使用 VMware 虚拟机,只需要从第一台服务器(k1)克隆即可。
四、配置集群安装环境
启动 kubeasz 容器(临时容器) ./ezdown -S
设置参数允许离线安装 sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/kubeasz/example/config.yml
配置免密登录其他服务器,生成公钥和私钥
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa
ssh-copy-id 192.168.64.191
ssh-copy-id 192.168.64.192
ssh-copy-id 192.168.64.193
创建集群配置
cd /etc/kubeasz
chmod +x ezctl
./ezctl new cs1
配置服务器地址
vim /etc/kubeasz/clusters/cs1/hosts
这是集群方案一:一台主控服务器,两台工作节点服务器 etcd相当于注册中心
如果内存有限, 可以只部署两台服务器进行测试
两台 主服务器既作为控制节点, 又作为工作节点
减少etcd服务数量
为防止后面执行一键安装失败,建议这里把三台服务器拍照,后面修改配置好立即恢复
执行一键安装
cd /etc/kubeasz
./ezctl setup cs1 all
设置 kubectl 命令的别名
# 设置 kubectl 命令别名 k
echo "alias k='kubectl'" >> ~/.bashrc
# 使设置生效
source ~/.bashrc
查看集群状态 k get cs
#cs指cluster,健康状态Healthy
[root@localhost kubeasz]# k get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-1 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
查看节点状态 k get no
,no也可全写node,指node节点,就绪状态Ready
[root@localhost kubeasz]# k get no
NAME STATUS ROLES AGE VERSION
192.168.64.191 Ready,SchedulingDisabled master 40h v1.21.0
192.168.64.192 Ready node 40h v1.21.0
192.168.64.193 Ready node 40h v1.21.0
五、三个核心概念
1 控制器
自动控制容器的部署和销毁、自动伸缩
2 pod容器
k8s 对 docker 容器的封装对象
3 Service
不变的访问地址,通过 Service 向容器转发调用
六、控制器ReplicationController
RC可以自动化维护多个pod,只需指定pod副本的数量,就可以轻松实现自动扩容缩容
当一个pod宕机,RC可以自动关闭pod,并启动一个新的pod替代它
下面是一个RC的部署文件,设置启动三个kubia容器:
cat <<EOF > kubia-rc.yml
apiVersion: v1
kind: ReplicationController # 资源类型
metadata:
name: kubia # 为RC命名
spec:
replicas: 3 # pod副本的数量
selector: # 选择器,用来选择RC管理的pod
app: kubia # 选择标签'app=kubia'的pod,由当前RC进行管理
template: # pod模板,用来创建新的pod
metadata:
labels:
app: kubia # 指定pod的标签
spec:
containers: # 容器配置
- name: kubia # 容器名
image: luksa/kubia # 镜像
imagePullPolicy: Never
ports:
- containerPort: 8080 # 容器暴露的端口
EOF
根据指定的配置文件创建RC
[root@localhost ~]# k create -f kubia-rc.yml
replicationcontroller/kubia created
RC创建后,会根据指定的pod数量3,自动创建3个pod
[root@localhost ~]# k get rc
NAME DESIRED CURRENT READY AGE
kubia 3 3 3 9s
desired 想要部署的容器个数
current 当前已经部署的容器
ready 启动成功,处于就绪状态的容器
查看容器k get po
,容器是控制器自动创建的
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 0 61m
kubia-gg57q 1/1 Running 0 61m
kubia-tvhr9 1/1 Running 0 61m
七、pod自定伸缩
k8s对应用部署节点的自动伸缩能力非常强,只需要指定需要运行多少个pod,k8s就可以完成pod的自动伸缩
# 对别名为kubia的控制器将pod数量缩容1个
[root@localhost ~]# k scale rc kubia --replicas=1
replicationcontroller/kubia scaled
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 0 75m
kubia-gg57q 1/1 Terminating 0 75m
kubia-tvhr9 1/1 Terminating 0 75m
#Terminating容器最终会完全杀掉
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 0 76m
[root@localhost ~]# k scale rc kubia --replicas=3
八、使用 service 对外暴露 pod
#创建Service
k expose \
rc kubia \
--type=NodePort \
--name kubia-http #Service别名
[root@localhost ~]# k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 45h
#30224服务器暴露的端口
kubia-http NodePort 10.68.59.96 <none> 8080:30224/TCP 14s
这里创建了一个 service 组件,用来对外暴露pod访问,在所有节点服务器上,暴露了30224端口,通过此端口,可以访问指定pod的8080端口
访问以下节点服务器的20916端口,都可以访问该应用
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 2 23h
kubia-6s5ns 1/1 Running 2 22h
kubia-fd88s 1/1 Running 2 22h
[root@localhost ~]# curl http://192.168.64.191:30224
You've hit kubia-fd88s #命中的容器的名称
[root@localhost ~]# curl http://192.168.64.191:30224
You've hit kubia-6s5ns
[root@localhost ~]# curl http://192.168.64.191:30224
You've hit kubia-6gtnh
每次请求容器更换啦,默认是负载均衡。
浏览器请求容器没有变化,因为浏览器缓存了一个长连接
访问 http://192.168.64.191:30224/
九、pod
1 使用部署文件手动部署pod
创建kubia-manual.yml
部署文件
cat <<EOF > kubia-manual.yml
apiVersion: v1 # k8s api版本
kind: Pod # 该部署文件用来创建pod资源
metadata:
name: kubia-manual # pod名称前缀,后面会追加随机字符串
spec:
containers: # 对pod中容器的配置
- image: luksa/kubia # 镜像名
imagePullPolicy: Never
name: kubia # 容器名
ports:
- containerPort: 8080 # 容器暴露的端口
protocol: TCP
EOF
使用部署文件创建pod ,kubia-manual就是我们部署的pod名称
[root@localhost ~]# k create -f kubia-manual.yml
pod/kubia-manual created
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 2 23h
kubia-6s5ns 1/1 Running 2 22h
kubia-fd88s 1/1 Running 2 22h
kubia-manual 1/1 Running 0 60s
查看pod部署到哪台服务器上k get po -o wide
(wide宽表,显示更多字段,有NODE就是指服务器),pod一般部署在工作节点上
[root@localhost ~]# k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubia-6gtnh 1/1 Running 2 23h 172.20.1.4 192.168.64.193 <none> <none>
kubia-6s5ns 1/1 Running 2 22h 172.20.2.2 192.168.64.192 <none> <none>
kubia-fd88s 1/1 Running 2 22h 172.20.2.3 192.168.64.192 <none> <none>
kubia-manual 1/1 Running 0 2m57s 172.20.1.5 192.168.64.193 <none> <none>
2 pod 标签
可以为 pod 指定标签,通过标签可以对 pod 进行分组管理ReplicationController,ReplicationSet,Service中,都可以通过 Label 来分组管理 pod
2.1 创建pod时指定标签
通过kubia-manual-with-labels.yml
部署文件部署pod
在部署文件中为pod设置了两个自定义标签:creation_method
和env
cat <<EOF > kubia-manual-with-labels.yml
apiVersion: v1 # api版本
kind: Pod # 部署的资源类型
metadata:
name: kubia-manual-v2 # pod名
labels: # 标签设置,键值对形式
creation_method: manual
env: prod
spec:
containers: # 容器设置
- image: luksa/kubia # 镜像
name: kubia # 容器命名
imagePullPolicy: Never
ports: # 容器暴露的端口
- containerPort: 8080
protocol: TCP
EOF
使用部署文件创建资源 k create -f kubia-manual-with-labels.yml
列出所有的pod,并显示pod的标签k get po --show-labels
[root@localhost ~]# k get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
kubia-6gtnh 1/1 Running 3 27h app=kubia
kubia-6s5ns 1/1 Running 3 26h app=kubia
kubia-fd88s 1/1 Running 3 26h app=kubia
kubia-manual 1/1 Running 1 4h14m <none>
kubia-manual-v2 1/1 Running 0 30s creation_method=manual,env=prod
2.2 对pod设置标签
对已有容器设置标签creation_method=manual,env=prod kubectl label po kubia-manual creation_method=manual env=prod
2.3 修改标签的值
pod kubia-manual-v2 的env标签值是prod, 我们把这个标签的值修改为 debug
修改一个标签的值时,必须指定 --overwrite
参数,目的是防止误修改
kubectl label po kubia-manual-v2 env=debug --overwrite
2.4 使用标签来查询 pod
k get po --show-labels -l creation_method=manual #查询 creation_method=manual 的pod
k get po --show-labels -l env #查询有 env 标签的 pod
k get po --show-labels -l creation_method=manual,env=debug #查询 creation_method=manual 并且 env=debug 的 pod
k get po --show-labels -l '!creation_method' #查询不存在 creation_method 标签的 pod
其他查询举例:
creation_method!=manual
env in (prod,debug)
env notin (prod,debug)
2.5 删除pod上的标签
删除pod上的env
标签 kubectl label po kubia-6gtnh env-
2.6 把pod部署到指定的节点服务器
我们不能直接指定服务器的地址来约束pod部署的节点
通过为node设置标签,在部署pod时,使用节点选择器,来选择把pod部署到匹配的节点服务器
创建 kubia-gpu.yml文件,其中节点选择器nodeSelector
设置了通过标签gpu=true
来选择节点
cat <<EOF > kubia-gpu.yml
apiVersion: v1
kind: Pod
metadata:
name: kubia-gpu # pod名
spec:
nodeSelector: # 节点选择器,把pod部署到匹配的节点
gpu: "true" # 通过标签 gpu=true 来选择匹配的节点
containers: # 容器配置
- image: luksa/kubia # 镜像
name: kubia # 容器名
imagePullPolicy: Never
EOF
创建pod容器,名称为 kubia-gpu,并查看pod的部署节点
[root@localhost ~]# k create -f kubia-gpu.yml
pod/kubia-gpu created
[root@localhost ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-6gtnh 1/1 Running 3 28h
kubia-6s5ns 1/1 Running 3 27h
kubia-fd88s 1/1 Running 3 27h
kubia-gpu 0/1 Pending 0 23s
kubia-manual 1/1 Running 1 4h52m
kubia-manual-v2 1/1 Running 0 38m
发现名为kubia-gpu的pod容器状态为Pending
状态,并且命令k get po -o wide
查看该pod的节点为空,因为此时服务器没有贴gpu=true
的标签,该pod容器没有部署到任何一台服务器上
给服务器贴gpu=true标签 kubectl lable no 192.168.64.192 gpu=true
在命令k get po -o wide
查看kubia-gpu pod容器部署状态,发现已成功部署在192.168.64.192节点上
十、namespace
可以使用命名空间对资源进行组织管理
不同命名空间的资源并不完全隔离,它们之间可以通过网络互相访问
1 创建命名空间
新建部署文件custom-namespace.yml
,创建命名空间,命名为custom-namespace
cat <<EOF > custom-namespace.yml
apiVersion: v1
kind: Namespace
metadata:
name: custom-namespace
EOF
# 创建命名空间
[root@localhost ~]# k create -f custom-namespace.yml
namespace/custom-namespace created
# 查看命名空间
[root@localhost ~]# k get ns
NAME STATUS AGE
custom-namespace Active 5s
default Active 4d8h
kube-node-lease Active 4d8h
kube-public Active 4d8h
kube-system Active 4d8h
2 查看命名空间
# namespace
k get ns
k get po --namespace kube-system
k get po -n kube-system
3 将pod部署到指定的命名空间中
创建pod
,并将其部署到命名空间custom-namespace
# 创建 Pod 时指定命名空间
k create \
-f kubia-manual.yml \
-n custom-namespace
# 默认访问default命名空间,默认命名空间中不存在pod kubia-manual
k get po kubia-manual
# 访问custom-namespace命名空间中的pod
k get po kubia-manual -n custom-namespace
----------------------------------------------------------
NAME READY STATUS RESTARTS AGE
kubia-manual 0/1 Running 0 59s
十一、存活探针
有三种存活探针:
- HTTP GET 返回 2xx 或 3xx 响应码则认为探测成功
- TCP 与指定端口建立 TCP 连接,连接成功则为成功
- Exec 在容器内执行任意的指定命令,并检查命令的退出码,退出码为0则为探测成功
1 HTTP GET 存活探针
luksa/kubia-unhealthy 镜像
在kubia-unhealthy镜像中,应用程序作了这样的设定: 从第6次请求开始会返回500错,在部署文件中,我们添加探针,来探测容器的健康状态.探针默认每10秒探测一次,连续三次探测失败后重启容器(即探测八次后开始重启容器)
cat <<EOF > kubia-liveness-probe.yml
apiVersion: v1
kind: Pod
metadata:
name: kubia-liveness # pod名称
spec:
containers:
- image: luksa/kubia-unhealthy # 镜像
name: kubia # 容器名
imagePullPolicy: Never
livenessProbe: # 存活探针配置
httpGet: # HTTP GET 类型的存活探针
path: / # 探测路径
port: 8080 # 探测端口
EOF
创建 pod
k create -f kubia-liveness-probe.yml
# pod的RESTARTS属性,每过1分半种就会加1
k get po kubia-liveness
--------------------------------------------------
NAME READY STATUS RESTARTS AGE
kubia-liveness 1/1 Running 0 5m25s
查看上一个pod的日志,前5次探测是正确状态,后面3次探测是失败的,则该pod会被删除
kubectl logs kubia-liveness --previous #选项--previous指上一个容器日志
----------------------------
Kubia server starting...
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
Received request from ::ffff:172.20.1.1
查看pod描述
k describe po kubia-liveness
---------------------------------
......
Restart Count: 6
Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
......
delay
0表示容器启动后立即开始探测timeout
1表示必须在1秒内响应,否则视为探测失败period
10s表示每10秒探测一次failure
3表示连续3次失败后重启容器
删除容器kubectl delete po kubia-liveness
通过设置 delay 延迟时间,可以避免在容器内应用没有完全启动的情况下就开始探测
cat <<EOF > kubia-liveness-probe-initial-delay.yml
apiVersion: v1
kind: Pod
metadata:
name: kubia-liveness
spec:
containers:
- image: luksa/kubia-unhealthy
name: kubia
imagePullPolicy: Never
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 15 # 第一次探测的延迟时间
EOF
[root@localhost ~]# k create -f kubia-liveness-probe-initial-delay.yml
pod/kubia-liveness created
[root@localhost ~]# kubectl logs kubia-liveness
Kubia server starting...
十二、删除资源
# 按名称删除, 可以指定多个名称
# 例如: k delete po po1 po2 po3
k delete po kubia-gpu
# 按标签删除
k delete po -l creation_method=manual
# 删除命名空间和其中所有的pod
k delete ns custom-namespace
# 删除当前命名空间中所有pod
k delete po --all
# 由于有ReplicationController,所以会自动创建新的pod
[root@master1 ~]# k get po
NAME READY STATUS RESTARTS AGE
kubia-m6k4d 1/1 Running 0 2m20s
kubia-rkm58 1/1 Running 0 2m15s
kubia-v4cmh 1/1 Running 0 2m15s
# 删除工作空间中所有类型中的所有资源
# 这个操作会删除一个系统Service kubernetes,它被删除后会立即被自动重建
k delete all --all