【概念介绍】
“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)'