3-6-2-ReplicaSet和Deployment控制器

熊 0 阅读 容器

控制器主要负责创建 , 管理k8s上的资源 , 如果对应资源不吻合用户定义的资源状态 , 它就会尝试重启或重建的方式让其状态和用户定义的状态吻合 ; 在k8s上控制器的类型有很多 , 比如pod控制 , service控制器 , endpoint控制器等等 ; 不同类型的控制器有着不同的功能和作用 ; 比如pod控制器就是针对pod资源进行管理的控制器 ; 单说pod控制器 , 它也有很多类型 , 根据pod里容器跑的应用程序来分类 , 可以分为有状态应用和无状态应用控制 , 从应用程序是否运行为守护进程我们可以将控制器分为 , 守护进程和非守护进程控制器 ; 其中无状态控制器中最常用的有ReplicaSet控制器和Deployment控制 ; 有状态应用控制器常用的有StatefulSet ; 守护进程控制器最常用的有daemonSet控制器 ; 非守护进程控制器有job控制器 , 对Job类型的控制器 , 如果要周期性执行的有Cronjob控制器 ;

1. ReplicaSet控制器

ReplicaSet控制器的主要作用是确保Pod对象副本数量在任何时刻都能精准满足用户期望的数量 ; 这种控制器启动以后 , 它首先会查找集群中匹配其标签选择器的Pod资源对象 , 当活动pod数量与用户期望的pod数量不吻合时 , 如果多了就删除 , 少了就创建 ; 它创建新pod是靠我们在配置清单中定义的pod模板来创建新pod ;

1.1 创建ReplicaSet控制器

示例 : 定义创建ReplicaSet控制器

root@k8s-master01:/opt/k8s-data/yaml/replicaset# cat replicaset-demo.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14-alpine
        ports:
        - name: http
          containerPort: 80
​

定义ReplicaSet控制器 ,

  • apiVersion字段的值为apps/v1

  • kind为ReplicaSet , 这两个字段都是固定的 ;

  • metadata中主要定义名称和名称空间 ;

  • spec中主要定义replicas、selector、template ;

    • replicas这个字段的值为一个整数 , 表示对应pod的副本数量 ;

    • selector用于定义标签选择器 ; 其值为一个对象 ,

      • matchLabels字段表示精确匹配标签 , 这个字段的值为一个字典 ; 除了精确匹配标签选择器这种方式 , 还有

      • matchExpressions表示使用匹配表达式 , 其值为一个对象 ; 简单说定义标签选择器 ,

        第一种是matchLabels , 这种方式就是指定一个或多个标签 , 每个标签就是一个kv键值对 ; 后者matchExpressions是指定一个表达式 , 其值为一个对象 , 这个对象中主要定义key字段 , 这个字段定义key的名称 ; operator定义操作符 , values定义值 ; key和operator字段的值类型都是字符串 , 其中operator的值有In, NotIn, Exists和DoesNotExist ; values是一个字符串列表 ;

    • 其次就是定义pod模板 , 使用template字段定义 , 该字段的值为一个对象其中metadata字段用于定义模板的元素据信息 , 这个元数据信息必须定义标签属性 ; 通常这个标签属性和选择器中的标签相同 ; spec字段用于定义pod模板的状态 , 最重要的是定义pod里容器的名字 , 镜像等等 ;

应用资源配置清单

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl apply -f replicaset-demo.yaml 
replicaset.apps/replicaset-demo created
​
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
replicaset-demo   3         3         3       74s
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs -o wide
NAME              DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
replicaset-demo   3         3         3       83s   nginx        nginx:1.14-alpine   app=nginx-pod
​

rs就是ReplicaSet的简写 ; 从上面的信息可以看到对应控制器已经创建 ; 并且当前pod副本数量为3 , 用户期望的数量也为3 , 有3个准备就绪 ;

查看pod

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods -L app
NAME                    READY   STATUS    RESTARTS   AGE   APP
replicaset-demo-fkzrw   1/1     Running   0          25m   nginx-pod
replicaset-demo-p9gdx   1/1     Running   0          25m   nginx-pod
replicaset-demo-zz7g5   1/1     Running   0          25m   nginx-pod

可以看到当前default名称空间中创建了3个pod,其标签为nginx-pod ;

测试 ; 更改其中一个pod的标签为ngx,看看对应控制器是否会新建一个标签为nginx-pod的pod

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl label pod/replicaset-demo-fkzrw  app=ngx --overwrite
pod/replicaset-demo-fkzrw labeled
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods -L app
NAME                    READY   STATUS              RESTARTS   AGE   APP
replicaset-demo-bhdnf   0/1     ContainerCreating   0          2s    nginx-pod
replicaset-demo-fkzrw   1/1     Running             0          28m   ngx
replicaset-demo-p9gdx   1/1     Running             0          28m   nginx-pod
replicaset-demo-zz7g5   1/1     Running             0          28m   nginx-pod
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods -L app
NAME                    READY   STATUS    RESTARTS   AGE   APP
replicaset-demo-bhdnf   1/1     Running   0          5s    nginx-pod
replicaset-demo-fkzrw   1/1     Running   0          28m   ngx
replicaset-demo-p9gdx   1/1     Running   0          28m   nginx-pod
replicaset-demo-zz7g5   1/1     Running   0          28m   nginx-pod

可以看到当我们把其中一个pod的标签更改为app=ngx后 , 对应控制器又会根据pod模板创建一个新pod ;

1.2 修改标签

测试 : 更改pod标签为app=nginx-pod , 看看对应控制器是否会删除一个pod

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods -L app
NAME                    READY   STATUS    RESTARTS   AGE   APP
replicaset-demo-fkzrw   1/1     Running   0          35m   nginx-pod
replicaset-demo-k7h7j   1/1     Running   0          3s    nginx-pod
replicaset-demo-p9gdx   1/1     Running   0          35m   ngx
replicaset-demo-zz7g5   1/1     Running   0          35m   nginx-pod
​
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl label pod/replicaset-demo-p9gdx app=nginx-pod --overwrite
pod/replicaset-demo-p9gdx labeled
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods -L app
NAME                    READY   STATUS    RESTARTS   AGE   APP
replicaset-demo-fkzrw   1/1     Running   0          35m   nginx-pod
replicaset-demo-p9gdx   1/1     Running   0          35m   nginx-pod
replicaset-demo-zz7g5   1/1     Running   0          35m   nginx-pod
​

可以看到当集群中有多余用户期望数量的pod标签时 , 对应控制器会把多余的相同标签的pod删除 ; 从上面的测试可以看到ReplicaSet控制器是依靠标签选择器来判断集群中pod的数量是否和用户定义的数量吻合 , 如果不吻合就尝试删除或新建 , 让对应pod数量精确满足用户期望pod数量 ;

查看rs控制器的详细信息

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl describe rs replicaset-demo
Name:         replicaset-demo
Namespace:    default
Selector:     app=nginx-pod
Labels:       <none>
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx-pod
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  38m    replicaset-controller  Created pod: replicaset-demo-p9gdx
  Normal  SuccessfulCreate  38m    replicaset-controller  Created pod: replicaset-demo-zz7g5
  Normal  SuccessfulCreate  38m    replicaset-controller  Created pod: replicaset-demo-fkzrw
  Normal  SuccessfulCreate  10m    replicaset-controller  Created pod: replicaset-demo-bhdnf
  Normal  SuccessfulDelete  4m40s  replicaset-controller  Deleted pod: replicaset-demo-bhdnf
  Normal  SuccessfulCreate  4m15s  replicaset-controller  Created pod: replicaset-demo-ltkl8
  Normal  SuccessfulDelete  4m1s   replicaset-controller  Deleted pod: replicaset-demo-ltkl8
  Normal  SuccessfulCreate  3m24s  replicaset-controller  Created pod: replicaset-demo-k7h7j
  Normal  SuccessfulDelete  3m15s  replicaset-controller  Deleted pod: replicaset-demo-k7h7j

1.3 扩展/缩容

扩展/缩减rs控制pod副本数量

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl scale rs replicaset-demo --replicas=6
replicaset.apps/replicaset-demo scaled
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
replicaset-demo   6         6         6       40m
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl scale rs replicaset-demo --replicas=4
replicaset.apps/replicaset-demo scaled
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
replicaset-demo   4         4         4       41m
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
replicaset-demo-4zzkk   1/1     Running   0          38s
replicaset-demo-fkzrw   1/1     Running   0          41m
replicaset-demo-p9gdx   1/1     Running   0          41m
replicaset-demo-zz7g5   1/1     Running   0          41m
​

scale也可以对控制器做扩展和缩减pod副本数量 , 除了以上使用命令的方式来变更对应pod副本数量 ; 也可以直接在配置清单中修改replicas字段 , 然后使用apply命令执行配置清单进行修改 ;

修改配置清单中的replicas字段的值来扩展pod副本数量

root@k8s-master01:/opt/k8s-data/yaml/replicaset# cat replicaset-demo.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-demo
  namespace: default
spec:
  replicas: 7
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14-alpine
        ports:
        - name: http
          containerPort: 80
​
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl apply -f replicaset-demo.yaml 
replicaset.apps/replicaset-demo configured
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
replicaset-demo-272ql   1/1     Running   0          5s
replicaset-demo-4gqb8   1/1     Running   0          5s
replicaset-demo-4zzkk   1/1     Running   0          33m
replicaset-demo-fkzrw   1/1     Running   0          74m
replicaset-demo-nrfbz   1/1     Running   0          5s
replicaset-demo-p9gdx   1/1     Running   0          74m
replicaset-demo-zz7g5   1/1     Running   0          74m
​

1.4 更新pod版本

1.4.1 更新资源配置清单

方式1 修改资源配置清单中pod模板的版本 , 这里直接将对应yaml文件中的镜像修改为nginx:1.16-alpine, 然后在使用apply命令来执行配置清单

root@k8s-master01:/opt/k8s-data/yaml/replicaset# cat replicaset-demo.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-demo
  namespace: default
spec:
  replicas: 7
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.16-alpine
        ports:
        - name: http
          containerPort: 80
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl apply -f replicaset-demo.yaml 
replicaset.apps/replicaset-demo configured
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs -o wide
NAME              DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
replicaset-demo   7         7         7       83m   nginx        nginx:1.16-alpine   app=nginx-pod

从上面命令可以看到 , 它显示的镜像版本是1.16的版本 ;

验证 : 查看对应pod , 看看对应pod中容器镜像版本是否变成了1.16

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
replicaset-demo-272ql   1/1     Running   0          11m
replicaset-demo-4gqb8   1/1     Running   0          11m
replicaset-demo-4zzkk   1/1     Running   0          45m
replicaset-demo-fkzrw   1/1     Running   0          85m
replicaset-demo-nrfbz   1/1     Running   0          11m
replicaset-demo-p9gdx   1/1     Running   0          85m
replicaset-demo-zz7g5   1/1     Running   0          85m

从pod创建的时间来看 , pod没有更新 ;

测试 : 删除一个pod看看对应pod里容器镜像是否会更新

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-demo              1/1     Running   0          10h
nginx-demo2             1/1     Running   0          9h
replicaset-demo-272ql   1/1     Running   0          11m
replicaset-demo-4gqb8   1/1     Running   0          11m
replicaset-demo-4zzkk   1/1     Running   0          45m
replicaset-demo-fkzrw   1/1     Running   0          85m
replicaset-demo-nrfbz   1/1     Running   0          11m
replicaset-demo-p9gdx   1/1     Running   0          85m
replicaset-demo-zz7g5   1/1     Running   0          85m

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl delete pods/replicaset-demo-272ql
pod "replicaset-demo-272ql" deleted

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
replicaset-demo-4gqb8   1/1     Running   0          14m
replicaset-demo-4rjx7   1/1     Running   0          34s
replicaset-demo-4zzkk   1/1     Running   0          48m
replicaset-demo-fkzrw   1/1     Running   0          88m
replicaset-demo-nrfbz   1/1     Running   0          14m
replicaset-demo-p9gdx   1/1     Running   0          88m
replicaset-demo-zz7g5   1/1     Running   0          88m

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl describe pods/replicaset-demo-4rjx7 | grep image
  Normal  Pulling    103s  kubelet            Pulling image "nginx:1.16-alpine"
  Normal  Pulled     73s   kubelet            Successfully pulled image "nginx:1.16-alpine" in 29.986s (29.986s including waiting)

可以看到我们删除了一个pod , 对应控制器又新建了一个pod , 对应新建的pod镜像版本就成为了新版本的pod ; 从上面测试情况可以看到 , 对于rs控制器当pod模板中的镜像版本发生更改 , 如果k8s集群上对应pod数量和用户定义的数量吻合 , 此时rs控制器不会更新pod ; 只有新建后的pod才会拥有新版本 ; 也就说如果我们要rs来对pod版本更新 , 就得删除原有老的pod后才会更新 ;

1.4.2 命令更新pod

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl set image rs replicaset-demo nginx=nginx:1.18-alpine
replicaset.apps/replicaset-demo image updated
root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get rs -o wide
NAME              DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
replicaset-demo   7         7         7       95m   nginx        nginx:1.18-alpine   app=nginx-pod

root@k8s-master01:/opt/k8s-data/yaml/replicaset# kubectl get pods 
NAME                    READY   STATUS    RESTARTS   AGE
nginx-demo              1/1     Running   0          10h
nginx-demo2             1/1     Running   0          10h
replicaset-demo-4gqb8   1/1     Running   0          21m
replicaset-demo-4rjx7   1/1     Running   0          7m3s
replicaset-demo-4zzkk   1/1     Running   0          54m
replicaset-demo-fkzrw   1/1     Running   0          95m
replicaset-demo-nrfbz   1/1     Running   0          21m
replicaset-demo-p9gdx   1/1     Running   0          95m
replicaset-demo-zz7g5   1/1     Running   0          95m

对于rs控制器 , 不管用命令还是修改资源配置清单中pod模板中镜像版本 , 如果有和用户期望数量的pod , 它是不会自动更新pod版本的 ; 只有手动删除老版本pod , 对应新版本pod才会被创建 ;

2. deployment控制器

对于deployment控制来说 , 它的定义方式和rs控制都差不多 , 但deploy控制器的功能要比rs强大 , 它可以实现滚动更新 , 用户手动定义更新策略; 其实deploy控制器是在rs控制器的基础上来管理pod; 也就说我们在创建deploy控制器时 , 它自动会创建一个rs控制器; 其中使用deployment控制器创建的pod名称是由deploy控制器名称加上“-”pod模板hash名称加上“-”随机字符串; 而对应rs控制器的名称恰好就是deploy控制器名称加“-”pod模板hash; 即pod名称就为rs控制器名称加“-”随机字符串;

2.1 创建deployment控制器

示例:创建deployment控制器

root@k8s-master01:/opt/k8s-data/yaml/deployment# cat deployment-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ngx-dep-pod
  template:
    metadata:
      labels:
        app: ngx-dep-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14-alpine
        ports:
        - name: http
          containerPort: 80

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl apply -f deployment-demo.yaml 
deployment.apps/deploy-demo created
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deploy -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     3            3           8s    nginx        nginx:1.14-alpine   app=ngx-dep-pod

验证 : 查看是否有rs控制器创建

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get rs
NAME                     DESIRED   CURRENT   READY   AGE
deploy-demo-57f99896b5   3         3         3       54s

可以看到有一个deploy-demo-57f99896b5控制器被创建 ;

验证:查看pod , 看看对应pod名称是否有rs控制器名称加“-”一串随机字符串

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pods 
NAME                           READY   STATUS    RESTARTS   AGE
deploy-demo-57f99896b5-g89gg   1/1     Running   0          2m34s
deploy-demo-57f99896b5-mktrc   1/1     Running   0          2m34s
deploy-demo-57f99896b5-pnqz4   1/1     Running   0          2m34s

可以看到有3个pod的名称是deploy-demo-57f99896b5-加随机字符串 ;

2.2 更新pod版本

2.2.1 更新配置清单

这里通过编辑yaml文件, 调整image镜像版本。这里直接将image版本从1.14-alpine修改为1.16-alpine

root@k8s-master01:/opt/k8s-data/yaml/deployment# cat deployment-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ngx-dep-pod
  template:
    metadata:
      labels:
        app: ngx-dep-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.16-alpine
        ports:
        - name: http
          containerPort: 80
          
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl apply -f deployment-demo.yaml
deployment.apps/deploy-demo configured

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deployment -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     2            3           9m16s   nginx        nginx:1.16-alpine   app=ngx-dep-pod

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
deploy-demo-55c5b97f5-52lk6   1/1     Running   0          8s
deploy-demo-55c5b97f5-6fx2z   1/1     Running   0          34s
deploy-demo-55c5b97f5-pzml4   1/1     Running   0          60s

可以看到deploy控制器只要更改了pod模板中镜像版本 , 对应pod会自动更新 ;

2.2.2 命令更新pod

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl set image deployment deploy-demo nginx=nginx:1.18-alpine
deployment.apps/deploy-demo image updated

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deployment -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     1            3           15m   nginx        nginx:1.18-alpine   app=ngx-dep-pod

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
deploy-demo-777c6bc997-czhkr   1/1     Running   0          66s
deploy-demo-777c6bc997-rfv4s   1/1     Running   0          88s
deploy-demo-777c6bc997-s79nr   1/1     Running   0          39s

可以看到deploy控制器 , 只要修改了pod模板中镜像的版本 , 对应pod就会随之滚动更新到我们指定的版本;

2.3更新历史版本

2.3.1 查看rs历史版本

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES              SELECTOR
deploy-demo-55c5b97f5    0         0         0       11m     nginx        nginx:1.16-alpine   app=ngx-dep-pod,pod-template-hash=55c5b97f5
deploy-demo-57f99896b5   0         0         0       19m     nginx        nginx:1.14-alpine   app=ngx-dep-pod,pod-template-hash=57f99896b5
deploy-demo-777c6bc997   3         3         3       4m18s   nginx        nginx:1.18-alpine   app=ngx-dep-pod,pod-template-hash=777c6bc997

deploy控制器的更新pod版本操作 , 它会记录rs的所有历史版本; 因为只要pod模板的hash值发生变化 , 对应的rs就会重新被创建一遍 , 不同于rs控制器 , 历史版本的rs上没有pod运行 , 只有当前版本的rs上才会运行pod ;

2.3.2 查看更新历史记录

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

这里可以看到有3个版本 , 没有记录对应的原因; 这是因为我们在更新pod版本是没有记录; 要想记录器更新原因 , 可以在对应名后面加--record选项即可;

示例 : 记录更新操作命令到更新历史记录

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/deploy-demo image updated

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true

可以看到更新操作时加上--record选项后 , 再次查看更新历史记录 , 就能显示对应的更新命令;

新版本已经弃用了该参数, 新版本的annotation会沿用上一个版本的内容。

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl set image deployment deploy-demo nginx=nginx:1.16-alpine 
deployment.apps/deploy-demo image updated
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
3         <none>
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
5         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true

取而代之的是命令如下 , 这个命令需要每次更新deployment后都执行一次

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl annotate deployment/deploy-demo kubernetes.io/change-cause="image updated to 1.16-alpine"
deployment.apps/deploy-demo annotated
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
3         <none>
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
5         image updated to 1.16-alpine

可以发现更新原因已经发生变化

2.3.3回到上一个版本

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deploy -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     3            3           52m   nginx        nginx:1.16-alpine   app=ngx-dep-pod

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo-55c5b97f5    3         3         3       44m   nginx        nginx:1.16-alpine   app=ngx-dep-pod,pod-template-hash=55c5b97f5
deploy-demo-57f99896b5   0         0         0       52m   nginx        nginx:1.14-alpine   app=ngx-dep-pod,pod-template-hash=57f99896b5
deploy-demo-777c6bc997   0         0         0       37m   nginx        nginx:1.18-alpine   app=ngx-dep-pod,pod-template-hash=777c6bc997

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo 
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
6         image updated to 1.16-alpine
7         image updated to 1.16-alpine

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout undo deploy/deploy-demo
deployment.apps/deploy-demo rolled back
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout history deploy/deploy-demo 
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
7         image updated to 1.16-alpine
8         image updated to 1.16-alpine


root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deploy -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     3            3           56m   nginx        nginx:1.18-alpine   app=ngx-dep-pod

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get rs  -o wide
NAME                     DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo-55c5b97f5    0         0         0       48m   nginx        nginx:1.16-alpine   app=ngx-dep-pod,pod-template-hash=55c5b97f5
deploy-demo-57f99896b5   0         0         0       56m   nginx        nginx:1.14-alpine   app=ngx-dep-pod,pod-template-hash=57f99896b5
deploy-demo-777c6bc997   3         3         3       41m   nginx        nginx:1.18-alpine   app=ngx-dep-pod,pod-template-hash=777c6bc997

可以看到执行了kubectl rollout undo deploy/deploy-demo命令后 , 对应版本从1.16就回滚到1.18的版本了; 对应更新历史记录也把1.18版本更新为当前最新记录;

2.3.4 回滚到指定历史记录版本

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout  history  deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
4         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
7         image updated to 1.16-alpine
8         image updated to 1.16-alpine



root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout undo deploy/deploy-demo --to-revision=4
deployment.apps/deploy-demo rolled back
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout  history  deploy/deploy-demo
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
7         image updated to 1.16-alpine
8         image updated to 1.16-alpine
9         kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get deploy -o wide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo   3/3     3            3           61m   nginx        nginx:1.14-alpine   app=ngx-dep-pod
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES              SELECTOR
deploy-demo-55c5b97f5    0         0         0       53m   nginx        nginx:1.16-alpine   app=ngx-dep-pod,pod-template-hash=55c5b97f5
deploy-demo-57f99896b5   3         3         3       62m   nginx        nginx:1.14-alpine   app=ngx-dep-pod,pod-template-hash=57f99896b5
deploy-demo-777c6bc997   0         0         0       46m   nginx        nginx:1.18-alpine   app=ngx-dep-pod,pod-template-hash=777c6bc997

指定要回滚到某个历史记录的版本 , 可以使用--to-revision选项来指定历史记录的编号 ;

查看deploy控制器的详细信息

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl describe deploy deploy-demo
Name:                   deploy-demo
Namespace:              default
CreationTimestamp:      Tue, 04 Jun 2024 17:03:17 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 9
                        kubernetes.io/change-cause: kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
Selector:               app=ngx-dep-pod
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=ngx-dep-pod
  Containers:
   nginx:
    Image:        nginx:1.14-alpine
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  deploy-demo-55c5b97f5 (0/0 replicas created), deploy-demo-777c6bc997 (0/0 replicas created)
NewReplicaSet:   deploy-demo-57f99896b5 (3/3 replicas created)
Events:
  Type    Reason             Age                  From                   Message
  ----    ------             ----                 ----                   -------
  Normal  ScalingReplicaSet  55m                  deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 1
  Normal  ScalingReplicaSet  55m                  deployment-controller  Scaled down replica set deploy-demo-57f99896b5 to 2 from 3
  Normal  ScalingReplicaSet  55m                  deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 2 from 1
  Normal  ScalingReplicaSet  54m                  deployment-controller  Scaled down replica set deploy-demo-57f99896b5 to 1 from 2
  Normal  ScalingReplicaSet  54m                  deployment-controller  Scaled down replica set deploy-demo-57f99896b5 to 0 from 1
  Normal  ScalingReplicaSet  48m                  deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 1
  Normal  ScalingReplicaSet  31m (x2 over 54m)    deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 3 from 2
  Normal  ScalingReplicaSet  22m                  deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 3 from 2
  Normal  ScalingReplicaSet  20m                  deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 1 from 0
  Normal  ScalingReplicaSet  20m (x21 over 48m)   deployment-controller  (combined from similar events): Scaled down replica set deploy-demo-777c6bc997 to 2 from 3
  Normal  ScalingReplicaSet  9m45s                deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 1 from 0
  Normal  ScalingReplicaSet  9m43s (x2 over 48m)  deployment-controller  Scaled down replica set deploy-demo-55c5b97f5 to 2 from 3
  Normal  ScalingReplicaSet  3m55s                deployment-controller  Scaled up replica set deploy-demo-57f99896b5 to 1 from 0

查看deploy控制器的详细信息 , 可以看到对应pod模板 , 回滚的过程 , 以及默认更新策略等等信息 ;

2.3.5 自定义滚动更新策略

root@k8s-master01:/opt/k8s-data/yaml/deployment# cat deployment-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-demo
  namespace: default
spec:
  revisionHistoryLimit: 10
  replicas: 3
  selector:
    matchLabels:
      app: ngx-dep-pod
  template:
    metadata:
      labels:
        app: ngx-dep-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.16-alpine
        ports:
        - name: http
          containerPort: 80
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  minReadySeconds: 5            

定义滚动更新策略需要使用strategy这个字段 , 这个字段的值是一个对象 , 其中type是指定更新策略 , 其策略有两种 ,

  • 第一种是Recreate , 这种策略更新方式是新建一个新版pod , 然后再删除一个旧版pod以这种方式滚动更新 ;

  • 第二种是RollingUpdate , 这种策略是用于我们手动指定的策略 ;

    • maxSurge表示最大允许超出用户期望的pod数量(即更新时允许新建超出用户期望的pod数量)

    • maxUnavailable表示最大允许少于用于期望的pod数量(即更新时可以一次删除几个旧版pod)

最后minReadySeconds字段不是定义更新策略的 , 它是spec中的一个字段 , 用于限定pod最小就绪时长 ; 以上更新策略表示 , 使用RollingUpdate类型策略 , 并指定最大新建pod超出用户期望pod数量为2个 , 最大允许少于用户期望pod数量为1个 ; pod最小就绪时间为5秒 ;

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl apply -f deployment-demo.yaml 
deployment.apps/deploy-demo configured
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl describe  deploy/deploy-demo
Name:                   deploy-demo
Namespace:              default
CreationTimestamp:      Tue, 04 Jun 2024 17:03:17 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 10
                        kubernetes.io/change-cause: kubectl set image deployment deploy-demo nginx=nginx:1.14-alpine --record=true
Selector:               app=ngx-dep-pod
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        5
RollingUpdateStrategy:  1 max unavailable, 2 max surge
Pod Template:
  Labels:  app=ngx-dep-pod
  Containers:
   nginx:
    Image:        nginx:1.16-alpine
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  deploy-demo-57f99896b5 (0/0 replicas created), deploy-demo-777c6bc997 (0/0 replicas created)
NewReplicaSet:   deploy-demo-55c5b97f5 (3/3 replicas created)
Events:
  Type    Reason             Age                 From                   Message
  ----    ------             ----                ----                   -------
  Normal  ScalingReplicaSet  58m                 deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 1
  Normal  ScalingReplicaSet  40m (x2 over 64m)   deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 3 from 2
  Normal  ScalingReplicaSet  31m                 deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 3 from 2
  Normal  ScalingReplicaSet  30m                 deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 1 from 0
  Normal  ScalingReplicaSet  30m (x21 over 57m)  deployment-controller  (combined from similar events): Scaled down replica set deploy-demo-777c6bc997 to 2 from 3
  Normal  ScalingReplicaSet  19m                 deployment-controller  Scaled up replica set deploy-demo-777c6bc997 to 1 from 0
  Normal  ScalingReplicaSet  19m (x2 over 57m)   deployment-controller  Scaled down replica set deploy-demo-55c5b97f5 to 2 from 3
  Normal  ScalingReplicaSet  13m                 deployment-controller  Scaled up replica set deploy-demo-57f99896b5 to 1 from 0
  Normal  ScalingReplicaSet  26s (x2 over 64m)   deployment-controller  Scaled down replica set deploy-demo-57f99896b5 to 2 from 3
  Normal  ScalingReplicaSet  26s                 deployment-controller  Scaled up replica set deploy-demo-55c5b97f5 to 2 from 0

可以看到对应deploy控制器的更新策略已经更改为我们定义的策略 ; 为了能够看出更新的效果 , 我们这里先手动把pod数量调整为10个 ;

2.3.6. 扩展pod副本数量

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl scale deploy/deploy-demo --replicas=10
deployment.apps/deploy-demo scaled
root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
deploy-demo-55c5b97f5-7b6fx   1/1     Running   0          10s
deploy-demo-55c5b97f5-8l5lr   1/1     Running   0          10s
deploy-demo-55c5b97f5-9lkj6   1/1     Running   0          10s
deploy-demo-55c5b97f5-dwj2k   1/1     Running   0          9m22s
deploy-demo-55c5b97f5-fqtm8   1/1     Running   0          10s
deploy-demo-55c5b97f5-gfvnv   1/1     Running   0          9m22s
deploy-demo-55c5b97f5-j86kr   1/1     Running   0          10s
deploy-demo-55c5b97f5-nkq89   1/1     Running   0          10s
deploy-demo-55c5b97f5-wn5ng   1/1     Running   0          9m22s
deploy-demo-55c5b97f5-zfdb4   1/1     Running   0          10s

查看更新过程

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pods -w
NAME                           READY   STATUS    RESTARTS   AGE
deploy-demo-55c5b97f5-gfvnv    1/1     Running   0          11m
deploy-demo-55c5b97f5-wn5ng    1/1     Running   0          11m
deploy-demo-777c6bc997-9xfhs   1/1     Running   0          3s
deploy-demo-777c6bc997-hk6ff   1/1     Running   0          3s
deploy-demo-777c6bc997-k95xj   1/1     Running   0          3s
nginx-demo                     1/1     Running   0          12h
nginx-demo2                    1/1     Running   0          11h
deploy-demo-55c5b97f5-gfvnv    1/1     Terminating   0          11m
deploy-demo-55c5b97f5-wn5ng    1/1     Terminating   0          11m
deploy-demo-55c5b97f5-wn5ng    0/1     Terminating   0          11m
deploy-demo-55c5b97f5-gfvnv    0/1     Terminating   0          11m
deploy-demo-55c5b97f5-wn5ng    0/1     Terminating   0          11m
deploy-demo-55c5b97f5-wn5ng    0/1     Terminating   0          11m
deploy-demo-55c5b97f5-wn5ng    0/1     Terminating   0          11m
.....

使用-w选项可以一直跟踪查看pod变化过程 ; 从上面的监控信息可以看到 , 在更新时 , 首先是将三个pod标记为pending状态 , 然后先删除一个pod , 然后再创建两个pod ; 然后又创建一个 , 再删除3个 , 一次进行 ; 不管怎么删除和新建 , 对应新旧pod的数量最少要有9个 , 最大不超过12个 ;

使用暂停更新实现金丝雀发布

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl set image deploy/deploy-demo nginx=nginx:1.16-alpine && kubectl rollout pause deploy/deploy-demo
deployment.apps/deploy-demo image updated
deployment.apps/deploy-demo paused

以上命令会根据我们定义的更新策略 , 先删除一个pod , 然后再创建3个新版pod , 然后更新操作就暂停了 ; 此时对应pod只更新了1个 , 然后新建了2个新pod , 总共就有12个pod ;

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl get pods -o wide  
NAME                           READY   STATUS    RESTARTS   AGE   IP             NODE                   NOMINATED NODE   READINESS GATES
deploy-demo-55c5b97f5-4v4jm    1/1     Running   0          3s    172.20.3.111   k8s-node01.cbear.top   <none>           <none>
deploy-demo-55c5b97f5-h2gsr    1/1     Running   0          3s    172.20.4.86    k8s-node02.cbear.top   <none>           <none>
deploy-demo-55c5b97f5-wg52h    1/1     Running   0          3s    172.20.5.72    k8s-node03.cbear.top   <none>           <none>
deploy-demo-57f99896b5-24vpg   1/1     Running   0          70s   172.20.4.84    k8s-node02.cbear.top   <none>           <none>
deploy-demo-57f99896b5-2j847   1/1     Running   0          70s   172.20.3.108   k8s-node01.cbear.top   <none>           <none>
deploy-demo-57f99896b5-98hcj   1/1     Running   0          63s   172.20.4.85    k8s-node02.cbear.top   <none>           <none>
deploy-demo-57f99896b5-9dwx2   1/1     Running   0          76s   172.20.5.69    k8s-node03.cbear.top   <none>           <none>
deploy-demo-57f99896b5-cxmp6   1/1     Running   0          76s   172.20.4.83    k8s-node02.cbear.top   <none>           <none>
deploy-demo-57f99896b5-lp2hh   1/1     Running   0          63s   172.20.5.71    k8s-node03.cbear.top   <none>           <none>
deploy-demo-57f99896b5-qcb7w   1/1     Running   0          76s   172.20.3.107   k8s-node01.cbear.top   <none>           <none>
deploy-demo-57f99896b5-tkngt   1/1     Running   0          63s   172.20.3.109   k8s-node01.cbear.top   <none>           <none>
deploy-demo-57f99896b5-w8hhz   1/1     Running   0          70s   172.20.5.70    k8s-node03.cbear.top   <none>           <none>

之所以多两个是因为我们在更新策略中定义允许最大超出用户期望2个pod ;

恢复更新

root@k8s-master01:/opt/k8s-data/yaml/deployment# kubectl rollout resume deploy/deploy-demo && kubectl rollout status deploy/deploy-demo
deployment.apps/deploy-demo resumed
Waiting for deployment "deploy-demo" rollout to finish: 3 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 3 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 6 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 out of 10 new replicas have been updated...
Waiting for deployment "deploy-demo" rollout to finish: 9 of 10 updated replicas are available...
Waiting for deployment "deploy-demo" rollout to finish: 9 of 10 updated replicas are available...
deployment "deploy-demo" successfully rolled out

resume表示恢复刚才暂停的更新操作 ; status是用来查看对应更新过程 ;

如果“金丝雀”遇险,这时候需要恢复滚动更新并立即回滚:

$ kubectl rollout resume deoloyments my-app-deployment \
  && kubectl rollout undo deoloyments my-app-deployment

回滚完成后验证 Deployment 管理的 ReplicaSet 控制器对象是否已恢复到指定的历史版本以确保回滚正常。在 kubectl rollout undo 后跟上 --to-revision=N 选项指定历史版本序号即可回滚至历史特定版本。


参考链接

容器编排系统k8s之ReplicaSet和Deployment控制器 - Linux-1874 - 博客园 (cnblogs.com)