Kubernetes(九)Deployment滚动更新

小知识点

kubectl  get pods podA -n NAMEAPSCE -o yaml --export

如果'不带上--export'  生成文件会有'很多无用的内容'

备注: 可以换成'其它系列'的资源

注意: 新版本已经'废弃'-->1.18.4有,1.19.3已经废弃了

一    Deployment理解

Deployment 是'Workload'中的一种 --> '无状态应用'

滚动更新 --> 理解为'灰度发布一种',只是'粒度'不一样

+++++++++++++++

滚动更新: 比如我们应用更新了,我们只需要'更新我们的容器镜像',然后修改 Deployment 里面的 'Pod 模板镜像',那么 Deployment 就会用'滚动更新(Rolling Update)'的方式来升级现在的 Pod

明确滚动更新'触发的表现形式' --> 'set image'、'path字段'、'修改后直接apply'

而 Deployment '这个能力的实现',依赖的' ReplicaSet 这个资源对象',实际上我们可以通俗的理解就是'每个 ReplicaSet' 就对应集群中的'一次部署'

(1)本章节的示例代码

apiVersion: apps/v1
kind: Deployment  
metadata:
  name:  nginx-deploy
  namespace: default
spec:
  replicas: 3  '期望的 Pod 副本数量'
  selector:  Label Selector,'必须匹配 Pod 模板中的标签'
    matchLabels:
      app: nginx
  template:    'Pod 模板'
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
+++++++++++++ '重点知识'

1)dp通过'控制rs'来'控制pod'

2)目前'更新应用'-->通过'镜像版本'来标识

3)ds的'名字发生变化'--> 由于'修改template中的属性了'

1)deployment部署,然后查看pod状态 

2)思考ds

结果: 这个 'Pod 的控制器'是一个 ReplicaSet 对象啊,我们'不是创建的一个 Deployment 吗'?为什么 Pod 会'被 RS 所控制呢'?

3)看下这个对应的 RS 对象的详细信息

意思就是我们的'Pod 依赖的控制器'--> 'RS 实际上被我们的 'Deployment 控制着'

4) deployment、replicaset、pod之间的关系

ReplicaSet '明确调整 Pod 的个数',而 Deployment 是通过管理 ReplicaSet 的'数量和属性'来实现'水平扩展/收缩'以及'滚动更新'两个功能的

Deployment

二    滚动更新理解

如果只是'水平扩展/收缩'这两个功能,就完全'没必要设计 Deployment 这个资源对象了',Deployment 最突出的一个功能是'支持滚动更新'

说明: ReplicSet也能完成'水平扩展/收缩'

(1)滚动更新的方案

1)Recreate      -->'先删除所有'已存在的pod,'重新创建新的';

2)RollingUpdate -->'滚动升级','逐步替换-->灰度替换'的策略,同时滚动升级时,支持更多的'附加参数';例如设置'最大不可用'pod数量,'最小升级间隔'时间等等

(2)Recreate

apiVersion: apps/v1
kind: Deployment
metadata:
  name:  nginx-deploy
  namespace: default
spec:
  replicas: 3  # 期望的 Pod 副本数量,默认值为1
  selector:  # Label Selector,必须匹配 Pod 模板中的标签
    matchLabels:
      app: nginx
  strategy:
    type: Recreate '关注这个字段'
  template:  # Pod 模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

注意: 滚动更新的时候加上'--record参数',使用此参数将'记录后续创建对象的操作-->记录当时滚动更新的命令',方便'管理'与'问题追溯'

备注: 后续我们通过'其它策略'让滚动更新时记录的'CHANGE-CAUSR' -->变得'更有意义'

(3)RollingUpdate

minReadySeconds'含义'

当'新的'pod启动'多少秒'后,再kill'掉旧'的pod

这里需要估一个'比较合理'的值-->从容器启动到'应用正常提供服务'

     maxSurge: 升级过程中,比目标pod'多出的'pod数量('某个时刻') -->'绝对值和百分比'(默认是25%)

     maxUnavailable:  最大'不能提供'服务的pod

     策略:  先创建'maxSurge'个,然后删除'maxUnavailable'个

滚动更新的三种方式

1)修改配置文件 -->最好做'版本控制',每次通过'不同的文件-->不同文件标识不同的配置'或者'相同的文件名-->即使record记录了,但是也毫无意义'

2)path修改字段 --> 以'补丁的形式'修改-->'set image'也算是patch中特殊的一种

3)set image   --> '直截了当,record看到当前对应更新的原因'

修改yaml文件中的镜像信息准备滚动更新

'3+1+1' -->先创建一个('过程'-->'最大4个pod')-->删除一个(最多一个'不能提供服务')
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  nginx-deploy
  namespace: default
spec:
  replicas: 3  # 期望的 Pod 副本数量,默认值为1
  selector:  # Label Selector,必须匹配 Pod 模板中的标签
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 1          '理解含义'  -->'百分比向上取整'
      maxUnavailable: 1    '理解含义'
  template:  # Pod 模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx  '1.18-->latest'
        ports:
        - containerPort: 80
~                           

查看滚动更新的过程

1) get pods -w          -->'查看过程'

2) rollout status       -->'查看详细信息的滚动过程'

3) describle deployment -->'看到详细的信息'-->更'推荐'

上面过程: '先启动'一个'新'的 Pod,'杀掉'一个'旧'的 Pod,然后再启动一个新的 Pod,这样滚动更新下去,直到全都变成新的 Pod

思考:如果replicas和images同时改变,如何滚动更新

例如: replica '4-->3'; image  --> 'nginx:1.18 --> nginx:latest'

所以 Deployment 控制器首先是将'old-->之前控制'的 nginx-deploy-7848d4b86f 这个 RS 资源对象'先进行缩容'操作,然后'滚动更新'开始了

Deployment RollingUpdate

思考:rs的名称组成

rs名称 = 'deployment名称' + 'yaml文件的哈希数值-->随机字符串'

思考:随机字符串'如何生成的'

pod名字: 'deployment名字'-'replicaset模板hash名字'-'pod模板hash名字'

需求:暂停过程发现有小问题

滚动更新  '暂停'

kubectl rollout 'pause' deployment app

备注: '此时的状态' -->混合达到'预期'的数目吗?

需求:发现没有问题,滚动更新继续

kubectl rollout 'resume' deploy app

需求:想查看滚动更新的历史

kubectl rollout history deployment nginx-deploy

CHANGE CAUSE -->'需要滚动更新的时候加上 --record参数' --> 把'执行的命令记录'下来 --> '上面讲解了记录的方式'

思考:如何让'CHANGE CAUSE更有意义' --> kubectl set image deployment/nginx nginx=nginx:1.16 --record

形式:  'image' (-f FILENAME | TYPE NAME) 'CONTAINER_NAME_1'=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N

需求:升级发现有大问题,如何回滚到指定版本

回滚'undo'到'指定'版本 --> 类似git的'回退'

kubectl 'rollout undo' deployment app --to-revision=1

备注: 如果'没有指定'具体版本,默认是'最近的一个历史'版本

每次更新应用的时候都会'记录下当前的配置',保存为一个'revision',这样就可以'回滚到某个特定的'revision

备注: 'deploy配置'和'revision'是一一对应的

简单原理: undo '某个revision' --> 查看对应'rs中匹配的'revision --> 按照'rs模板'创建
备注: 这种'文件形式',可以'多处改动',纳入'git版本控制'更好 --> 通过'yaml文件'的版本控制进行滚动更新

注意: record仅仅'一条记录信息(保证意义)',而不是按照'该条指令'去滚动更新 -->例如'文件形式',回滚的时候'当前目录没有这个文件',还是可以'成功的'

目的: 让'滚动更新有意义',能够'记录'滚动的版本信息!

(4)revisionHistoryLimit

思考

上面的结果可以看出在执行Deployment升级的时候最好带上record参数,便于查看历史版本信息

默认情况下,所有通过kubectl xxxx --record都会被kubernetes记录到etcd进行持久化,这无疑会占用资源,最重要的是,时间久了,当你kubectl get rs时,会有成百上千的垃圾RS返回给你,那时你可能就眼花缭乱了

生产环境:我们最好通过设置Deployment的.spec.revisionHistoryLimit来限制最大保留的revision number

比如15个版本,回滚的时候一般只会回滚到最近的几个版本就足够了,系统默认是记录最近的10个更新记录,一般10个就不少了

 

++++++++++++  '深层次思考'  ++++++++++++

滚动更新的过程'没有完成',又继续进行滚动更新,导致'rollout history'记录的信息不准确

'换句话说': 上次滚动更新没有完成,'又进行'滚动更新

导致现象: revisionHistoryLimit超过'预设'的数值

代码分析原因: 回滚'删除revision与否',是通过'判断rs下面的pod数量是否为0',如果pod不为0,则不会删除该revision

+++++++++++++++++++++ '分割线'

revisorHIstoryLimit:3 --> 当前rs'没有pod'才会删除

做法:没有等到滚动更新完成,又'修改参数'进行滚动更新

rs是否能够真正的被删除的'标准' -->'没有副本的时候才可以删除','换句话说'滚动更新的过程中'只能删除没有pod的rs'

rollout history 读取的是rs

(5)滚动更新的原理

Deployment

首先: 在前面我们'知道deploy是通过控制rs来控制pod的副本',通过'滚动更新'我们看到'产生了许多rs'

rollout history中'记录的revision个数'都和'ReplicaSets'一一对应

验证:手动delete某个ReplicaSet,对应的rollout history是否会被删除

结论: 一旦'手动删除rs',ectd中就'没有记录了',对应的rollout history中'记录的record会被删除',后续无法'回滚到这个revison了'

后续: '本地缓存'是否会影响

可以'回滚的原因':rs保存了'当前资源的信息'(-o yaml导出)、只是'这个rs下面没有pod'

后续1:查询etcd中存储的

后续2:直接做滚动更新,导致请求丢失,如何避免0宕机,引出Service

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值