当想要更新启动的pod镜像时,可以通过滚动更新,不停止Pod的情况下,将版本更新完成,非常简单 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新。滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。

如:更新httpd镜像版本

先部署3个httpd:2.2.31的副本

[root@node1 ~]# vim httpd.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  selector:
    matchLabels:
      run: httpd
  replicas: 3
  template:
    metadata:
      labels:
        run: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2.2.31
        ports:
        - containerPort: 80

运行文件

[root@node1 ~]# kubectl apply -f httpd.yml 
deployment.apps/httpd created

查看使用镜像

[root@node1 ~]# kubectl get deployments -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
httpd   3/3     3            3           79s   httpd        httpd:2.2.31   run=httpd
[root@node1 ~]# kubectl get rs -o wide
NAME               DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
httpd-5f8664fc66   3         3         3       93s   httpd        httpd:2.2.31   pod-template-hash=5f8664fc66,run=httpd

部署的过程是:

创建Deployment:httpd

创建ReplicaSet:httpd-5f8664fc66

创建三个Pod

先将文件中的镜像版本修改为httpd:2.2.32

[root@node1 ~]# vim httpd.yml 
# 修改镜像版本
        image: httpd:2.2.32

重新部署

[root@node1 ~]# kubectl apply -f httpd.yml 
deployment.apps/httpd configured

查看pod的变化

[root@node1 ~]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
httpd-5f8664fc66-hcpgc   1/1     Running             0          6m28s
httpd-5f8664fc66-rpc69   1/1     Running             0          6m28s
httpd-5f8664fc66-xvgxw   1/1     Running             0          6m28s
httpd-6998bd9ff5-d9nzj   0/1     ContainerCreating   0          10s

现在在创建一个新的Pod

再次查看,有一个Pod状态为Terminating,是之前使用2.2.31镜像的Pod

[root@node1 ~]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
httpd-5f8664fc66-hcpgc   1/1     Running             0          7m6s
httpd-5f8664fc66-rpc69   1/1     Running             0          7m6s
httpd-5f8664fc66-xvgxw   1/1     Terminating         0          7m6s
httpd-6998bd9ff5-d9nzj   1/1     Running             0          48s
httpd-6998bd9ff5-zts66   0/1     ContainerCreating   0          2s

更新结束后查看镜像版本

[root@node1 ~]# kubectl get rs -o wide
NAME               DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES         SELECTOR
httpd-5f8664fc66   0         0         0       8m30s   httpd        httpd:2.2.31   pod-template-hash=5f8664fc66,run=httpd
httpd-6998bd9ff5   3         3         3       2m12s   httpd        httpd:2.2.32   pod-template-hash=6998bd9ff5,run=httpd

2.2.31已经没有在运行Pod了,而2.2.32运行了三个Pod

综上所述,证明在进行版本的滚动更新时,不会影响Pod的正常访问,是一个一个Pod进行替换的,永远有pod在不间断运行

这种现象还在swarm集群的service中出现过,滚动更新也是为了保证处于期望状态,将新版本的镜像下载好之后,先将旧版本的Pod停止一个,然后创建一个,完成之后,在按照这个方式,更换其他Pod为新版本,整个过程始终有副本在运行,从而保证了业务的连续性。这就是滚动更新的策略

查看ReplicaSet还可以看到旧版本的存在,只不过没有被删除,期望状态转移到了新版本的ReplicaSet下

[root@node1 ~]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
httpd-5f8664fc66   0         0         0       13m
httpd-6998bd9ff5   3         3         3       6m43s

在这个过程中Deployment是没有更换的,直接更换了ReplicaSet。

整个替换过程在Deployment的events事件中是有写入的

[root@node1 ~]# kubectl describe deployments httpd
...
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  14m    deployment-controller  Scaled up replica set httpd-5f8664fc66 to 3
  # 2.2.31的Pod有3个
  Normal  ScalingReplicaSet  8m25s  deployment-controller  Scaled up replica set httpd-6998bd9ff5 to 1
  # 开始替换后,2.2.32版本的开始运行第一个
  Normal  ScalingReplicaSet  7m39s  deployment-controller  Scaled down replica set httpd-5f8664fc66 to 2
  # 关闭了2.2.31的一个Pod,还剩2个
  Normal  ScalingReplicaSet  7m39s  deployment-controller  Scaled up replica set httpd-6998bd9ff5 to 2
  # 2.2.32在运行第二个Pod,已经运行了2个
  Normal  ScalingReplicaSet  7m4s   deployment-controller  Scaled down replica set httpd-5f8664fc66 to 1
  # 关闭第二个2.2.31的Pod,还剩一个
  Normal  ScalingReplicaSet  7m4s   deployment-controller  Scaled up replica set httpd-6998bd9ff5 to 3
  # 2.2.32运行的第三个Pod,已经运行3个
  Normal  ScalingReplicaSet  7m1s   deployment-controller  Scaled down replica set httpd-5f8664fc66 to 0
  # 2.2.31的Pod全部关闭

查看Deployment的事件详情,可以看到ReplicaSet在轮换的进行Scaled upScaled down

查看滚动状态是否成功

[root@node1 ~]# kubectl rollout status deployment httpd 
deployment "httpd" successfully rolled out

然后可以将旧的ReplicaSet删除就好了,看好再删,别把更新完的ReplicaSet删了

[root@node1 ~]# kubectl delete replicasets.apps nginx-deployment-5bf87f5f59
[root@node1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
httpd-deployment-5dd67c6b75   3         3         3       114m
nginx-deployment-5f8c6846ff   2         2         2       91m

每次替换的 Pod 数量是可以定制的。Kubernetes 提供了两个参数 maxSurgemaxUnavailable 来精细控制 Pod 的替换数量,后面会写到

回滚镜像版本

kubectl apply 每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个 revision(版次),这样就可以回滚到某个特定 revision。

默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit 属性增加 revision 数量。

先将之前的更新过的Deployment给删除

[root@node1 ~]# kubectl delete -f httpd.yml 
deployment.apps "httpd" deleted

修改yml文件,添加revisionHistoryLimit

[root@node1 ~]# vim httpd.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  revisionHistoryLimit: 10   # 添加
  selector:
    matchLabels:
      run: httpd
  replicas: 3
  template:
    metadata:
      labels:
        run: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2.4.16   # 修改镜像为2.4.16
        ports:
        - containerPort: 80

运行Pod,--record的作用是将当前命令记录到 revision 记录中

[root@node1 ~]# kubectl apply -f httpd.yml --record 
deployment.apps/httpd created

查看Pod是否运行成功

[root@node1 ~]# kubectl get pod -l run=httpd
NAME                     READY   STATUS    RESTARTS   AGE
httpd-79bcc48899-9bfms   1/1     Running   0          100s
httpd-79bcc48899-9kz5b   1/1     Running   0          100s
httpd-79bcc48899-vqsrd   1/1     Running   0          100s

修改版本进行重新部署

[root@node1 ~]# cp httpd.yml httpd.v1.yml
# 修改版本为2.4.17
[root@node1 ~]# vim httpd.v1.yml
        image: httpd:2.4.17
[root@node1 ~]# kubectl apply -f httpd.v1.yml --record 
deployment.apps/httpd configured
# 等待更新完成
[root@node1 ~]# kubectl get deployments -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
httpd   3/3     3            3           21m   httpd        httpd:2.4.17   run=httpd

修改版本再次部署

[root@node1 ~]# cp httpd.yml httpd.v2.yml
# 修改版本为2.4.18
[root@node1 ~]# vim httpd.v1.yml
        image: httpd:2.4.18
[root@node1 ~]# kubectl apply -f httpd.v2.yml --record 
deployment.apps/httpd configured
[root@node1 ~]# kubectl get deployments -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
httpd   3/3     3            3           29m   httpd        httpd:2.4.18   run=httpd

查看记录到的revision历史记录

[root@node1 ~]# kubectl rollout history deployment httpd 
deployment.apps/httpd 
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=httpd.yml --record=true
2         kubectl apply --filename=httpd.v1.yml --record=true
3         kubectl apply --filename=httpd.v2.yml --record=true

如果要回滚,可以直接指定REVISION字段下的数字即可

如:回滚到1

[root@node1 ~]# kubectl rollout undo deployment httpd --to-revision=1
deployment.apps/httpd rolled back

这个时候revision的历史记录也会将1更新为最新的数字

[root@node1 ~]# kubectl rollout history deployment httpd 
deployment.apps/httpd 
REVISION  CHANGE-CAUSE
2         kubectl apply --filename=httpd.v1.yml --record=true
3         kubectl apply --filename=httpd.v2.yml --record=true
4         kubectl apply --filename=httpd.yml --record=true

查看镜像版本

[root@node1 ~]# kubectl get deployments -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
httpd   3/3     3            3           36m   httpd        httpd:2.4.16   run=httpd

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0