Deployment概述

Deployment 是 kubernetes 中最常用的资源对象,为 ReplicaSet 和 Pod 的创建提供了一种声明式的定义方法,在 Deployment 对象中描述一个期望的状态,Deployment 控制器就会按照一定的控制速率把实际状态改成期望状态,通过定义一个 Deployment 控制器会创建一个新的 ReplicaSet 控制器,通过ReplicaSet 创建 pod,删除 Deployment 控制器,也会删除 Deployment 控制器下对应的 ReplicaSet 控制器和 pod 资源。使用 Deployment 而不直接创建 ReplicaSet 是因为 Deployment 对象拥有许多 ReplicaSet 没有的特性,例如滚动升级和回滚。

通过 Deployment 对象,你可以轻松的做到以下事情:

  1. 创建 ReplicaSet 和 Pod

  2. 滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)

  3. 暂停和继续 Deployment

  4. 平滑地扩容和缩容

Deployment创建

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
  labels:
    app: nginx-deploy
spec:
  replicas: 2
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.5
        imagePullPolicy: IfNotPresent
  selector:
    matchLabels:
      app: nginx-pod

执行下面的命令,创建Deployment

kubectl apply -f nginx-deploy.yaml
#查看Deployment
kubectl get deploy

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   2/2     2            2           7s
#查看ReplicaSet
kubectl get rs

NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-746f69785b   2         2         2       11s
#查看pod状态
kubectl get pod -o wide

NAME                            READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
nginx-deploy-746f69785b-gt5jk   1/1     Running   0          3m16s   10.81.85.242   k8s-node01   <none>           <none>
nginx-deploy-746f69785b-zdgpn   1/1     Running   0          3m16s   10.81.58.230   k8s-node02   <none>           <none>

通过观察创建好的Deployment、ReplicaSet、Pod,ReplicaSet的名称是由Deployment名称+hash值,Pod的名称是由ReplicaSet名称+hash值。

Deployment管理

扩容、缩容

Deployment控制器对于进行扩容或缩容有多种方式,下面我们分别用不用的方式来进行操作;

修改yaml方式

修改资源文件中的spec.replicas的值,例如我当前修改为4并保存,重新执行命令kubectl apply -f nginx-deploy.yaml,然后查看pod状态

NAME                            READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
nginx-deploy-746f69785b-ds9k2   1/1     Running   0          4s    10.81.58.231   k8s-node02   <none>           <none>
nginx-deploy-746f69785b-gt5jk   1/1     Running   0          71m   10.81.85.242   k8s-node01   <none>           <none>
nginx-deploy-746f69785b-lk7h7   1/1     Running   0          4s    10.81.85.243   k8s-node01   <none>           <none>
nginx-deploy-746f69785b-zdgpn   1/1     Running   0          71m   10.81.58.230   k8s-node02   <none>           <none>

kubectl edit方式

kubectl edit deploy nginx-deploy

**这种方式跟修改资源文件方式一样,也是修改spec.replicas的值保存退出,只不过不用重新执行kubectl apply命令,它会自动更新。**这次将副本数修改为1个,然后查看pod状态。

NAME                            READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
nginx-deploy-746f69785b-gt5jk   1/1     Running   0          82m   10.81.85.242   k8s-node01   <none>           <none>

kubectl scale方式

kubectl scale deploy nginx-deploy --replicas=3

这种方式效率最高,直接一条命令搞定,这里我们把副本数又修改成了3个,我们再次查看pod状态。

NAME                            READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
nginx-deploy-746f69785b-gt5jk   1/1     Running   0          85m   10.81.85.242   k8s-node01   <none>           <none>
nginx-deploy-746f69785b-tp6ng   1/1     Running   0          6s    10.81.58.232   k8s-node02   <none>           <none>
nginx-deploy-746f69785b-vt7lf   1/1     Running   0          6s    10.81.58.233   k8s-node02   <none>           <none>

滚动更新

Deployment 控制器是建立在 ReplicaSet 之上的一个控制器,可以管理多个 ReplicaSet,每次更新镜像版本,都会生成一个新的 ReplicaSet,把旧的 ReplicaSet 替换掉,多个 ReplicaSet 同时存在,但是只有一个 ReplicaSet 运行。 ReplicaSet v1控制三个 pod,当升级v2版本时,在 eplicaSet v2上重新建立一个pod,然后删除一个ReplicaSet v1上的pod,依次类推,直到全部pod都是由 ReplicaSet v2控制,如果ReplicaSet v2有问题,还可以回滚,Deployment 是建构在 ReplicaSet 之上的,多个 ReplicaSet 组成一个Deployment,但是只有一个 ReplicaSet 处于活跃状态。

image

#修改Deployment控制器
kubectl edit deploy nginx-deploy

通过上面的命令修改Deployment控制器的内容,例如我们修改一下nginx镜像的版本,从1.21.5修改为1.19.2-alpine,修改完成后保存退出,然后观察ReplicaSet和pod的状态;

#实时查看pod状态
kubectl get pod -w

NAME                            READY   STATUS              RESTARTS   AGE
nginx-deploy-54c7949846-d9sdw   0/1     ContainerCreating   0          26s
nginx-deploy-746f69785b-gt5jk   1/1     Running             0          112m
nginx-deploy-746f69785b-tp6ng   1/1     Running             0          27m
nginx-deploy-746f69785b-vt7lf   1/1     Running             0          27m
nginx-deploy-54c7949846-d9sdw   1/1     Running             0          38s
nginx-deploy-54c7949846-4xjv6   0/1     Pending             0          0s
nginx-deploy-54c7949846-4xjv6   0/1     Pending             0          0s
nginx-deploy-746f69785b-vt7lf   1/1     Terminating         0          27m
nginx-deploy-54c7949846-4xjv6   0/1     ContainerCreating   0          0s
nginx-deploy-54c7949846-4xjv6   0/1     ContainerCreating   0          2s
nginx-deploy-746f69785b-vt7lf   0/1     Terminating         0          27m
nginx-deploy-746f69785b-vt7lf   0/1     Terminating         0          27m
nginx-deploy-746f69785b-vt7lf   0/1     Terminating         0          27m

Pending表示正在进行调度,ContainerCreating表示正在创建一个pod,Running表示运行一个pod,Running起来一个pod之后再Terminating一个pod,以此类推,直到所有pod完成滚动升级。从上面我们可以发现当更新镜像以后会发生如下变化:

  1. 创建一个新的ReplicaSet控制器nginx-deploy-54c7949846;
  2. 创建并启动新的pod,名称以nginx-deploy-54c7949846为前缀;
  3. 新的pod启动成功一个后便会停止一个旧的pod(nginx-deploy-746f69785b-*);
  4. 重复第三步的动作,直到所有旧的pod全部停止完毕,从而实现滚动更新。

版本回滚

滚动升级完成后,我们查看ReplicaSet的状态如下,上面那个是新的,下面那个是旧的,已经被停掉,但是可以随时进行回滚。

#查看ReplicaSet
kubectl get rs

NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-54c7949846   3         3         3       101s
nginx-deploy-746f69785b   0         0         0       113m
#查看更新历史记录
kubectl rollout history deploy nginx-deploy
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

从上面的信息可以看出有两个版本,REVISION=1的是更新前的版本1.21.5,REVISION=2是更新后的版本1.19.2-alpine,下面我们把版本回滚到更新前的版本。

#根据版本号查看版本的内容
kubectl rollout history deployment nginx-deploy --revision=1
kubectl rollout history deployment nginx-deploy --revision=2

#根据版本号回滚到指定版本
kubectl rollout undo deployment nginx-deploy --to-revision=1

等回滚完成后,再次查看ReplicaSet状态,当前生效的又变回了nginx-deploy-746f69785b,说明回滚成功

NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-746f69785b   3         3         3       10m
nginx-deploy-54c7949846   0         0         0       10m