K8S之使用Deployment实现滚动更新

滚动更新

滚动更新简介

滚动更新是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式,一次滚动发布一般由若干个批次组成,每批的数量一般是可以配置的(通过发布模板定义)。批次间可留观察间隔,通过手工验证或监控反馈确保没有问题再继续下一批次,所以总体上滚动式发布过程是比较缓慢的。

使用Deployment实现滚动更新

相关字段介绍

通过编写资源文件实现,涉及的字段如下:

bash 复制代码
kubectl explain deployment.spec
  • paused:暂停,当我们更新的时候创建pod先暂停,不是立即更新
    (ps. 金丝雀发布 会使用到)
  • strategy:更新策略,支持的滚动更新策略
  • revisionHistoryLimit : 保留的历史版本数,默认是10个。
    (ps. 需要回滚时使用,每更新镜像会产生一个版本,默认保留10个版本,回滚时可指定版本)

看更新策略

bash 复制代码
kubectl explain deploy.spec.strategy

更新的2种策略

  • Recreate:重建式更新,删除一个pod更新一个 pod。
  • RollingUpdate :滚动更新,定义滚动更新的更新方式的,也就是pod能多几个,少几个,控制更新力度的

看RollingUpdate 滚动更新的配置

bash 复制代码
kubectl explain deploy.spec.strategy.rollingUpdate
  • maxSurge:更新的过程当中最多允许超出的指定的目标副本数有几个
    它有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示原本是5个,最多可以超出20%,那就允许多一个,最多可以超过40%,那就允许多两个
  • maxUnavailable:最多允许几个不可用
    假设有5个副本,maxUnavailable = 1表示:最多一个不可用,就 最少有4个可用

测试滚动更新

观察滚动更新

例子:用deployment先创建一个pod ,变更镜像再重新更新pod。观察

bash 复制代码
vim deploy-demo.yaml 

编写Deployment资源文件

yaml 复制代码
apiVersion: apps/v1  # deployment对应的api版本
kind: Deployment     # 创建的资源是deployment
metadata:
  name: myapp-v1    # deployment的名字
spec:
  replicas: 2     # deployment管理的pod副本数
  selector:       # 标签选择器
    matchLabels:  # 筛选定义的标签需要跟template.metadata.labels定义的标签一致
      app: myapp
      version: v1
  template:
    metadata:
      labels:    # Pod具有的标签
        app: myapp
        version: v1
    spec:   #定义容器的属性
      containers:  
      - name: myweb
        image: janakiramm/myapp:v1     # 容器使用的镜像
        imagePullPolicy: IfNotPresent  # 镜像拉取策略
        ports:
        - containerPort: 80     # 容器里的应用的端口

更新资源清单文件

bash 复制代码
kubectl apply -f deploy-demo.yaml

在终端1下 执行如下:

bash 复制代码
kubectl get pods -l app=myapp -w

打开一个新的终端2窗口更改镜像版本,按如下操作:

bash 复制代码
vim deploy-demo.yaml

把 "image: janakiramm/myapp:v1 "变成 "image: janakiramm/myapp:v2"

保存退出,执行

bash 复制代码
kubectl apply -f deploy-demo.yaml 

再回到 终端1 监测的那个窗口,可以看到信息如下:

pending表示正在进行调度,ContainerCreating表示正在创建一个pod,running表示运行一个pod,running起来一个pod之后再Terminating一个pod,以此类推,直 到所有pod完成滚动升级

在另外一个终端3 执行

bash 复制代码
kubectl get rs

显示如下:

上面可以看到rs有两个,下面那个是升级之前的,已经被停掉,但是可以随时回滚

查看历史版本

查看 myapp-v1 这个控制器的滚动历史

bash 复制代码
kubectl rollout history deployment myapp-v1 -n default

显示如下:每更新镜像会产生一个版本

回滚操作如下:

"--to-revision" 指定要回滚到的版本号

bash 复制代码
kubectl rollout undo deployment/myapp-v1 --to-revision=1 -n default
bash 复制代码
kubectl get pods -l app=myapp -w

发现runing状态的又回到了第一版

自定义滚动更新策略

自定义配置建议

maxSurge 和 maxUnavailable 用来控制滚动更新的更新策略

取值范围

  • 填写整数类型的话,范围如下(ps. 两者不能同时为0):

    -- maxUnavailable: 0 ~ replicas的值(副本数)

    -- maxSurge: 0 ~ replicas的值(副本数)

  • 填写比例的话,范围如下(ps. 两者不能同时为0):

    -- maxUnavailable: 0%~100%;(向下取整,比如10个副本,5%的话 相当于 0.5个,但计算按照0个)

    -- maxSurge: 0%~100%;(向上取整,比如10个副本,5%的话 相当于 0.5个,但计算按照1个)

建议配置

maxUnavailable 设置为 0

maxSurge 设置为 1

建议生产环境提供的默认配置。即 "一上一下,先上后下" 最平滑原则:1个新版本pod ready(结合readiness就绪性探测)后,才销毁旧版本pod。

此配置适用场景:平滑更新、保证服务平稳,但也有缺点,就是"太慢"了。

配置总结: maxUnavailable:和期望的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;

maxSurge:和期望的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。

实践自定义策略

通过 RollingUpdateStrategy 字段来设置滚动更新策略

修改更新策略:maxUnavailable=1,maxSurge=1

bash 复制代码
kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":1}}}}' 

查看myapp-v1这个控制器的详细信息

bash 复制代码
kubectl describe deployment myapp-v1

这个rollingUpdate更新策略变成了新设定的,因为创建deployment 时,设定的pod副本数是3,1 max unavailable表示:最少不能少于2个pod,1 max surge表示:最多不能超过4个pod

使用Recreate更新策略

bash 复制代码
vim deploy-demo.yaml 

编写Deployment资源文件

yaml 复制代码
apiVersion: apps/v1  
kind: Deployment     
metadata:
  name: myapp-v1    
spec:
  strategy:  # 使用更新策略类型为Recreate
    type: Recreate
  replicas: 2     
  selector:       
    matchLabels:  
      app: myapp
      version: v1
  template:
    metadata:
      labels:    
        app: myapp
        version: v1
    spec:   
      containers:  
      - name: myweb
        image: janakiramm/myapp:v2  # 变更镜像apply才更新生效     
        imagePullPolicy: IfNotPresent  
        ports:
        - containerPort: 80     

更新资源清单文件

bash 复制代码
kubectl apply -f deploy-demo.yaml

打开新的终端,看pod更新过程

bash 复制代码
kubectl get pods -l app=myapp -w

发现 先都删除旧pod后再启动新的pod

总结:recreate这种更新策略,会把之前的所有pod都删除,再创建新的pod,风险很大

相关推荐
测试人社区—小叶子26 分钟前
测试开发面试高频“灵魂八问”深度解析与应答策略
网络·人工智能·测试工具·云原生·容器·面试·职场和发展
Henry Zhu1232 小时前
VPP中ACL实战配置指南与VPP的API使用初探
运维·服务器·网络·计算机网络·云原生
VermiliEiz2 小时前
使用二进制文件方式部署kubernetes(1)
kubernetes·云计算
云计算小黄同学4 小时前
k8s中的服务通过secret访问数据库的实际案例
数据库·阿里云·kubernetes
炸裂狸花猫5 小时前
开源日志收集体系ELK
elk·elasticsearch·云原生·kubernetes·metricbeat
DeepFlow 零侵扰全栈可观测6 小时前
助力金融信创与云原生转型,DeepFlow 排障智能体和可观测性建设实践
云原生·金融
拾忆,想起6 小时前
Dubbo通信协议全景指南:如何为你的微服务选择最佳通信方案?
微服务·云原生·性能优化·架构·dubbo·safari
网络小白不怕黑6 小时前
Containerd指南:从Docker到K8s的容器运行时
docker·容器·kubernetes
Hui Baby6 小时前
K8S蓝绿发布
java·容器·kubernetes
一周困⁸天.6 小时前
K8S-Helm
容器·kubernetes