Kubernetes入门 七、Deployment控制器

目录

  • 什么是Deployment
  • 创建Deployment
    • 命令创建
    • yaml文件创建
  • 扩容缩容
  • 镜像更新
    • 重建更新
    • 滚动更新
  • 回滚
  • 暂停和恢复

前面已经简单里了解过Deployment,下面来深入学一下。

什么是Deployment

下面来简单回顾下Deployment的概念。

Deployment在K8s架构中属于控制器。

Deployment 是对 ReplicaSet(RS)更高层次的封装, 可以来自动管理 ReplicaSet,从而来管理Pod的副本数。还可以通过标签选择器选择对哪些Pod生效。

而ReplicaSet用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而异常多出来的容器也会自动回收。

所以使用Deployment可以确保健康 Pod 的数量、弹性伸缩、滚动升级以及应用多版本发布跟踪等。

创建Deployment

创建 Deployment可以有两种方式:

  • 直接使用命令(实际生产不推荐)
  • 执行yaml文件

命令创建

执行如下命令:

kubectl create deploy nginx-deploy --image=nginx:1.7.9
# deployment.apps/nginx-deploy created

然后我们可以看下创建的Deployment:

kubectl get deploy
# 结果如下
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   1/1     1            1           44s

除了创建了Deployment,他还会帮我们创建对应RS和Pod,查看如下:

# 查看rs
kubectl get rs
# 结果如下:
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58dcf5bbfb   1         1         1       110s

# 查看pod
kubectl get po
# 结果如下:
NAME                            READY   STATUS    RESTARTS   AGE
nginx-deploy-58dcf5bbfb-52j95   1/1     Running   0          2m33s

我们还可以获取Deployment的信息时,通过yaml的方式输出:

kubectl get deploy nginx-deploy -o yaml

其结果如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2023-08-16T14:54:24Z"
  generation: 1
  labels:  # Deployment的标签
    app: nginx-deploy
  name: nginx-deploy
  namespace: default
  resourceVersion: "509161"
  uid: decc3132-c0ab-44f1-bcf0-0f26d66acef5
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-deploy
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-deploy
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2023-08-16T14:54:26Z"
    lastUpdateTime: "2023-08-16T14:54:26Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2023-08-16T14:54:24Z"
    lastUpdateTime: "2023-08-16T14:54:26Z"
    message: ReplicaSet "nginx-deploy-58dcf5bbfb" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

yaml文件创建

创建文件nginx-deploy.yaml,内容如下:

apiVersion: apps/v1  # deployment api 版本
kind: Deployment  # 资源类型为deployment
metadata:  # 元信息
  labels:  # 标签
    app: nginx-deploy
  name: nginx-deploy  # deployment的名字
  namespace: default  # 所在命名空间
spec:
  replicas: 1  # 期望副本数
  revisionHistoryLimit: 10  # 进行滚动更新后,保留的历史版本数
  selector:  # 选择器,用于找到匹配的RS,管理指定标签的Rs
    matchLabels:  # 按照标签匹配
      app: nginx-deploy  # 匹配的标签
  strategy:  # 更新策略
    rollingUpdate:  # 滚动更新配置
      maxSurge: 25%  # 进行滚动更新时,更新的个数超过期望副本数的比例
      maxUnavailable: 25%  # 进行滚动更新时,最大不可用更新比例,也就是更新不成功最多能有多少个
    type: RollingUpdate  # 更新策略采用滚动更新
  template:  # pod模板
    metadata:  # pod的元信息
      labels:  # pod的标签
        app: nginx-deploy
    spec:  # pod的描述信息
      containers: # pod的描述信息
      - image: nginx:1.7.9   # pod使用镜像
        imagePullPolicy: IfNotPresent   # 镜像拉取策略
        name: nginx  # 容器名称
      restartPolicy: Always  # 重启策略
      terminationGracePeriodSeconds: 30  # 容器删除等待时间

执行命令:

kubectl create -f nginx-deploy.yaml
# deployment.apps/nginx-deploy created

检查结果:

kubectl get deploy
# 结果如下
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   1/1     1            1           5s

kubectl get rs
# 结果如下
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58dcf5bbfb   1         1         1       11s

kubectl get po
NAME                            READY   STATUS    RESTARTS        AGE
nginx-deploy-58dcf5bbfb-6jszh   1/1     Running   0               97s

扩容缩容

所谓的扩缩容就是可以动态的去更新pod的副本数。扩容即增加副本数,缩容即减少副本数。

实现扩缩容有如下4种方式:

  1. 使用 Kubectl edit 命令,修改 spec:replicas:n 即可
kubectl edit deployment nginx-deploy
  1. 使用 scale 命令实现扩缩容
kubectl scale deploy nginx-deploy --replicas=3
  1. 修改 yaml 文件中 spec.replicas 字段,随后使用 kubectl apply -f xxx.yaml 命令即可
vim nginx-deploy.yaml
kubectl apply -f nginx-deploy.yaml
  1. 使用patch命令
kubectl patch statefulset web -p '{"spec":{"replicas":3}}'

下面我们使用edit命令演示:

kubectl edit deploy nginx-deploy

如下副本数改为3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxlSKhio-1692547564785)(./imgs/7-1.png)]

然后就会帮我们立马创建3个pod出来,但是deployment和RS还是一个:

kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     3            3           15m

kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58dcf5bbfb   3         3         3       15m

get po --show-labels
NAME                            READY   STATUS    RESTARTS   AGE    LABELS
nginx-deploy-58dcf5bbfb-6jszh   1/1     Running   0          16m    app=nginx-deploy,pod-template-hash=58dcf5bbfb
nginx-deploy-58dcf5bbfb-6q5k7   1/1     Running   0          2m4s   app=nginx-deploy,pod-template-hash=58dcf5bbfb
nginx-deploy-58dcf5bbfb-t5k8p   1/1     Running   0          2m4s   app=nginx-deploy,pod-template-hash=58dcf5bbfb

注意pod标签会自动加一个pod-template-hash=58dcf5bbfb,用来表示pod使用的哪个模板。可以看到,3个pod使用的模板是一个。

镜像更新

Deployment 支持两种镜像更新策略:重建更新滚动更新,可以通过 strategy 字段进行配置:

strategy: # 指定新的Pod替代旧的Pod的策略,支持两个属性
  type: # 指定策略类型,支持两种策略 Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod   
  rollingUpdate: # 当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性:
    maxUnavailable: 25% # 用来指定在升级过程中不可用的Pod的最大数量,默认为25%。
    maxSurge: 25% # 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。

Deployment 的默认的镜像更新策略是 RollingUpdate(滚动更新),实际开发的时候,使用默认镜像更新策略即可。

重建更新

重建更新即创建出新的Pod之前会先杀掉所有已经存在的Pod。这样会有一段时间服务不可用。所以不常用。

修改我们上面yaml文件如下:

apiVersion: apps/v1  # deployment api 版本
kind: Deployment  # 资源类型为deployment
metadata:  # 元信息
  labels:  # 标签
    app: nginx-deploy
  name: nginx-deploy  # deployment的名字
  namespace: default  # 所在命名空间
spec:
  replicas: 3  # 期望副本数
  revisionHistoryLimit: 10  # 进行滚动更新后,保留的历史版本数
  selector:  # 选择器,用于找到匹配的RS,管理指定标签的Rs
    matchLabels:  # 按照标签匹配
      app: nginx-deploy  # 匹配的标签
  strategy: # 更新策略
    type: Recreate # Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod
  template:  # pod模板
    metadata:  # pod的元信息
      labels:  # pod的标签
        app: nginx-deploy
    spec:  # pod的描述信息
      containers: # pod的描述信息
      - image: nginx:1.7.9   # pod使用镜像
        imagePullPolicy: IfNotPresent   # 镜像拉取策略
        name: nginx  # 容器名称
      restartPolicy: Always  # 重启策略
      terminationGracePeriodSeconds: 30  # 容器删除等待时间

然后执行命令创建Deployment:

kubectl create -f nginx-deploy.yaml
# deployment.apps/nginx-deploy created

然后可执行如下命令更新使用的镜像:

kubectl set image deployment nginx-deploy nginx=nginx:1.20.2

或者也可以直接修改yaml文件。

结果会看到以前3个被删除,重新创建了三个pod

滚动更新

所谓滚动更新就是并不是一次性全部删除,而是先更新一部分pod,再删除一部分老的pod,直至所有的pod更新完成,以前的老的pod也全部删除。

滚动更新也是Deployment默认的更新策略。

下面修改yaml文件如下:

apiVersion: apps/v1  # deployment api 版本
kind: Deployment  # 资源类型为deployment
metadata:  # 元信息
  labels:  # 标签
    app: nginx-deploy
  name: nginx-deploy  # deployment的名字
  namespace: default  # 所在命名空间
spec:
  replicas: 3  # 期望副本数
  revisionHistoryLimit: 10  # 进行滚动更新后,保留的历史版本数
  selector:  # 选择器,用于找到匹配的RS,管理指定标签的RS
    matchLabels:  # 按照标签匹配
      app: nginx-deploy  # 匹配的标签
  strategy:  # 更新策略
    rollingUpdate:  # 滚动更新配置
      maxSurge: 25%  # 进行滚动更新时,更新的个数超过期望副本数的比例
      maxUnavailable: 25%  # 进行滚动更新时,最大不可用更新比例,也就是更新不成功最多能有多少个
    type: RollingUpdate  # 更新策略采用滚动更新
  template:  # pod模板
    metadata:  # pod的元信息
      labels:  # pod的标签
        app: nginx-deploy
    spec:  # pod的描述信息
      containers: # pod的描述信息
      - image: nginx:1.7.9   # pod使用镜像
        imagePullPolicy: IfNotPresent   # 镜像拉取策略
        name: nginx  # 容器名称
      restartPolicy: Always  # 重启策略
      terminationGracePeriodSeconds: 30  # 容器删除等待时间

设置了副本数为3,好演示更新的效果。

然后执行命令创建Deployment:

kubectl create -f nginx-deploy.yaml
# deployment.apps/nginx-deploy created

然后可执行如下命令更新使用的镜像:

kubectl set image deployment nginx-deploy nginx=nginx:1.9.1

然后多次查看deployment的状态:

kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     2            3           10s

kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     2            3           10s

test@testdeMacBook-Pro ~ % kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     3            3           10s

可以看到,deployment的READY数量一直是3,UP-TO-DATE 的数量是逐渐增加的。这就是滚动更新策略的效果。

可以使用describe命令查看deployment的事件:

 kubectl describe deploy nginx-deploy

主要查看事件,结果如下:

Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m24s  deployment-controller  Scaled up replica set nginx-deploy-58dcf5bbfb to 3
  Normal  ScalingReplicaSet  2m16s  deployment-controller  Scaled up replica set nginx-deploy-6d5979b84b to 1
  Normal  ScalingReplicaSet  2m15s  deployment-controller  Scaled down replica set nginx-deploy-58dcf5bbfb to 2 from 3
  Normal  ScalingReplicaSet  2m15s  deployment-controller  Scaled up replica set nginx-deploy-6d5979b84b to 2 from 1
  Normal  ScalingReplicaSet  2m14s  deployment-controller  Scaled down replica set nginx-deploy-58dcf5bbfb to 1 from 2
  Normal  ScalingReplicaSet  2m14s  deployment-controller  Scaled up replica set nginx-deploy-6d5979b84b to 3 from 2
  Normal  ScalingReplicaSet  2m13s  deployment-controller  Scaled down replica set nginx-deploy-58dcf5bbfb to 0 from 1

从上面信息也可以看到滚动更新的步骤。

回滚

还是以上面我们创建的3副本yaml文件为例,演示下如何进行版本回滚。

首先可以使用如下命令查询历史版本:

kubectl rollout history deployment nginx-deploy

结果如下:

deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         
2         

可以看到已经有两个版本了,其中第一列表示版本号,第二列是修改的信息,现在是空的,我们可以在更新deployment时,在命令后面加上–record,如下:

kubectl set image deployment nginx-deploy nginx=nginx:1.7.9

然后再查看下历史版本;

kubectl rollout history deployment nginx-deploy
# 结果如下
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
4         kubectl set image deployment nginx-deploy nginx=nginx:1.9.1 --record=true
5         kubectl set image deployment nginx-deploy nginx=nginx:1.7.9 --record=true

然后我们可以看下rs的数量

kubectl get rs
# 结果如下
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58dcf5bbfb   3         3         3       16m
nginx-deploy-6d5979b84b   0         0         0       16m

可以看到RS也有两个,其中第二个nginx-deploy-6d5979b84b的READY为0,它就是上个版本用到的RS。

Deployment 之所以能够实现版本的回退,就是通过记录下历史的 ReplicaSet 来实现的,一旦想回滚到那个版本,只需要将当前版本的 Pod 数量降为 0 ,然后将回退版本的 Pod 提升为目标数量即可。

好了,下面就开始回滚版本。

如果我想使用第4个版本,把镜像版本改回到nginx:1.9.1,可使用如下命令:

kubectl rollout undo deployment nginx-deploy --to-revision=4
# deployment.apps/nginx-deploy rolled back,说明回滚成功

再看下RS:

kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58dcf5bbfb   0         0         0       20m
nginx-deploy-6d5979b84b   3         3         3       20m

nginx-deploy-6d5979b84b的READY变回了3,上面的nginx-deploy-58dcf5bbfb变成了0。

暂停和恢复

Deployment 支持版本升级过程中的暂停、继续功能等诸多功能:

kubetl rollout 参数 deploy xx  # 支持下面的选择
# status 显示当前升级的状态
# history 显示升级历史记录
# pause 暂停版本升级过程
# resume 继续已经暂停的版本升级过程
# restart 重启版本升级过程
# undo 回滚到上一级版本 (可以使用--to-revision回滚到指定的版本),前面说过

这里就不再演示了。

你可能感兴趣的:(#,K8S入门与实战,kubernetes,容器,云原生)