美文网首页Kubernetes专栏
Kubernetes:Deployment剖析

Kubernetes:Deployment剖析

作者: wyatt_plus | 来源:发表于2021-03-27 07:03 被阅读0次

    一. 简介

    Deployment是Kubernetes“控制器模式”的最基础的完整实现之一,但是却提供了Pod 的“水平扩展 / 收缩”(horizontal scaling out/in)的能力,这是非常核心的编排能力。

    关于本文的代码,都在如下的地址中:Github资源

    二. 核心

    2.1 架构设计

    Deployment 实际上是一个两层控制器。首先,它通过 ReplicaSet 的个数来描述应用的版本;然后,它再通过 ReplicaSet 的属性(比如 replicas 的值),来保证 Pod 的副本数量。
    具体的deployment-replicaset-pod之间的关系可以如下图展示:


    deployment-replicaset

    2.2 ReplicaSet

    ReplicaSet 对象,其实就是由副本数目的定义和一个 Pod 模板组成的,其实就是是 Deployment 的一个子集。Deployment 的控制器,实际上控制的是 ReplicaSet 的数目,以及每个 ReplicaSet 的属性。

    2.3 滚动更新

    将一个集群中正在运行的多个 Pod 版本,交替地逐一升级的过程,就是“滚动更新”。这两个比例的值都是可以配置的,默认都是 DESIRED 值的 25%。

    三. 创建Deployment流程

    关于基于Deployment的自动扩容流程可以借助一个完整案例展示出来。

    3.1 创建Depolyment YAML

    定义一个 demo-deployment,它定义的 Pod 副本个数是 5 (spec.replicas=5)

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-deployment
      labels:
        app: nginx
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.8.0
            ports:
            - containerPort: 80
    

    3.2 水平扩展/收缩分析

    ReplicaSet 负责通过“控制器模式”,保证系统中 Pod 的个数永远等于指定的个数(5 个)。 所以,Deployment 只允许容器的 restartPolicy=Always 的主要原因:只有在容器能保证自己始终是 Running 状态的前提下,ReplicaSet 调整 Pod 的个数才有意义。
    Deployment 同样通过“控制器模式”,来操作 ReplicaSet 的个数和属性,进而实现“水平扩展 / 收缩”和“滚动更新”这两个编排动作。

    • 水平扩展
      Deployment Controller 只需要修改它所控制的 ReplicaSet 的 Pod 副本个数就可以了。比如,把这个值从 5 改成 6,那么 Deployment 所对应的 ReplicaSet,就会根据修改后的值自动创建一个新的 Pod。
    • 水平收缩
      按照上面流程按序反向删除即可。

    3.3 创建

    执行如下的创建指令即可:

    kubectl apply -f demo-deployment.yaml --record
    

    关于–record 参数,可与记录下每次操作所执行的命令,以方便后面查看。

    3.4 检查Deployment状态

    执行如下指令可以查看deployments的整体状态:

    kubectl get deployments
    # result
    NAME              READY   UP-TO-DATE   AVAILABLE   AGE
    demo-deployment   5/5     5            5           24s
    

    关于图中的3种状态,详细含义如下:

    • READY:分子代表当前处于 Running 状态的 Pod 的个数,分母代表用户期望的 Pod 副本个数(spec.replicas 的值)。
    • UP-TO-DATE:当前处于最新版本的 Pod 的个数,所谓最新版本指的是 Pod 的 Spec 部分与 Deployment 里 Pod 模板里定义的完全一致。
    • AVAILABLE:当前已经可用的 Pod 的个数,即:既是 Running 状态,又是最新版本,并且已经处于 Ready(健康检查正确)状态的 Pod 的个数。
      所以, AVAILABLE 字段,描述的才是用户所期望的最终状态。

    3.5 实时滚动状态

    实时查看 Deployment 对象的状态变化,执行如下指令:

    kubectl rollout status deployment/demo-deployment
    

    关于真实的滚动状态,手速要快,执行完apply后立即查看,结果如下:


    rollout status

    3.6 查看ReplicaSet状态

    执行如下指令:

    kubectl get rs
    
    replicaSet status
    在用户提交了一个 Deployment 对象后,Deployment Controller 就会立即创建一个 Pod 副本个数为 5 的 ReplicaSet。这个 ReplicaSet 的名字,则是由 Deployment 的名字和一个随机字符串共同组成。
    随机规则叫作pod-template-hash,ReplicaSet 会把这个随机字符串加在它所控制的所有 Pod 的标签里,从而保证这些 Pod 不会与集群里的其他 Pod 混淆。

    3.7 检查Events

    为了产生事件,我在demo-deployment-v1.yaml里面调整了nginx的版本,并执行创建了。所以执行如下指令,可以看到这5个Pod的滚动更新状态。

    kubectl describe deployment demo-deployment
    

    通过查看 Deployment 的 Events,看到这个“滚动更新”的流程:


    events

    像这样,将一个集群中正在运行的多个 Pod 版本,交替地逐一升级的过程,就是“滚动更新”。

    3.8 ReplicaSet最终状态

    执行如下指令,获取ReplicaSet的最终状态:

    kubectl get rs
    # result
    NAME                         DESIRED   CURRENT   READY   AGE
    demo-deployment-5d59d67564   5         5         5       7m22s
    demo-deployment-64c9d67564   0         0         0       13m
    

    结果如下,旧 ReplicaSet(hash=64c9d67564)已经被“水平收缩”成了 0 个副本。


    image

    四. 拓展

    4.1 历史回滚

    我们可以通过kubectl rollout undo命令,就能把整个 Deployment 进行回滚。

    1. 检查历史版本
      我需要使用 kubectl rollout history 命令,查看每次 Deployment 变更对应的版本。而由于我们在创建这个 Deployment 的时候,指定了–record 参数,所以我们创建这些版本时执行的 kubectl 命令,都会被记录下来。
      指令如下:
    kubectl rollout history deployment/demo-deployment
    deployment.apps/demo-deployment
    REVISION  CHANGE-CAUSE
    1         kubectl apply --filename=demo-deployment.yaml --record=true
    2         kubectl apply --filename=demo-deployment-v2.yaml --record=true
    

    结果如下图:


    history

    注意:关于这个结果,是从上向下查看,版本号从Index 1开始。

    1. 查看指定版本内容
      根据上图,我们打算回查看版本1内容,所以我们执行如下指令:
    kubectl rollout history deployment/demo-deployment --revision=1
    

    具体内容如下:


    version-1
    1. 回滚到指定版本
      执行如下的回滚指令:
    kubectl rollout undo deployment/demo-deployment --to-revision=1
    

    Deployment Controller 还会按照“滚动更新”的方式,完成对 Deployment 的降级操作。

    1. 设置历史版本数量
      spec.revisionHistoryLimit,就是 Kubernetes 为 Deployment 保留的“历史版本”个数。如果把它设置为 0,就不支持回滚操作。

    4.2 发布方式区别

    关于‘金丝雀发布’,‘蓝绿发布’和‘滚动发布’之间的区别,就以如下简单的总结。

    • 金丝雀部署
      金丝雀发布的好处在于可以用真实环境测试新版本,当新版本存在问题时最多只影响部分用户,且支持安全快速的回滚策略(将路由到新版本上的流量切换到其它的老版本机器上即可)
    • 蓝绿发布
      目的是减少因发布导致的服务中断时间,同时它也支持发布失败时的快速回滚。
      蓝绿部署需要在发布过程中,同时运行两套程序。对硬件的要求也是当前所需的2倍,比如当前运行时,需要10台服务器支撑业务,那么使用蓝绿部署,你就需要购置20台服务器。
    • 滚动升级
      滚动发布能够解决掉蓝绿部署时对硬件要求增倍的问题。
      所谓滚动发布,就是在发布过程中,并不一下子启动所有新版本,而是先启动一台新版本,再停止一台老版本,然后再启动一台新版本,再停止一台老版本,直到全部发布完成,这样的话,如果当前需要10台服务器支撑服务,那么升级过程中一共只需要11台就行了。

    五. 总结

    Kubernetes 项目对 Deployment 的设计,实际上是代替我们完成了对“应用”的抽象,使得我们可以使用这个 Deployment 对象来描述应用,使用 kubectl rollout 命令控制应用的版本。
    关于Deployment是日常无状态应用中最常见的组件,使用很简单,但是灵活使用很难。毕竟,工具始终是死的,主要还是看个人的符合场景的架构设计。

    欢迎关注个人博客: Wyatt's Blog

    Reference

    https://ixyzero.com/blog/archives/4722.html
    https://time.geekbang.org/column/article/40906?utm_campaign=guanwang&utm_source=baidu-ad&utm_medium=ppzq-pc&utm_content=title&utm_term=baidu-ad-ppzq-title

    相关文章

      网友评论

        本文标题:Kubernetes:Deployment剖析

        本文链接:https://www.haomeiwen.com/subject/gisehltx.html