K8S发布策略-滚动更新(rollingUpdate)

现在很多公司都使用K8S(kubernetes)进行容器管理和编排,今天来说下k8s的发布策略: 滚动更新

滚动更新的优点:允许通过使用新的实例逐步更新Pods实例来实现部署的更新,从而实现零停机 。应用程序始终可用。 在金丝雀发布基础上的进一步优化改进, 滚动更新是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式,

滚动更新的缺点: 发布过程是比较缓慢 。 一次滚动发布一般由若干个发布批次组成,每批的数量一般是可以配置的(可以通过发布模 板定义),例如第一批 1 台,第二批 10%,第三批 50%,第四批 100%。每个批次之间留观察间隔,通过手工验证或监控反馈确保没有问题再发下一批次,所以总体上滚动式发布过程是比较缓慢的。

滚动更新(rollingUpdate)

  滚动更新步骤:

  1. 准备一个新版本的POD,比如新版本为V2,旧版本为V1。

  2. 当V2版本的POD准备好后,在负载均衡中的实例池中将V2的版本加入。

  3. 在实例池中剔除一个V1版本的POD。

  4. 逐个实例替换,直到每个版本都是V2版本。

   如下图:

image-20220224114328171

滚动更新使用的YAML方式如下:

spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # 一次可以添加多少个Pod
      maxUnavailable: 1  # 滚动更新期间最大多少个Pod不可用

我们准备两个版本, fffmo.com-app-v1.yaml文件。

apiVersion: v1
kind: Service
metadata:
  name: fffmo.com-app
  labels:
    app: fffmo.com-app
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: http
  selector:
    app: fffmo.com-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fffmo.com-app
  labels:
    app: fffmo.com-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: fffmo.com-app
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: fffmo.com-app
  template:
    metadata:
      labels:
        app: fffmo.com-app
        version: v1.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9101"
    spec:
      containers:
      - name: fffmo.com-app
        image: containersol/k8s-deployment-strategies
        ports:
        - name: http
          containerPort: 8080
        - name: probe
          containerPort: 8086
        env:
        - name: VERSION
          value: v1.0.0
        livenessProbe:
          httpGet:
            path: /live
            port: probe
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: probe
          periodSeconds: 5

然后我们再准备一下滚动更新的v2版本,
fffmo.com-app-rolling-update.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fffmo.com-app
  labels:
    app: fffmo.com-app
spec:
  replicas: 10
  # maxUnavailable设置为0可以完全确保在滚动更新期间服务不受影响,还可以使用百分比的值来进行设置。
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: fffmo.com-app
  template:
    metadata:
      labels:
        app: fffmo.com-app
        version: v2.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9101"
    spec:
      containers:
      - name: fffmo.com-app
        image: containersol/k8s-deployment-strategies
        ports:
        - name: http
          containerPort: 8080
        - name: probe
          containerPort: 8086
        env:
        - name: VERSION
          value: v2.0.0
        livenessProbe:
          httpGet:
            path: /live
            port: probe
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: probe
          # 初始延迟设置高点可以更好地观察滚动更新过程
          initialDelaySeconds: 15
          periodSeconds: 5

  接下来,我们按如下步骤进行操作:

  1. 启动fffmo.com-app-v1应用

  2. 启动fffmo.com-app-rollingupdate应用

  3. 观察所有容器版本变为V2版本

启动fffmo.com-app-v1应用并观察,都已经启动,我们进行接口调用。

apply -f fffmo.com-app-v1.yaml
kubectl get pods -l app=fffmo.com-app

NAME                      READY     STATUS    RESTARTS   AGE
fffmo.com-app-847874cd75-h3d2e   1/1       Running   0          47s
fffmo.com-app-847874cd75-p4l8f   1/1       Running   0          47s
fffmo.com-app-847874cd75-qnt7p   1/1       Running   0          47s
$ kubectl get svc fffmo.com-app
NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
fffmo.com-app    NodePort   10.109.99.184   <none>        80:30486/TCP   1m

确认更新完成
kubectl rollout status deployment/fffmo.com-app


$ curl http://127.0.0.1:30486
Host: fffmo.com-app-847874cd75-qnt7p, Version: v1.0.0

  在当前窗口监控容器的情况,执行命令

watch kubectl get pods -l app=fffmo.com-app

  打开一个新的窗口,然后执行滚动更新命令

kubectl apply -f fffmo.com-app-rolling-update.yaml

查看部署

kubectl get deployments -l run=fffmo.com-app  

查看正在运行的Pods
$ kubectl get pods -o wide

在watch的终端观察,开始的时候并没删除旧的pod,而是创建好新的pod后,然后进行挨个替,我们可以使用如下命令观察接口请求, 渐渐的有了第二个版本的请求。

$ while sleep 0.1; do curl http://127.0.0.1:30486; done


Host:fffmo.com-app-847874cd75-h3d2e, Version: v1.0.0 
...... 
Host: fffmo.com-app-847874cd75-h3d2e, Version: v1.0.0
Host: fffmo.com-app-6b5479d97f-2fk24, Version: v2.0.0

  在这个过程中,我们发现第二个版本有问题,我们需要进行回滚,此时我们需要执行一下如下命令

kubectl rollout undo deploy fffmo.com-app

  如果想两个版本都观察一下,这个时候需要执行命令。

kubectl rollout pause deploy fffmo.com-app

  如果发现第二个版本没有问题,那么我们要恢复执行,也就是我们说的回滚。

kubectl rollout resume deploy fffmo.com-app

  最后我们清理一下所有的部署

kubectl delete -l app=fffmo.com-app

  总结一下:

   1. k8s发布策略-滚动部署没有控制流量的情况。
  2. 各个版本部署的时候需要一定的时间。
  3. 在k8s中,更新是版本化的,任何部署更新都可以恢复为以前的(稳定)版本。

赞(1) 打赏
特别声明:除特殊标注,本站文章均为原创,遵循CC BY-NC 3.0,转载请注明出处。三伏磨 » K8S发布策略-滚动更新(rollingUpdate)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏