Kubernetes里第一个控制器模式的完整实现:Deployment。Deployment 看似简单,但实际上,它实现了 Kubernetes 项目中一个非常重要的功能:Pod的“水平扩展 / 收缩”(horizontal scaling out/in)。这个功能,是从 PaaS 时代开始,一个平台级项目就必须具备的编排能力。
实例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Deployment、ReplicaSet与Pod的关系
image.png
通过这张图,我们就很清楚的看到,一个定义了 replicas=3 的 Deployment,与它的ReplicaSet,以及 Pod 的关系,实际上是一种“层层控制”的关系。其中,ReplicaSet 负责通过“控制器模式”,保证系统中 Pod 的个数永远等于指定的个数。这也正是 Deployment 只允许容器的 restartPolicy=Always 的主要原因:只有在容器能保证自己始终是 Running 状态的前提下,ReplicaSet 调整 Pod 的个数才有意义。而在此基础上,Deployment 同样通过“控制器模式”,来操作 ReplicaSet 的个数和属性,进
而实现“水平扩展 / 收缩”和“滚动更新”这两个编排动作
kubectl scale deployment nginx-deployment --replicas=3
kubectl get pods
nginx-deployment-69fbc8b64f-4f97r 1/1 Running 0 95m
nginx-deployment-69fbc8b64f-4n9nj 1/1 Running 0 95m
nginx-deployment-69fbc8b64f-wdjcs 1/1 Running 0 95m
kubectl create -f nginx-deployment.yaml --record
#record 的作用在于记录每次操作的命令
查看deployment的状态
[root@k8s-master pods]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 3h39m
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 0 0 0 3h40m
nginx-deployment-69fbc8b64f 3 3 3 3h40m
#可以看到,在deployment的名字的最后为随机数,该值为hash值,通过kubectl describle deployment nginx-deployment-69fbc8b64f 查看到
- UP-TO-DATE:当前处于最新版本的 Pod 的个数,所谓最新版本指的是 Pod 的 Spec 部分
与 Deployment 里 Pod 模板里定义的完全一致
- AVAILABLE:当前已经可用的 Pod 的个数,即:既是 Running 状态,又是最新版本,并
且已经处于 Ready(健康检查正确)状态的 Pod 的个数 - DESIRED:用户期望的 Pod 副本个数(spec.replicas 的值)
- CURRENT:当前处于 Running 状态的 Pod 的个数
实时查看deployment的状态
[root@k8s-master pods]# kubectl rollout status deployment/nginx-deployment
deployment.apps/nginx-deployment successfully rolled out
滚动更新
通过edit修改etcd在的API对象
kubectl edit deployment nginx-deployment-69fbc8b64f
#通过修改镜像的版本,达到滚动更新的效果
# revisionHistoryLimit: 10 历史记录最大条数
# maxSurge: 25% 滚动更新时,最大启动的台数
# maxUnavailable: 25% 滚动更新时,最大不可用的台数
#当然,kubectl edit 并不神秘,它不过是把 API 对象的内容下载到了本地文件,让你修改完成后再提交上去
查看结果
kubectl describe deployment nginx-deployme
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 35m deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 2
Normal ScalingReplicaSet 5m17s deployment-controller Scaled up replica set nginx-deployment-5875d75456 to 1
Normal ScalingReplicaSet 3m deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 1
Normal ScalingReplicaSet 3m deployment-controller Scaled up replica set nginx-deployment-5875d75456 to 2
Normal ScalingReplicaSet 85s deployment-controller Scaled down replica set nginx-deployment-59c9f8dff to 0
#可以看到是停止一个旧pod,启动一个新pod,直到所有的pod均换为新镜像启动的pod
#查看depliyment的状态
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 2 2 2 54s
nginx-deployment-69fbc8b64f 1 1 0 14s
[root@k8s-master pods]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-59c9f8dff 0 0 0 81s
nginx-deployment-69fbc8b64f 2 2 2 41s
滚动更新的优势:在升级刚开始的时候,集群里只有 1 个新版本的 Pod。如果这时,新版本 Pod 有问题启动不起来,那么“滚动更新”就会停止,从而允许开发和运维人员介入。而在这个过程中,由于
应用本身还有两个旧版本的 Pod 在线,所以服务并不会受到太大的影响
#修改pod的镜像,作用与上面的一致
kubectl set image deployment/nginx-deployment nginx=nginx:1.91
回滚的方法
kubectl rollout undo deployment/nginx-deployme
#直接回滚到上一各版本
#回滚到指定版本
kubectl rollout history deployment/nginx-deployment #查看所有的历史版本,使用record会有记录,否则不会有命令
#回滚
kubectl rollout undo deployment/nginx-deployment --to-revision=2
#查看特定版本的信息
kubectl rollout history deployment/nginx-deployment --revision=2
我们对 Deployment 的多次更新操作,最后只生成一个 ReplicaSet
使 Deployment 进入暂停状态
kubectl rollout pause deployment nginx-deployment
你就可以随意使用 kubectl edit 或者 kubectl set image 指令,修改这个Deployment 的内容了。
由于此时 Deployment 正处于“暂停”状态,所以我们对 Deployment 的所有修改,都不会触发新的“滚动更新”,也不会创建新的 ReplicaSet。
kubectl rollout resume deploy/nginx-deployment
恢复deployment,触发执行最后一次滚动更新
网友评论