一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。
Kubernetes中的Deployment是一种资源对象,用于定义和管理Pod的副本集。它提供了一种声明式的方式来创建、更新和删除Pod副本。Deployment可以确保指定数量的Pod副本在集群中运行,并且可以自动处理Pod的扩容和缩容。
Deployment通过使用ReplicaSet(RS)来实现Pod的副本控制。RS是一个控制器,它确保指定数量的Pod副本在集群中运行,并且可以根据需要进行扩展或缩减。Deployment通过与RS进行交互来创建和管理Pod副本。
Deployment还提供了滚动更新的功能,可以在不中断服务的情况下逐步更新Pod副本。通过指定更新策略和版本号,Deployment可以自动创建新的Pod副本并逐步替换旧的Pod副本,从而实现无缝的应用程序更新。
总结起来,Kubernetes中的Deployment是一种用于定义和管理Pod副本集的资源对象,它通过与ReplicaSet进行交互来实现Pod的副本控制,并提供了滚动更新的功能。当创建一个Deployment时,ReplicaSet资源也会随之创建(最终会有更多的资源被创建)。ReplicaSet是新一代的ReplicationController,并推荐使用它替代ReplicationController来复制和管理pod。在使用Deployment时,实际的pod 是由Deployment的Replicaset创建和管理的,而不是由Deployment直接创建和管理的(如图所示):
在k8s中对象常常都是以一个yaml格式的文件来定义的,deployment的定义如下:
apiVersion: apps/v1 #版本号
kind: Deployment #类型
metadata: #元数据
name: #rs名称
namespace: #所属命名空间
labels: #标签
controller: deploy
spec: # 定义规格
replicas: #副本数量
revisionHistoryLimit: #保留历史版本,默认是10
paused: #暂停部署,默认是false
progressDeadlineSeconds: #部署超时时间(s),默认是600
strategy: #策略
type: RollingUpdates #滚动更新策略
rollingUpdate: #滚动更新
maxSurge: #最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavaliable: #最大不可用状态的pod的最大值,可以为百分比,也可以为整数
selector: #选择器,通过它指定该控制器管理哪些pod
matchLabels: #Labels匹配规则
app: nginx-pod
matchExpressions: #Expression匹配规则
- {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
由上面的deploy-nginx.yml文件可看出,除了名字和标签类型是对于deployment的定义外,下面的规格就是deployment的属性配置。
从定义上我们可以明显的看出 deployment 并不是直接控制的 pod ,其中在规格中的定义是 replicas ,所以控制其实是 ReplicaSet,由 ReplicaSet 去控制 pod。
# 创建Deployment
kubectl create -f deploy-nginx.yml
# 查看 ReplicaSet
kubectl get replicaset
NAME DESIRED CURRENT READY AGE
nginx-deployment-54f57cf6bf 2 2 2 75s
# 查看ReplicaSet信息
kubectl describe replicaset nginx-deployment-54f57cf6bf
# 查看 Pod
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-54f57cf6bf-mjqw9 1/1 Running 0 4s
nginx-deployment-54f57cf6bf-pvtkq 1/1 Running 0 4s
# 查看 指定Pod具体信息
kubectl describe pod nginx-deployment-54f57cf6bf-mjqw9
删除pod
我们可以通过 kubectl delete pod [podName] 命令删除一个 pod,然后我们再去查看当前 pod 的情况:
NAME READY STATUS RESTARTS AGE
nginx-deployment-54f57cf6bf-4scrb 1/1 Running 0 43s
nginx-deployment-54f57cf6bf-pvtkq 1/1 Running 0 5m
我们会惊奇的发现,它又重新创建了一个pod。Deployment 会维护pod的数量,一旦不满足数量的定义需求,就会进行创建。
删除rs
我们可以通过 kubectl delete rs [podName] 命令删除一个 rs,然后我们去看 rs 和 pod,你就会发现它又重新帮你创建了,Deployment 同样会维护 ReplicaSet的数量。
Deployment扩容缩容的本质其实就是改变ReplicaSet的数量来控制Pod的数量,增加就是扩容,缩小就是缩容。
扩容示例:假设我们要将nginx从3个pod扩展到5个pod:
kubectl scale deploy nginx-deployment --replicas=5 -n default
deployment.apps/nginx-deployment scaled
缩容示例:假设我们将nginx从5个缩容到3个
kubectl edit deploy nginx-deployment -n default deployment.apps/nginx-deployment edited
#找到replicas,将其数量改为3
spec:
progressDeadlineSeconds: 600
replicas: 3
deployment支持两种镜像更新策略:重建更新和滚动更新(默认),可以通过strategy选项进行配置:
strategy:指定新的pod替换旧的pod的策略,支持两个属性:
type:指定策略类型,支持两种策略
Recreate:在创建出新的pod之前会先杀掉所有已存在的pod
RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本pod
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性
maxUnavailable:用来指定在升级过程中不可用pod的最大数量,默认为25%
maxSurge:用来指定在升级过程中可以超过期望的pod的最大数量,默认为25%
spec:
strategy: #策略
type: Recreate #重建更新策略
#首先记录原本的pod名
[root@k8s-master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d9c9b97bb-4p2hx 1/1 Running 0 40m
nginx-deployment-5d9c9b97bb-bjnbs 1/1 Running 0 21m
nginx-deployment-5d9c9b97bb-p58lf 1/1 Running 0 40m
#更改pod镜像
[root@k8s-master yaml]# kubectl set image deploy nginx-deployment nginx=nginx:1.17.2
deployment.apps/nginx-deployment image updated
#再次查看镜像(先是中断rs控制器,再是拉取nginx新镜像,最后根据新镜像创建pod)
[root@k8s-master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d9c9b97bb-4p2hx 0/1 Terminating 0 42m
[root@k8s-master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7c7477c7ff-5xmxl 0/1 ContainerCreating 0 0s
nginx-deployment-7c7477c7ff-xjdcg 0/1 ContainerCreating 0 0s
nginx-deployment-7c7477c7ff-xtxh7 0/1 ContainerCreating 0 0s
[root@k8s-master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7c7477c7ff-5xmxl 1/1 Running 0 63s
nginx-deployment-7c7477c7ff-xjdcg 1/1 Running 0 63s
nginx-deployment-7c7477c7ff-xtxh7 1/1 Running 0 63s
注:Recreate 的升级策略就是完全删除再重建,这样会导致服务一段时间不可用
strategy:
type: RollingUpdate #滚动更新策略
rollingUpdate:
maxUnavailable: 25% #用来指定在升级过程中不可用pod的最大数量,默认为25%
maxSurge: 25% #用来指定在升级过程中可以超过期望的pod的最大数量,默认为25%
deployment支持版本升级过程中的暂停,继续功能以及版本回退等诸多功能
kubectl rollout:版本升级相关功能,支持下面的选项:
#当前nginx版本
[root@k8s-master yaml]# kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 24m nginx nginx:1.17.3 app=nginx-pod
#查看升级状态
[root@k8s-master yaml]# kubectl rollout status deploy nginx-deployment
deployment "nginx-deployment" successfully rolled out
#查看升级历史
[root@k8s-master yaml]# kubectl rollout history deploy nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
#查看版本详情
[root@k8s-master yaml]# kubectl rollout history deployment nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx-pod
pod-template-hash=7c7477c7ff
Containers:
nginx:
Image: nginx:1.17.2
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
#版本回滚这里使用--to-revision=2回滚到2版本,如果省略这个选项,则会回退到上个版本
[root@k8s-master yaml]# kubectl rollout undo deployment nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back
#查看当前版本(nginx为1.17.2)说明回退成功
[root@k8s-master yaml]# kubectl get deployments -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 27m nginx nginx:1.17.2 app=nginx-pod
灰度发布(金丝雀发布):比如有一批新的pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新的pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
#更新deployment版本,并配置暂停deployment
[root@k8s-master yaml]# kubectl set image deploy nginx-deployment nginx=nginx:1.17.3 && kubectl rollout pause deploy nginx-deployment
deployment.apps/nginx-deployment image updated
deployment.apps/nginx-deployment paused
#查看rs,发现老版本rs没有减少,新版本rs增加一个,状态为更新中....
[root@k8s-master yaml]# kubectl get rs,deploy
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 39m
replicaset.apps/nginx-deployment-76fd8c7f84 1 1 1 30m
replicaset.apps/nginx-deployment-7c7477c7ff 3 3 3 34m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 4/3 1 4 39m
[root@k8s-master yaml]# kubectl rollout status deployment nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
#继续deploy的更新
[root@k8s-master yaml]# kubectl rollout resume deployment nginx-deployment
deployment.apps/nginx-deployment resumed
[root@k8s-master yaml]# kubectl rollout status deployment nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
#查看rs更新结果,发现老版本均停止,新版本已经创建好
[root@k8s-master yaml]# kubectl get rs,deploy
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-5d9c9b97bb 0 0 0 41m
replicaset.apps/nginx-deployment-76fd8c7f84 3 3 3 32m
replicaset.apps/nginx-deployment-7c7477c7ff 0 0 0 36m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 41m
deployment支持更新过程中的控制,如"暂停(pause)"或"继续(resume)"更新操作,观察新服务实际运行状况再决定操作。