pod控制器及其功能
Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类:
- 自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建
- 控制器创建的pod:kubernetes通过控制器创建的pod,这种pod删除了之后还会自动重建
什么是pod控制器
Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的 Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资 源在运行中出现故障,它会基于指定策略重新编排Pod。
pod控制器有多种类型:
在kubernetes中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有下面这些: 1、ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代
2、ReplicaSet: 待用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动 式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
(1)用户期望的pod副本数量
(2)标签选择器,判断哪个pod归自己管理
(3)当现存的pod数量不足,会根据pod资源模板进行新建 帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制 器,而是使用Deployment。
3、Deployment:通过控制ReplicaSet来控制Pod,用于管理无状态应用,目前来说最好的控制器。支 持滚动更新和回滚功能,还提供声明式配置。
4、DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任 务。比如ELK服务,特性:服务是无状态的,服务必须是守护进程
5、Job:只要完成就立即退出,不需要重启或重建。用于执行一次性任务
6、Cronjob:周期性任务控制,不需要持续后台运行
7、StatefulSet:管理有状态应用 注:有状态和无状态(站在服务器这角度容易理解) 状态(公共交互)信息是由请求方还是响应方负责保存,请求方保存就是无状态,响应方保存就是有状 态。
ReplicaSet控制器(RS)
ReplicaSet的主要作用是保证一定数量的pod正常运行,它会持续监听这些Pod的运行状态,一旦Pod发 生故障,就会重启或重建。同时它还支持对pod数量的扩缩容和镜像版本的升降级。 虽然ReplicaSet可以独立使用,但一般还是建议使用 Deployment 来自动管理ReplicaSet,这样就无需 担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。
ReplicaSet的资源清单文件:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: rs
spec: # 详情描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
在这里面,需要新了解的配置项就是 spec 下面几个选项:
replicas:指定副本数量,其实就是当前rs创建出来的pod的数量,默认为1
selector:选择器,它的作用是建立pod控制器和pod之间的关联关系,采用的Label Selector机制 在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了 template:模板,就是当前控制器创建pod所使用的模板,里面其实就是前一章学过的pod的定义
创建ReplicaSet
创建pc-replicaset.yaml文件,内容如下:
cat > pc-replicaset.yaml << EOF
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: pc-replicaset
namespace: dev
labels:
controller: rs
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
EOF
# 创建rs
[root@k8s-master01 ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 查看rs
# DESIRED:期望副本数量
# CURRENT:当前副本数量
# READY:已经准备好提供服务的副本数量
[root@k8s-master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
SELECTOR
pc-replicaset 3 3 3 22s nginx nginx:1.17.1
app=nginx-pod
# 查看当前控制器创建出来的pod
# 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码
[root@k8s-master01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 54s
pc-replicaset-fmb8f 1/1 Running 0 54s
pc-replicaset-snrk2 1/1 Running 0 54s
扩缩容
# 编辑rs的副本数量,修改spec:replicas: 6即可
[root@k8s-master01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 114m
pc-replicaset-cftnp 1/1 Running 0 10s
pc-replicaset-fjlm6 1/1 Running 0 10s
pc-replicaset-fmb8f 1/1 Running 0 114m
pc-replicaset-s2whj 1/1 Running 0 10s
pc-replicaset-snrk2 1/1 Running 0 114m
# 当然也可以直接使用命令实现
# 使用scale命令实现扩缩容, 后面--replicas=n直接指定目标数量即可
[root@k8s-master01 ~]# kubectl scale rs pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
# 命令运行完毕,立即查看,发现已经有4个开始准备退出了
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 0/1 Terminating 0 118m
pc-replicaset-cftnp 0/1 Terminating 0 4m17s
pc-replicaset-fjlm6 0/1 Terminating 0 4m17s
pc-replicaset-fmb8f 1/1 Running 0 118m
pc-replicaset-s2whj 0/1 Terminating 0 4m17s
pc-replicaset-snrk2 1/1 Running 0 118m
#稍等片刻,就只剩下2个了
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-fmb8f 1/1 Running 0 119m
pc-replicaset-snrk2 1/1 Running 0 119m
镜像升级
# 编辑rs的容器镜像 - image: nginx:1.17.2
[root@k8s-master01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 再次查看,发现镜像版本已经变更了
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
...
pc-replicaset 2 2 2 140m nginx nginx:1.17.2
...
# 同样的道理,也可以使用命令完成这个工作
# kubectl set image rs rs名称 容器=镜像版本 -n namespace
[root@k8s-master01 ~]# kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n
dev
replicaset.apps/pc-replicaset image updated
# 再次查看,发现镜像版本已经变更了
[root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
...
pc-replicaset 2 2 2 145m nginx nginx:1.17.1
删除ReplicaSet
# 使用kubectl delete命令会删除此RS以及它管理的Pod
# 在kubernetes删除RS前,会将RS的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象
的删除
[root@k8s-master01 ~]# kubectl delete rs pc-replicaset -n dev
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 ~]# kubectl get pod -n dev -o wide
No resources found in dev namespace.
# 如果希望仅仅删除RS对象(保留Pod),可以使用kubectl delete命令时添加--cascade=false选项
(不推荐)。
[root@k8s-master01 ~]# kubectl delete rs pc-replicaset -n dev --cascade=false
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-cl82j 1/1 Running 0 75s
pc-replicaset-dslhb 1/1 Running 0 75s
# 也可以使用yaml直接删除(推荐)
[root@k8s-master01 ~]# kubectl delete -f pc-replicaset.yaml
replicaset.apps "pc-replicaset" deleted
Deployment控制器(Deploy)
为了更好的解决服务编排的问题,kubernetes在V1.2版本开始,引入了Deployment控制器。值得一提 的是,这种控制器并不直接管理pod,而是通过管理ReplicaSet来简介管理Pod,即:Deployment管理 ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。
Deployment主要功能有下面几个:
- 支持ReplicaSet的所有功能
- 支持发布的停止、继续
- 支持滚动升级和回滚版本
Deployment创建的过程
(1)用户通过kubectl创建Deployment
(2)Deployment创建ReplicaSet
(3)ReplicaSet创建Pod
从官方的定义来看Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更 新。那到底这是什么意思呢?下面我们举一个简单的例子来说明。
l 使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失 败。
l 然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的 ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
l 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的 revision。
l 扩容Deployment以满足更高的负载。
l 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
l 根据Deployment 的状态判断上线是否hang住了。 l 清除旧的不必要的ReplicaSet。
创建deployment
使用命令快速创建deploy
kubectl create deployment net-test --replicas=3 --image=nginx:latest
查看deployment
kubectl get deploy
使用deployment资源清单创建
创建pc-deployment.yaml,内容如下:
cat > pc-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
EOF
apiVersion对应的值是 apps/v1
kind要指定为Deployment指定一些 meta 信息,比如名字,或者标签
spec配置选项,这里我们定义需要两个副本,当然还有很多可以设置的属性,比如一个 Pod 在没有任何错误
变成准备的情况下必须达到的最小秒数
# 创建deployment
[root@k8s-master01 ~]# kubectl create -f pc-deployment.yaml --record=true
deployment.apps/pc-deployment created
# 查看deployment
# UP-TO-DATE 最新版本的pod的数量
# AVAILABLE 当前可用的pod的数量
[root@k8s-master01 ~]# kubectl get deploy pc-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 3/3 3 3 15s
# 查看rs
# 发现rs的名称是在原来deployment的名字后面添加了一个10位数的随机串
[root@k8s-master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 3 3 3 23s
# 查看pod
[root@k8s-master01 ~]# kubectl get pods |grep pc-deployment
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 107s
pc-deployment-6696798b78-smpvp 1/1 Running 0 107s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 107s
deployment扩缩容
# 变更副本数量为5个
[root@k8s-master01 ~]# kubectl scale deploy pc-deployment --replicas=5
deployment.apps/pc-deployment scaled
# 查看deployment
[root@k8s-master01 ~]# kubectl get deploy pc-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 2m
# 查看pod
[root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 4m19s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 94s
pc-deployment-6696798b78-mktqv 1/1 Running 0 93s
pc-deployment-6696798b78-smpvp 1/1 Running 0 4m19s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 4m19s
# 编辑deployment的副本数量,修改spec:replicas: 4即可
[root@k8s-master01 ~]# kubectl edit deploy pc-deployment
deployment.apps/pc-deployment edited
# 查看pod
[root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pc-deployment-6696798b78-d2c8n 1/1 Running 0 5m23s
pc-deployment-6696798b78-jxmdq 1/1 Running 0 2m38s
pc-deployment-6696798b78-smpvp 1/1 Running 0 5m23s
pc-deployment-6696798b78-wvjd8 1/1 Running 0 5m23s
滚动升级
deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,下面具体来看. kubectl rollout: 版本升级相关功能,支持下面的选项:
status 显示当前升级状态
history 显示 升级历史记录
pause 暂停版本升级过程
resume 继续已经暂停的版本升级过程
restart 重启版本升级过程
undo 回滚到上一级版本(可以使用--to-revision回滚到指定版本)
变更镜像
kubectl set image deployment pc-deployment nginx=nginx:1.17.3 --record
观察升级过程
kubectl rollout status deploy pc-deployment
kubectl get pods -w
镜像更新中rs的变化:
观察rs
kubectl get rs
rs不会消失,保证回滚
查看升级历史,回滚
kubectl rollout history deploy pc-deployment
版本回滚
# 这里直接使用--to-revision=1回滚到了1版本, 如果省略这个选项,就是回退到上个版本,就是2版本
[root@k8s-master01 ~]# kubectl rollout undo deployment pc-deployment --torevision=1
金丝雀发布
Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。
比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分 还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期 望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是 所谓的金丝雀发布。
# 更新deployment的版本,并配置暂停deployment
[root@k8s-master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4
&& kubectl rollout pause deployment pc-deployment
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused
#观察更新状态
[root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 4 new
replicas have been updated...
# 监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为
使用了pause暂停命令
[root@k8s-master01 ~]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS
IMAGES
pc-deployment-5d89bdfbf9 3 3 3 19m nginx
nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 14m nginx
nginx:1.17.2
pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx
nginx:1.17.4
[root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
pc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
pc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 确保更新的pod没问题了,继续更新
[root@k8s-master01 ~]# kubectl rollout resume deploy pc-deployment
deployment.apps/pc-deployment resumed
# 查看最后的更新情况
[root@k8s-master01 ~]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS
IMAGES
pc-deployment-5d89bdfbf9 0 0 0 21m nginx
nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 16m nginx
nginx:1.17.2
pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx
nginx:1.17.4
[root@k8s-master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pc-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37s
删除deployment
# 删除deployment,其下的rs和pod也将被删除
[root@k8s-master01 ~]# kubectl delete -f pc-deployment.yaml
deployment.apps "pc-deployment" deleted
快速创建yaml文件
方式一、使用kubectl create命令生成yaml文件
kubectl create deployment web --image=nginx -o yaml --dry-run=server >m1.yaml
只生成yaml文件,并不真正执行。
方式二、使用kubectl get命令导出yaml文件
kubectl create deployment nginx-web --image=nginx
kubectl get deploy 如果有名为nginx-web的deployment
kubectl get deploy nginx-web -o yaml > m2.yaml 根据部署好的,导出yaml文件