云原生 | kubernetes 资源对象 - 控制器模型之Deployment

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生 | kubernetes 资源对象 - 控制器模型之Deployment相关的知识,希望对你有一定的参考价值。

Deployment概述

Kubernetes 中的一个控制器模式,最常用于部署无状态服务的方式。Deployment 控制器实际操纵的是 ReplicaSet对象,而不是 Pod 对象。 保证系统中的Pod数量永远在期望状态

使用场景

  • 创建Deployment
  • 滚动升级和回滚操作
  • 检测状态
  • 扩缩容
  • 清理策略

创建Deployment

下面的 yaml 文件定义了一个 Deployment,该 Deployment 将创建一个有 3 个 nginx Pod 副本的 ReplicaSet(副本集)

我们回过头在了解一下ReplicaSet对象,它的结构非常简单,和Deployment相似。

我们可以看到,一个 ReplicaSet 对象,其实就是由副本数目的定义和一个 Pod 模板组成的。更重要的是,Deployment 控制器实际操纵的,正是这样的 ReplicaSet 对象,而不是 Pod 对象。

让我们创建 Deployment 对象并查看。

[root@ycloud ~]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment created
[root@ycloud ~]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           54s
  • READY:第一个3是当前状态的Running的Pod个数,第二个3是用户期望的Pod副本个数(.spec.replicas)
  • UP-TO-DATE: 当前处于最新版本的 Pod 的个数
  • AVVILABLE: 当前已经可用的 Pod 的个数

下面这张图就能很好体现,Deployment、Pod、ReplicaSet三者的关系

滚动升级和回滚操作

1.滚动升级

当 Deployment Pod 模板(即 .spec.template)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。

1>使用 set image 命令更新Pod,使用 nginx:1.7.9 镜像,--record 可以记录每次控制器变化

[root@ycloud ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.7.9 --record
deployment.apps/nginx-deployment image updated

2>或者直接通过 edit 编辑资源清单

[root@ycloud ycloud]# kubectl edit deployment/nginx-deployment
·····
    spec:
      containers:
      - image: nginx:latest       -----> 修改成nginx:1.7.9
        imagePullPolicy: Always
        name: nginx
······

Kubernetes 为我们提供了一条指令,让我们可以实时查看 Deployment 对象的状态变化。

[root@ycloud ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
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

也可以通过Deployment 的 Event,看到 “滚动更新” 的流程:

[root@ycloud ~]# kubectl describe deployment nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Sun, 02 Oct 2022 23:28:23 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
·········
Events:
  Type    Reason             Age                  From                   Message
  ----    ------             ----                 ----                   -------
  Normal  ScalingReplicaSet  3m2s  deployment-controller  Scaled up replica set nginx-deployment-585449566 to 3
  Normal  ScalingReplicaSet  111s  deployment-controller  Scaled up replica set nginx-deployment-56db85c5db to 1
  Normal  ScalingReplicaSet  86s   deployment-controller  Scaled down replica set nginx-deployment-585449566 to 2
  Normal  ScalingReplicaSet  86s   deployment-controller  Scaled up replica set nginx-deployment-56db85c5db to 2
  Normal  ScalingReplicaSet  61s   deployment-controller  Scaled down replica set nginx-deployment-585449566 to 1
  Normal  ScalingReplicaSet  61s   deployment-controller  Scaled up replica set nginx-deployment-56db85c5db to 3
  Normal  ScalingReplicaSet  37s   deployment-controller  Scaled down replica set nginx-deployment-585449566 to 0

"Scaled up replica set nginx-deployment-56db85c5db to 3",可以看到,当我们修改Pod模板中的镜像时,Deployment-controller 控制器会根据修改的 Pod模板,创建一个新的ReplicaSet(nginx-deployment-56db85c5db )

像Events中记录的这中,当一个新Pod运行成功,就会down掉一个旧的Pod,来保证系统中的Pod数量永远在期望状态 ,这种交替更新的过程就叫滚动更新

通过滚动更新实践,可以扩展出Deployment、Pod、ReplicaSet三者的关系

2.回滚操作

查看 ReplicaSet 对象,查看其更新之后的状态

[root@sztcyl-177-9-244 ~]# kubectl get rs 
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-56db85c5db   3         3         3       29m
nginx-deployment-585449566    0         0         0       30m

这次我们把镜像名字修改成为了一个错误的名字,比如:nginx:1.79。这样,这个 Deployment 就会出现一个升级失败的版本。这种情况Deployment会进入反复崩溃状态。

[root@ycloud ~]# kubectl set image deploy/nginx-deployment nginx=nginx:1.79 --record
deployment.apps/nginx-deployment image updated

这时,我们再次查看 ReplicaSet 状态

[root@ycloud ~]# kubectl get rs 
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-56db85c5db   3         3         3       36m
nginx-deployment-585449566    0         0         0       37m
nginx-deployment-5c4bcd6994   1         1         0       84s

发现新版本已经停止,这是我们只需要执行一个 kubectl rollout undo 命令,就可以使整个Deployment回滚到上个版本

[root@ycloud ~]# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
[root@ycloud ~]# kubectl get rs 
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-56db85c5db   3         3         3       40m
nginx-deployment-585449566    0         0         0       42m
nginx-deployment-5c4bcd6994   0         0         0       5m42s

我们也可以回滚到历史版本,只需在添加 --to-revision=2 这个参数,

[root@sztcyl-177-9-244 ~]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
2         kubectl set image deploy/nginx-deployment nginx=nginx:1.7.9 --record=true
3         <none>
4         kubectl set image deploy/nginx-deployment nginx=nginx:1.79 --record=true
[root@sztcyl-177-9-244 ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=2

扩缩容

“水平扩展 / 收缩”非常容易实现,Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。

1.可以通过如下命令实现

[root@sztcyl-177-9-244 ~]# kubectl scale deployment nginx-deployment --replicas=4                     
deployment.apps/nginx-deployment scaled  

2.或者直接通过 edit 编辑资源清单

[root@ycloud ycloud]# kubectl edit deployment/nginx-deployment
·····
spec:
  progressDeadlineSeconds: 600
  replicas: 4
······

清理策略

可以在 Deployment 中设置 .spec.revisionHistoryLimit 字段以指定保留此 Deployment 的多少个旧有 ReplicaSet。其余的 ReplicaSet 将在后台被垃圾回收。 默认情况下,此值为 10。

结论

Deployment 实际上是一个两层控制器。 Deployment 控制 ReplicaSet(版本),ReplicaSet 控制 Pod(副本数)

参考文献

https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#canary-deployment

以上是关于云原生 | kubernetes 资源对象 - 控制器模型之Deployment的主要内容,如果未能解决你的问题,请参考以下文章

云原生之kubernetes实战k8s集群下的DaemonSet 高级资源对象

云原生 | kubernetes 资源对象 - 控制器模型之Deployment

云原生 | kubernetes 资源对象 - 持久化存储PV,PVC

云原生之kubernetes实战k8s集群核心资源对象之Pod

云原生之kuberneteskubernetes集群下的Deployment高级资源对象管理

#云原生征文#深入Kubernetes(k8s)概念