kubernetes Pod-06 升级与回滚

概述

在Kubernetes(K8s)中,升级和回滚可通过Deployment来实现对应用服务无中断或少中断的更新。升级过程通常采用滚动更新策略,逐步替换Pod实例以新版本镜像启动新Pod,同时确保服务始终有足够副本在线提供服务。回滚则是指在升级出现问题时快速恢复到先前稳定版本的操作,K8s会自动基于Deployment的历史记录轻松回滚到之前的一个修订版本。整个过程旨在保障服务连续性和稳定性。

升级

当集群中的某个服务需要升级,我们需要停止该服务下的所有Pod,然后下载新版本并创建新Pod,如果集群规模大,这个行为就成为了挑战。k8s提供了滚动更新功能。

如果Pod是deployment创建,我们直接可以修改镜像名称,系统即可完成自动更新操作。如果在更新过程中发生错误,则可以回滚。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

运行并查看结果

bash 复制代码
# 运行
[root@master1 pod]# kubectl apply -f 26.yaml
deployment.apps/nginx-deployment created

# 查看结果
[root@master1 pod]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5d59d67564-hmpdx   1/1     Running   0          5s
nginx-deployment-5d59d67564-l4qs5   1/1     Running   0          5s
nginx-deployment-5d59d67564-l5gkr   1/1     Running   0          5s

更新镜像版本到1.9.1

bash 复制代码
# 编辑
[root@master1 pod]# kubectl edit deployment/nginx-deployment

# 更改 image 版本号
# wq保存推出

# 查看新创建
[root@master1 pod]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-69c44dfb78-djrfv   1/1     Running   0          3m16s
nginx-deployment-69c44dfb78-jtk2g   1/1     Running   0          2m29s
nginx-deployment-69c44dfb78-nsvdt   1/1     Running   0          2m4s

# 查看更新过程
[root@master1 ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 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: 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

其升级过程就是此消彼长过程

在升级过程中,系统会至少有两个Pod可用,并且最多同时运行4个Pod。这样能够保证在升级的过程中,老系统可以不中断服务。

更新策略有两种:

  • Recreate:重建,全部删掉Pod,然后重建。设置spec.strategy.type=Recreate
  • RollingUpdate:滚动更新。设置spec.strategy.type=RollingUpdate
    • maxUnavailable: 可用Pod数量上限
    • maxSurge:更新过程中Pod总数超过Pod期望副本数的最大值

回滚

默认情况下,所有Deployment的发布和历史记录都被保存在系统中,以便我们随时进行回滚。 用以上的例子。

bash 复制代码
[root@master1 pod]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5d59d67564-4l9c4   1/1     Running   0          3s
nginx-deployment-5d59d67564-62xvx   1/1     Running   0          3s
nginx-deployment-5d59d67564-hltmg   1/1     Running   0          3s

假设我们在更新镜像的时候,版本写错了,写成1.91

bash 复制代码
kubectl set image deployment/nginx-deployment nginx=nginx:1.91

# 查看部署过程会被卡住
[root@master1 pod]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...

# 查看ReplicaSet 可以看见新建的RS(nginx-deployment-d645d84b6)
[root@master1 pod]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5d59d67564   3         3         3       6m57s
nginx-deployment-d645d84b6    1         1         0       3m3s

# 查看Pod 看到拉去镜像失败
[root@master1 pod]# kubectl get pod
NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-5d59d67564-4l9c4   1/1     Running            0          8m50s
nginx-deployment-5d59d67564-62xvx   1/1     Running            0          8m50s
nginx-deployment-5d59d67564-hltmg   1/1     Running            0          8m50s
nginx-deployment-d645d84b6-57w4s    0/1     ImagePullBackOff   0          4m56s

为了解决上述问题,我想需要回滚稳定版本 注意:执行命令时增加 --record=true,才可以看到每个版本执行的命令,否则看到的结果如下:

bash 复制代码
[root@master1 pod]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

如果增加了 --record=true 查看结果为

bash 复制代码
[root@master1 pod]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=26.yaml --record=true
2         kubectl set image deployment/nginx-deployment nginx=nginx:1.91 --record=true

回滚操作可以有两种

  • 默认返回上个版本

    bash 复制代码
    [root@master1 pod]# kubectl rollout undo deployment/nginx-deployment
    deployment.apps/nginx-deployment rolled back
    
    # 查看版本
    [root@master1 pod]# kubectl get pod
      NAME                                READY   STATUS    RESTARTS   AGE
      nginx-deployment-5d59d67564-ckgk4   1/1     Running   0          6m22s
      nginx-deployment-5d59d67564-nqb52   1/1     Running   0          6m22s
      nginx-deployment-5d59d67564-s7h7m   1/1     Running   0          6m22s
  • 通过版本

    bash 复制代码
    [root@master1 pod]# kubectl rollout undo deployment/nginx-deployment --to-revision=2
      deployment.apps/nginx-deployment rolled back
      # 查询结果
      [root@master1 pod]# kubectl get pod
      NAME                                READY   STATUS              RESTARTS   AGE
      nginx-deployment-5d59d67564-ckgk4   1/1     Running             0          8m27s
      nginx-deployment-5d59d67564-nqb52   1/1     Running             0          8m27s
      nginx-deployment-5d59d67564-s7h7m   1/1     Running             0          8m27s
      nginx-deployment-d645d84b6-4pwkx    0/1     ContainerCreating   0          4s

    以上,Kubernetes 提供了一种声明式的、安全的方式来管理和控制应用服务的版本升级与回滚,极大地增强了系统的可靠性和运维效率。

相关推荐
匆匆那年96741 分钟前
Docker容器中安装MongoDB,导入数据
运维·docker·容器
i小溪2 小时前
在使用 Docker 时,如果容器挂载的数据目录(如 `/var/moments`)位于数据盘,只要服务没有读写,数据盘是否就不会被唤醒?
人工智能·docker
敖行客 Allthinker4 小时前
云原生安全观察:零信任架构与动态防御的下一代免疫体系
安全·ai·云原生·架构·kubernetes·ebpf
蓝纹绿茶5 小时前
【Mac】实现Docker下载安装【正在逐步完善】
macos·docker·容器
2401_861615285 小时前
跨平台的ARM 和 x86 Docker 镜像:汇编语言实验环境搭建
linux·汇编·ubuntu·docker·容器
探索云原生6 小时前
开源 vGPU 方案 HAMi 原理分析 Part1:hami-device-plugin-nvidia 实现
云原生·kubernetes·gpu·vgpu
INFINI Labs7 小时前
搭建持久化的 INFINI Console 与 Easysearch 容器环境
docker·easysearch·console
生活爱好者!8 小时前
NAS 部署白板工具,实现思维导图/画板/流程图自由
运维·docker·容器
亿牛云爬虫专家13 小时前
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
分布式·python·架构·kubernetes·爬虫代理·监测·采集