作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122796352
目录
第1章 什么是Deployment工作负载资源
1.1 工作负载总体概述
1.2 什么是Deployment
1.3 Deployment的应用场合
1.4 ReplicationSet(RS)和ReplicationController(RC)概念
1.5 Deployment、RS、Pod它们三者之间的关系:
第2章 Deployment的镜像更新策略
2.1 更新策略
2.2 滚动升级
2.3 滚动回退(回滚)
2.4 金丝雀发布,也叫做灰度发布
2.5 Deployment配置文件详解
第3章 Deployment常见特性与操作命令
3.1 显示当前的Deployment
3.2 新创建一个Deployment
3.3 Deployment多副本的能力
3.4 Deployment的故障治愈能力
3.5 Deployment的故障转移能力
3.6 删除一个Depolyment
第4章 Depolyment高级特性相关的命令
4.1 扩容与缩容能力:kubectl scale
4.2 pod对应的Docker镜像更新:kubectl set image
4.3 版本回退:kubectl rollout
[云原生专题-31]:K8S - 核心概念 - 大规模pods编排工具:工作负载(workloads)资源及其八大特性_文火冰糖(王文兵)的博客-CSDN博客
为了更好地解决服务编排的问题,k8s在V1.2版本开始,引入了deployment控制器,它是工作负载资源中的一种,主要针对的无状态应用程序pods的编排问题。
值得一提的是,这种控制器并不直接管理pod,而是通过管理replicaset来间接管理pod,即:deployment管理replicaset,replicaset管理pod。
replicaset(简称RS)构建在pods之上 ,用于编排pods的多个实例,每个实例可以运行在不同的节点之上。
deployment构建在replicaset之上,增加了一些新的功能强大的编排策略。所以deployment比replicaset的功能更强大。
虽然replicaset也是可以单独使用的,但是一般推荐和Deployment一起使用,这样会使得的Deployment提供的一些回滚更新操作同样用于replicaset上,因为replicaset不支持回滚更新操作,Deployment支持。
有了deployment,我们就不直接部署无状态的Pod,而是通过 Deployment 来创建 Pod,由 Deployment 来负责创建、更新、维护其所管理的所有 Pods。
这里就需要说一下ReplicationSet(RS:副本组)和ReplicationController(RC:副本控制器),RS是在RC基础上发展来的,在新版的Kubernetes中,已经将RC替换为RS 了,它们两者没有本质的区别,都是用于Pod副本数量的维护与更新的,使得副本数量始终维持在用户定义范围内,即如果存在容器异常退出,此时会自动创建新的Pod进行替代;而且异常多出来的容器也会自动回收。
RS负责控制副本数量,由Deployment来创建具体的Pod。
pods镜像的更新是Deployment一个非常重要的功能,是支持敏捷开发和DevOps的一个必不可少的能力。
(1)镜像更新的方向
(2)镜像更新的策略
Deployment控制器支持两种镜像版本更新策略:滚动更新(rolling update)和重新创建(recreate),默认为滚动更新。可以通过strategy选项进行配置。
先删除所有pod,然后在一个个创建新pod, 这种方式先删除所有需要更新的pod,然后再创建新的pod,如果新pod创建有问题,就会有系统有较大的影响。
创建-》删除-》创建-》删除-》....., 这种方式是,先创建一部分,删除一部分,然后再创建一部分,再删除一部分,对系统的影响非常小,因此滚动更新是默认更新方式,缺点更新的速度较慢,过程复杂。在更新的过程中,同一时间有两个版本。
滚动更新又分为:滚动升级与滚动回退。
滚动升级是默认的更新策略,它在删除一部分旧版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是升级期间,容器中应用提供的服务不会中断,但要求应用程序能够应对新旧版本同时工作的情形,例如新旧版本兼容同一个数据库方案等。不过,更新操作期间,不同客户端得到的响应内容可能会来自不同版本的应用。
Deployment控制器的滚动更新操作并非在同一个ReplicaSet控制器对象下删除并创建Pod资源,而是将它们分置于两个不同的控制器之下:旧控制器的Pod对象数量不断减少的同时,新控制器的Pod对象数量不断增加,直到旧控制器不再拥有Pod对象,而新控制器的副本数量变得完全符合期望值为止,如图所示:
滚动更新时,应用升级期间还要确保可用的Pod对象总数量不低于某阈值,以确保可以持续处理客户端的服务请求,变动的方式和Pod对象的数量范围将通过spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable两个属性协同进行定义,它们的功用如图所示:
上述案例中,删除一个V1版本的Pod,然后创建2个V2版本的Pod。
maxSurge和maxUnavailable属性的值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行滚动更新操作。
Deployment也支持用户保留其滚动更新历史中的旧ReplicaSet对象版本,这赋予了Deployment进行应用回滚的能力:用户可按需回滚到指定的历史版本。
Deployment可保存的历史版本数量由“spec.revisionHistoryLimit”属性进行定义。当然,也只有保存于revision历史中的ReplicaSet版本可用于回滚,因此,用户要习惯性地在更新操作时指定保留旧版本。
所谓的金丝雀发布,也叫做灰度发布,就是并非一次性全部更新完所有pods。
当一批新的pod资源创建完成后,立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新的pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的pod资源滚动更新,否则立即回滚更新操作。
apiVersion: apps/v1 #版本号
kind: Deployment #Deployment类型标识
metadata: #元数据
name: #Deployment资源名称
namespace: #所属命名空间
labels: #标签
controller: deploy
spec: #详情描述
replicas: #副本数量
revisionHistoryLimit: #保留历史版本,默认是10
paused: #暂停部署,默认是false
progressDeadlineSeconds: #部署超时时间(s),默认是600
strategy: #自动编排策略
type: RollingUpdates #滚动更新策略
rollingUpdate: #滚动更新
maxSurge: #最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavaliable: #最大不可用状态的pod的最大值,可以为百分比,也可以为整数
selector: #选择器,通过它指定该控制器管理哪些pod
matchLabels: #Labels匹配规则
app: nginx-pod
matchExpressions: #Expression匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: #模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
(1)命令行
$ kubectl create namespace dev
$ kubectl get deploy -n dev -owide
$ kubectl get pods -n dev
$ kubectl delete pod -n dev
(2)UI
通过dashboard显示
(1)命令行方式
# 创建一个部署,指定docker image镜像
$ kubectl create deployment my-deploy --image=nginx:1.17.1 --replicas=3
# 创建一个部署,指定docker image镜像和名字空间
$ kubectl create deployment my-deploy --image=nginx:1.17.1 -n dev
[root@k8s-master1 ~]# kubectl get deploy -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy 3/3 3 3 43s nginx nginx:1.17.1 app=my-deploy
[root@k8s-master1 ~]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-app 2/2 Running 0 62m 192.168.36.68 k8s-node1
my-deploy-68c5f8dbb6-m2vmk 1/1 Running 0 62s 192.168.36.74 k8s-node1
my-deploy-68c5f8dbb6-rtxh2 1/1 Running 0 62s 192.168.36.73 k8s-node1
my-deploy-68c5f8dbb6-sxc4n 1/1 Running 0 62s 192.168.36.75 k8s-node1
mynginx 1/1 Running 0 69m 192.168.36.66 k8s-node1
[root@k8s-master1 ~]#
(2)配置文件方式
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deploy
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
$ kubectl delete deploy my-deploy
$ touch my-deploy.yaml
$ vi my-deploy.yaml
$ kubectl create namespace dev
$ kubectl create -f my-deploy.yaml
$ kubectl apply -f my-deploy.yaml
[root@k8s-master1 ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
my-deploy 3/3 3 3 25s
# 创建一个部署,指定docker image镜像,生成n份副本
$ kubectl create deployment my-deploy --image=nginx:1.17.1 --replicas=3
[root@k8s-master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app 2/2 Running 0 75m
my-deploy-8686b49bbd-b8w65 1/1 Running 0 11s
my-deploy-8686b49bbd-jz5cx 1/1 Running 0 11s
my-deploy-8686b49bbd-rtv7h 1/1 Running 0 11s
mynginx 1/1 Running 0 82m
$ kubectl delete pod my-deploy-8686b49bbd-rtv7h
[root@k8s-master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app 2/2 Running 0 76m
my-deploy-8686b49bbd-b8w65 1/1 Running 0 44s
my-deploy-8686b49bbd-f2m4c 1/1 Running 0 4s
my-deploy-8686b49bbd-jz5cx 1/1 Running 0 44s
mynginx 1/1 Running 0 83m
备注:直接删除pod的操作,模拟的pod节点出出故障的情形。由于不是直接删除的deployment,而是直接删除的pod,deployment会检测到其管辖的pod失效,会自动重启启动pod,新的pod有可能在原有的节点上,也可能在新的节点上。
# 先通过云平台使得某台机器shutdown
$ kubectl get pods -owide
# 等待5min
# 被shutdown机器上的pod会被deployment部署到新的节点上
(1)命令行方式
$ kubectl delete deployment mynignx
$ kubectl get pods
$ kubectl get deploy -n dev -owide
该删除操作,会删除depolyment所有的pods。
(2)通过UI方式:dashboard
(1)方式1:命令行
$ kubectl get deploy -A
[root@k8s-master1 ~]# kubectl get deploy -A
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
default my-deploy 3/3 3 3 7m19s
dev my-deploy 3/3 3 3 9m25s
kube-system calico-kube-controllers 1/1 1 1 4d2h
kube-system coredns 2/2 2 2 4d4h
kubernetes-dashboard dashboard-metrics-scraper 1/1 1 1 4d2h
kubernetes-dashboard kubernetes-dashboard 1/1 1 1 4d2h
# 自动选择节点,自动创建pod实例
$ kubectl scale deploy my-deploy --replicas=5 -n dev
# 检查扩容后的状态
[root@k8s-master1 ~]# kubectl get deploy -A
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
default my-deploy 3/3 3 3 8m11s
dev my-deploy 5/5 5 5 10m
kube-system calico-kube-controllers 1/1 1 1 4d2h
kube-system coredns 2/2 2 2 4d4h
kubernetes-dashboard dashboard-metrics-scraper 1/1 1 1 4d2h
kubernetes-dashboard kubernetes-dashboard 1/1 1 1 4d2h
(2)方式2:编辑deploy文件
$ kubectl edit deploy my-deploy -n dev
replicas: 3 => replicas: 4
$ kubectl get pod -n dev
[root@k8s-master1 ~]# kubectl get deploy -A
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
default my-deploy 3/3 3 3 11m
dev my-deploy 4/4 4 4 13m
kube-system calico-kube-controllers 1/1 1 1 4d2h
kube-system coredns 2/2 2 2 4d4h
kubernetes-dashboard dashboard-metrics-scraper 1/1 1 1 4d2h
kubernetes-dashboard kubernetes-dashboard 1/1 1 1 4d2h
(1)修改策略
strategy: #指定新的pod替换旧的pod的策略,支持两个属性:
type: #指定策略类型,支持两种策略
Recreate: #在创建出新的pod之前会先杀掉所有已存在的pod,这种更新较大的风险
RollingUpdate:#滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本pod
# 当type为RollingUpdate时生效,
rollingUpdate:
maxUnavailable:#用来指定在升级过程中不可用pod的最大数量,默认为25%
maxSurge: #用来指定在升级过程中可以超过期望的pod的最大数量,默认为25%
$ kubectl edit deploy my-deploy -n dev
strategy:
type: RollingUpdate #滚动更新策略
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
$ kubectl apply -f my-deploy.yaml
# 查看当前镜像的版本
$ kubectl get pod -n dev
$ kubectl edit deploy my-deploy -n dev
spec:
strategy: #策略
type: Recreate #重建更新策略
$ kubectl apply -f my-deploy.yaml
# 查看当前镜像的版本
$ kubectl get pod -n dev
(2)创建新镜像、更新镜像
#首先记录原本的pod名
$ kubectl get pod -n dev
# 更改pod镜像版本
$ kubectl set image deploy my-deploy nginx=nginx:1.17.2 -n dev
$ kubectl set image deploy my-deploy nginx=nginx:1.17.3 -n dev
#再次查看镜像
[root@k8s-master1 ~]# kubectl get deploy -n dev -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy 3/4 2 3 24m nginx nginx:1.17.2 app=nginx-pod
[root@k8s-master1 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
my-deploy-86f4996797-2rlc6 1/1 Running 0 50s
my-deploy-86f4996797-8qjlp 1/1 Running 0 50s
my-deploy-86f4996797-djtmj 1/1 Running 0 25s
my-deploy-86f4996797-w5hqb 1/1 Running 0 22s
(1)功能简介
所谓版本回退,就是自动把版本回退到先前更旧的版本等功能,支持的详细功能如下
(2)在rollout的过程中,查看升级状态
$ kubectl rollout status deploy my-deploy -n dev
(3)在rollout的过程中,查看升级历史
[root@k8s-master1 ~]# kubectl rollout history deploy my-deploy -n dev
deployment.apps/my-deploy
REVISION CHANGE-CAUSE
4
5
6
备注:
(4)软件版本回退:undo
[root@k8s-master1 ~]# kubectl rollout undo deploy my-deploy --to-revision=2 -n dev
error: unable to find specified revision 2 in history
[root@k8s-master1 ~]# kubectl rollout undo deploy my-deploy --to-revision=4 -n dev
deployment.apps/my-deploy rolled back
#查看是否回滚成功
$ kubectl get rs -n dev
$ kubectl get pods -n dev
$ kubectl get deploy -owide -n dev
回滚的过程,也是先创建一个新的低版本的pod,然后杀掉已有的高版本的pod。
4.4 Deployment金丝雀发布(灰度发布)
灰度发布通过如下两个命令配合使用来完成:
kubectl rollout pause deploy =》 暂停正在进行的更新
kubectl rollout resume deploy =》唤醒被暂停的更新
(1)启动rollout pause部署更新
$ kubectl set image deploy my-deploy nginx=nginx:1.17.3 -n dev && kubectl rollout pause deploy my-deploy -n dev
(2)查看rs
$ kubectl get rs -n dev
发现老版本rs没有减少,新版本rs增加一个
(3)#查看更新过程
$ kubectl rollout status deploy my-deploy -n dev
$ kubectl get rs -n dev
[root@k8s-master1 ~]# kubectl get deploy -n dev -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy 5/4 2 5 42m nginx nginx:1.17.3 app=nginx-pod
# 唤醒被paused更新,继续进行更新
$ kubectl rollout resume deploy
[root@k8s-master1 ~]# kubectl get deploy -n dev -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy 4/4 4 4 45m nginx nginx:1.17.3 app=nginx-pod
发现老版本均停止,新版本已经创建好。
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122796352