9bb33d03d9e9bfaeadbd742b07d5b2b6.gif

1、通过k8s实现滚动更新-滚动更新流程和策略

1.1 滚动更新简介

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

1.2 在k8s中实现金滚动更新

首先看下Deployment资源对象的组成:

[root@xianchaomaster1~]# kubectl explain deployment

[root@xianchaomaster1 ~]# kubectl explain deployment.spec

KIND:      Deployment

VERSION:   apps/v1

RESOURCE: spec <Object>

DESCRIPTION:

      Specification of the desired behavior of the Deployment.

      DeploymentSpec is the specification of the desired behavior of the

      Deployment.

FIELDS:

    minReadySeconds<integer>

     Minimum  number of seconds for which a newly created pod should be ready

     without  any of its container crashing, for it to be considered available.

     Defaults  to 0 (pod will be considered available as soon as it is ready)

   paused<boolean>

     Indicates  that the deployment is paused.

#暂停,当我们更新的时候创建pod先暂停,不是立即更新

    progressDeadlineSeconds  <integer>

     The  maximum time in seconds for a deployment to make progress before it is

      considered to be failed. The deployment controller will continue to  process

     failed  deployments and a condition with a ProgressDeadlineExceeded reason

     will be  surfaced in the deployment status. Note that progress will not be

     estimated  during the time a deployment is paused. Defaults to 600s.

   replicas   <integer>

     Number of  desired pods. This is a pointer to distinguish between explicit

     zero and  not specified. Defaults to 1.

    revisionHistoryLimit<integer>

#保留的历史版本数,默认是10个

     The  number of old ReplicaSets to retain to allow rollback. This is a

     pointer  to distinguish between explicit zero and not specified. Defaults to

     10.

   selector   <Object> -required-

     Label  selector for pods. Existing ReplicaSets whose pods are selected by

     this will  be the ones affected by this deployment. It must match the pod

      template's labels.

   strategy   <Object>

#更新策略,支持的滚动更新策略

     The  deployment strategy to use to replace existing pods with new ones.

   template   <Object> -required-

     Template  describes the pods that will be created.

kubectl explaindeploy.spec.strategy

KIND:     Deployment

VERSION:  apps/v1

RESOURCE: strategy  <Object>

DESCRIPTION:

     The deployment strategy to use to  replace existing pods with new ones.

     DeploymentStrategy describes how to  replace existing pods with new ones.

FIELDS:

   rollingUpdate  <Object>

     Rolling update config params. Present  only if DeploymentStrategyType =

     RollingUpdate.

   type  <string>

     Type of deployment. Can be  "Recreate" or "RollingUpdate". Default is

     RollingUpdate.

#支持两种更新,Recreate和RollingUpdate  

#Recreate是重建式更新,删除一个更新一个

#RollingUpdate 滚动更新,定义滚动更新的更新方式的,也就是pod能多几个,少几个,控制更新力度的

kubectl explaindeploy.spec.strategy.rollingUpdate

KIND:     Deployment

VERSION:  apps/v1

RESOURCE: rollingUpdate  <Object>

DESCRIPTION:

     Rolling update config params. Present  only if DeploymentStrategyType =

     RollingUpdate.

     Spec to control the desired behavior of  rolling update.

FIELDS:

   maxSurge   <string>

     The maximum number of pods that can be  scheduled above the desired number

     of pods. Value can be an absolute number  (ex: 5) or a percentage of desired

     pods (ex: 10%). This can not be 0 if  MaxUnavailable is 0. Absolute number

     is calculated from percentage by  rounding up. Defaults to 25%. Example:

     when this is set to 30%, the new  ReplicaSet can be scaled up immediately

     when the rolling update starts, such  that the total number of old and new

     pods do not exceed 130% of desired pods.  Once old pods have been killed,

     new ReplicaSet can be scaled up further,  ensuring that total number of pods

     running at any time during the update is  at most 130% of desired pods.

#我们更新的过程当中最多允许超出的指定的目标副本数有几个;

它有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示原本是5个,最多可以超出20%,那就允许多一个,最多可以超过40%,那就允许多两个

   maxUnavailable<string>

     The maximum number of pods that can be  unavailable during the update. Value

     can be an absolute number (ex: 5) or a  percentage of desired pods (ex:

     10%). Absolute number is calculated from  percentage by rounding down. This

     can not be 0 if MaxSurge is 0. Defaults  to 25%. Example: when this is set

     to 30%, the old ReplicaSet can be scaled  down to 70% of desired pods

     immediately when the rolling update  starts. Once new pods are ready, old

     ReplicaSet can be scaled down further,  followed by scaling up the new

     ReplicaSet, ensuring that the total  number of pods available at all times

     during the update is at least 70% of  desired pods.

#最多允许几个不可用

假设有5个副本,最多一个不可用,就表示最少有4个可用

deployment是一个三级结构,deployment控制replicaset,replicaset控制pod,

例子:用deployment创建一个pod

[root@xianchaomaster1~]# cat deploy-demo.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp-v1

  namespace: blue-green

spec:

  replicas: 2

  selector:

   matchLabels:

    app: myapp

    version: v1

  template:

   metadata:

    labels:

     app: myapp

     version: v1

   spec:

    containers:

    - name: myapp

      image: janakiramm/myapp:v1

      imagePullPolicy: IfNotPresent

      ports:

      - containerPort: 80

更新资源清单文件:

[root@xianchaomaster1~]# kubectl apply -f deploy-demo.yaml

查看deploy状态:

[root@xianchaomaster1~]# kubectl get deploy -n blue-green

显示如下:

NAME       READY  UP-TO-DATE   AVAILABLE   AGE

myapp-v1     2/2     2               2           60s

创建的控制器名字是myapp-v1

[root@xianchaomaster1~]# kubectl get rs -n blue-green

显示如下:

AME                  DESIRED   CURRENT  READY   AGE

myapp-v1-67fd9fc9c8   2        2            2       2m35s

创建deploy的时候也会创建一个rs(replicaset),67fd9fc9c8这个随机数字是我们引用pod的模板template的名字的hash值

[root@xianchaomaster1~]# kubectl get pods -n blue-green

显示如下:

NAME                        READY   STATUS   RESTARTS   AGE

myapp-v1-67fd9fc9c8-tsl92   1/1    Running   0          3m23s

myapp-v1-67fd9fc9c8-np57d   1/1    Running   0          3m23s

通过deployment管理应用,在更新的时候,可以直接编辑配置文件实现,比方说想要修改副本数,把2个变成3个

[root@xianchaomaster1~]# cat  deploy-demo.yaml

直接修改replicas数量,如下,变成3

spec:

  replicas: 3

修改之后保存退出,执行

[root@xianchaomaster1~]# kubectl apply -f deploy-demo.yaml

注意:apply不同于create,apply可以执行多次;create执行一次,再执行就会报错有重复。

[root@xianchaomaster1~]# kubectl get pods  -n blue-green

显示如下:

NAME                        READY   STATUS   RESTARTS   AGE

myapp-v1-67fd9fc9c8-tsl92   1/1    Running   0         8m18s

myapp-v1-67fd9fc9c8-4bv5n   1/1    Running   0          8m18s

myapp-v1-67fd9fc9c8-cw59c   1/1    Running   0          18s

上面可以看到pod副本数变成了3个

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

[root@xianchaomaster1~]# kubectl describe deploy myapp-v1 -n blue-green

#显示如下:

Name:                   myapp-v1

Namespace:              blue-green

CreationTimestamp:      Sun, 21 Mar  2021 18:46:52 +0800

Labels:                  <none>

Annotations:             deployment.kubernetes.io/revision: 1

Selector:               app=myapp,version=v1

Replicas:               3 desired |  3 updated | 3 total | 3 available | 0 unavailable

StrategyType:            RollingUpdate

#默认的更新策略rollingUpdate

MinReadySeconds:        0

RollingUpdateStrategy:  25% max  unavailable, 25% max surge

#最多允许多25%个pod,25%表示不足一个,可以补一个

Pod Template:

  Labels:  app=myapp

           version=v1

  Containers:

   myapp:

    Image:        janakiramm/myapp:v1

    Port:         80/TCP

    Host Port:    0/TCP

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type           Status  Reason

  ----           ------  ------

  Progressing    True     NewReplicaSetAvailable

  Available      True     MinimumReplicasAvailable

OldReplicaSets:  <none>

NewReplicaSet:   myapp-v1-67fd9fc9c8  (3/3 replicas created)

Events:

  Type    Reason             Age                 From                   Message

  ----    ------             ----                ----                   -------

  Normal  ScalingReplicaSet  3m26s               deployment-controller  Scaled down replica set myapp-v1-67fd9fc9c8  to 2

  Normal  ScalingReplicaSet  2m1s (x2 over 10m)  deployment-controller  Scaled up replica set myapp-v1-67fd9fc9c8  to 3

例子:测试滚动更新

在终端执行如下:

[root@xianchaomaster1~]# kubectl get pods -l app=myapp -n blue-green -w

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

[root@xianchaomaster1~]# vim deploy-demo.yaml

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

保存退出,执行

[root@xianchaomaster1~]# kubectl apply -f deploy-demo.yaml

再回到刚才监测的那个窗口,可以看到信息如下:

NAME                        READY   STATUS   RESTARTS   AGE

myapp-v1-67fd9fc9c8-tsl92   1/1    Running   0          22m

myapp-v1-67fd9fc9c8-4bv5n   1/1    Running   0          22m

myapp-v1-67fd9fc9c8-cw59c   1/1    Running   0          14m

myapp-v1-75fb478d6c-24tbp   0/1    Pending   0          0s

myapp-v1-75fb478d6c-24tbp   0/1    Pending   0          0s

myapp-v1-75fb478d6c-24tbp   0/1    ContainerCreating   0          0s

myapp-v1-75fb478d6c-24tbp   1/1    Running             0          11s

myapp-v1-67fd9fc9c8-cw59c   1/1    Terminating         0          15m

myapp-v1-75fb478d6c-f52l6   0/1    Pending             0          0s

myapp-v1-75fb478d6c-f52l6   0/1    Pending             0          0s

myapp-v1-75fb478d6c-f52l6   0/1    ContainerCreating   0          0s

myapp-v1-67fd9fc9c8-cw59c   0/1    Terminating         0          15m

myapp-v1-75fb478d6c-f52l6   1/1    Running             0          11s

myapp-v1-67fd9fc9c8-4bv5n   1/1    Terminating         0          23m

myapp-v1-75fb478d6c-jlw28   0/1    Pending             0          0s

myapp-v1-75fb478d6c-jlw28   0/1    Pending             0          0s

myapp-v1-75fb478d6c-jlw28   0/1    ContainerCreating   0          0s

myapp-v1-75fb478d6c-jlw28   1/1    Running             0          1s

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

在另外一个窗口执行

[root@xianchaomaster1~]# kubectl get rs -n blue-green

显示如下:

NAME                  DESIRED   CURRENT  READY   AGE

myapp-v1-75fb478d6c   3        3         3       2m7s

myapp-v1-67fd9fc9c8   0        0         0       25m

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

[root@xianchaomaster1~]# kubectl rollout history deployment myapp-v1 -n blue-green

查看myapp-v1这个控制器的滚动历史,显示如下:

deployment.apps/myapp-v1

REVISION  CHANGE-CAUSE

1         <none>

2         <none>

回滚操作如下:

[root@xianchaomaster1~]# kubectl rollout undo deployment/myapp-v1 --to-revision=2 -n blue-green

12.3 自定义滚动更新策略

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

取值范围

数值

1. maxUnavailable: [0, 副本数]

2. maxSurge: [0, 副本数]

注意:两者不能同时为0。

比例

1. maxUnavailable: [0%, 100%] 向下取整,比如10个副本,5%的话==0.5个,但计算按照0个;

2. maxSurge: [0%, 100%] 向上取整,比如10个副本,5%的话==0.5个,但计算按照1个;

注意:两者不能同时为0。

建议配置

1. maxUnavailable == 0

2. maxSurge == 1

这是我们生产环境提供给用户的默认配置。即“一上一下,先上后下”最平滑原则:

1个新版本pod ready(结合readiness)后,才销毁旧版本pod。此配置适用场景是平滑更新、保证服务平稳,但也有缺点,就是“太慢”了。

总结:

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

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

自定义策略:

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

[root@xianchaomaster1 ~]# kubectlpatch deployment myapp-v1 -p'{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1}}}}' -n blue-green

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

[root@xianchaomaster1 ~]# kubectldescribe deployment myapp-v1 -n blue-green

显示如下:

RollingUpdateStrategy:  1 max unavailable, 1 max surge

上面可以看到RollingUpdateStrategy: 1 maxunavailable, 1 max surge

这个rollingUpdate更新策略变成了刚才设定的,因为我们设定的pod副本数是3,1和1表示最少不能少于2个pod,最多不能超过4个pod

这个就是通过控制RollingUpdateStrategy这个字段来设置滚动更新策略的

微信公众号

c7f02fe02bca34ec91dd9fa98ddaa027.png

作者微信:luckylucky421302

9dcf95bb6f6d0675405ce24ee62a3040.png

精彩文章推荐

k8s核心技术+Istio微服务+SpringCloud微服务+DevOps+Helm等最佳落地实践

基于Jenkins和k8s构建企业级DevOps容器云平台

k8s原生的CI/CD工具tekton

K8S二次开发-自定义CRD资源

基于Jenkins+git+harbor+Helm+k8s+Istio构建DevOps流水线

基于k8s+Prometheus+Alertmanager+Grafana构建企业级监控告警系统

k8s开启临时容器ephemeral进行debug调试

k8s更新策略-系列文章第一篇:蓝绿发布

f369f6fa03d7b428b222498d77831b4e.png

                   点亮,服务器10年不宕机f99c5147c8c938fc246ef0b494b58e82.gif

dea2ee2788ff81df1a38e9b61682571a.gif 点击阅读 | 了解更多

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐