API对象--Deployment(chrono《kubernetes入门实战课》笔记整理)

【概念介绍】

“Deployment”,顾名思义,它是专门用来部署应用程序的,能够让应用永不宕机,多用来发布无状态的应用,是 Kubernetes 里最常用也是最有用的一个对象。之前学习过的两个API对象: Job 和 CronJob,通过对 Pod 的包装,向 Pod 添加控制字段,实现了基于 Pod 运行两大离线业务的功能(临时任务和定时任务)。

对于在线业务的监管,调度,基于k8s里“单一职责”和“对象组合”的原则,可使用deployment来进行控制。因为如果把在线业务放在pod里,如果pod也挂了怎么办呢?谁来负责这些pod的状态呢?还是应该使用独立的api对象来进行这项工作。

【如何使用 YAML 描述 Deployment】

使用kubectl api-resources | grep deploy查看对应描述。

[root@master ~]# kubectl api-resources | grep deploy
deployments                       deploy       apps/v1                                true         Deployment
[root@master ~]#

所以yaml的基本格式为:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: xxx-dep

通过使用kubectl create 来创建 Deployment 的 YAML 样板,免去反复手工输入的麻烦。

export out="--dry-run=client -o yaml"
kubectl create deploy ngx-dep --image=nginx:alpine $out

可以得到如下的yml:

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: ngx-dep
  name: ngx-dep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ngx-dep
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: ngx-dep
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        resources: {}
status: {}
复制代码

“spec”部分多了 replicas、selector 这两个新字段,而这两个字段,就是 Deployment 特殊能力的根本。

【Deployment 的关键字段】

1、replicas:就是“副本数量”的意思,也就是说,指定要在 Kubernetes 集群里运行多少个 Pod 实例。就相当于为 Kubernetes 明确了应用部署的“期望状态”,Deployment 对象就可以扮演运维监控人员的角色,自动地在集群里调整 Pod 的数量。

比如,Deployment 对象刚创建出来的时候,Pod 数量肯定是 0,那么它就会根据 YAML 文件里的 Pod 模板,逐个创建出要求数量的 Pod。接下来 Kubernetes 还会持续地监控 Pod 的运行状态,万一有 Pod 发生意外消失了,数量不满足“期望状态”,它就会通过 apiserver、scheduler 等核心组件去选择新的节点,创建出新的 Pod,直至数量与“期望状态”一致。

2、selector:它的作用是“筛选”出要被 Deployment 管理的 Pod 对象,下属字段“matchLabels”定义了 Pod 对象应该携带的 label,它必须和“template”里 Pod 定义的“labels”完全相同,否则 Deployment 就会找不到要控制的 Pod 对象,apiserver 也会告诉你 YAML 格式校验错误无法创建。

复制代码
...
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ngx-dep
      
  template:
    metadata:
      labels:
        app: ngx-dep
    ...
复制代码

之所以要这样严谨地对应起来,是因为在线业务和离线业务的应用场景差异很大。离线业务中的 Pod 基本上是一次性的,只与这个业务有关,紧紧地绑定在 Job 对象里,一般不会被其他对象所使用。而在线业务就要复杂得多了,因为 Pod 永远在线,除了要在 Deployment 里部署运行,还可能会被其他的 API 对象引用来管理,比如负责负载均衡的 Service 对象,也可能对这个pod进行一些负载均衡方面的管理。那么deployment和pod就不能强绑定,否则其他API对象就无法对这些pod来管理了。

所以 Deployment 和 Pod 实际上是一种松散的组合关系,Deployment 实际上并不“持有”Pod 对象,它只是帮助 Pod 对象能够有足够的副本数量运行,其他的api对象也是有可能来管理这些pod的。如果像 Job 那样,把 Pod 在模板里“写死”,那么其他的对象再想要去管理这些 Pod 就无能为力了。

Kubernetes 采用的是这种“贴标签”的方式,通过在 API 对象的“metadata”元信息里加各种标签(labels),我们就可以使用类似关系数据库里查询语句的方式,筛选出具有特定标识的那些对象。通过标签这种设计,Kubernetes 就解除了 Deployment 和模板里 Pod 的强绑定,把组合关系变成了“弱引用”。让他们既有联系,又不会“霸权”。如下图所示:

 

 【如何使用 kubectl 操作 Deployment】

1、写好yml后,apply一下;

kubectl apply -f deploy.yml

2、查看状态。被 Deployment 管理的 Pod 自动带上了名字,命名的规则是 Deployment 的名字加上两串随机数(其实是 Pod 模板的 Hash 值)。:

kubectl get deploy

 

 1)READY 表示运行的 Pod 数量,前面的数字是当前数量,后面的数字是期望数量,所以“1/1”的意思就是要求有1个 Pod 运行(分母),现在已经启动了1个Pod(分子);

2)UP-TO-DATE 指的是当前已经更新到最新状态的 Pod 数量。因为如果要部署的 Pod 数量很多或者 Pod 启动比较慢,Deployment 完全生效需要一个过程,UP-TO-DATE 就表示现在有多少个 Pod 已经完成了部署,达成了模板里的“期望状态”;

3)AVAILABLE 要比 READY、UP-TO-DATE 更进一步,不仅要求已经运行,还必须是健康状态,能够正常对外提供服务,它才是我们最关心的 Deployment 指标;

4) AGE表示 Deployment 从创建到现在所经过的时间,也就是运行的时间。

【功能的尝试】

1、delete掉deployment部署的pod,看看效果。可以看到立刻被重新拉起了。Deployment 确实实现了它预定的目标,能够让应用“永远在线”“永不宕机”。

 

 【更多的内容】

1、扩容缩容:在 Deployment 部署成功之后,还可以随时调整 Pod 的数量,实现所谓的“应用伸缩”。这项工作在 Kubernetes 出现之前对于运维来说是一件很困难的事情,而现在由于有了 Deployment 就变得轻而易举了。

kubectl scale 是专门用于实现“扩容”和“缩容”的命令,你只要用参数 --replicas 指定需要的副本数量,Kubernetes 就会自动增加或者删除 Pod,让最终的 Pod 数量达到“期望状态”。如下命令,就是扩容到5个:

kubectl scale --replicas=5 deploy ngx-dep

但要注意, kubectl scale 是命令式操作,扩容和缩容只是临时的措施,如果应用需要长时间保持一个确定的 Pod 数量,最好还是编辑 Deployment 的 YAML 文件,改动“replicas”,再以声明式的 kubectl apply 修改对象的状态。

2、selector中lable的用法:之前我们通过 labels 为对象“贴”了各种“标签”,在使用 kubectl get 命令的时候,加上参数 -l,使用 ==、!=、in、notin 的表达式,就能够很容易地用“标签”筛选、过滤出所要查找的对象,效果和 Deployment 里的 selector 字段是一样的。

如下示例,第一条命令找出“app”标签是 nginx 的所有 Pod,第二条命令找出“app”标签是 ngx、nginx、ngx-dep 的所有 Pod:

kubectl get pod -l app=nginx
kubectl get pod -l 'app in (ngx, nginx, ngx-dep)'

posted @   1234roro  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示