Kubernetes专栏

Kubernetes:Deployment剖析

2021-03-27  本文已影响0人  wyatt_plus

一. 简介

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 的个数和属性,进而实现“水平扩展 / 收缩”和“滚动更新”这两个编排动作。

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种状态,详细含义如下:

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 发布方式区别

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

五. 总结

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

上一篇下一篇

猜你喜欢

热点阅读