深入了解Deployment
# 深入了解Deployment
Deployment典型用例
1.创建 Deployment 以将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
2.通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态 。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
3.如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
4.扩大 Deployment 规模以承担更多负载。
5.暂停 Deployment 以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
6.使用 Deployment 状态 来判定上线过程是否出现停滞。
7.清理较旧的不再需要的 ReplicaSet 。
主要字段
# Pod的升级和回滚
当Pod通过Department创建,我们可以在创建前修改yml去配置自己需要的参数(端口,卷,镜像)信息,并再次应用到deployment对象上,系统即可完成自动升级更新,或回滚
- 创建一个简单的deployment-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.yfklife.cn/nginx:1.17.2
ports:
- containerPort: 80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Deployment的升级
- 升级镜像(set)
kubectl set image deployment/nginx-deployment nginx=registry.yfklife.cn/nginx:1.20.2
[root@manage-10 deployment]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-55bbf954b8-4h6xd 1/1 Running 0 9m13s 10.240.1.94 hdss-21 <none> <none>
nginx-deployment-55bbf954b8-79ckm 1/1 Running 0 9m13s 10.240.1.95 hdss-21 <none> <none>
nginx-deployment-55bbf954b8-j8d22 1/1 Running 0 9m13s 10.240.2.91 hdss-22 <none> <none>
[root@manage-10 deployment]#
[root@manage-10 deployment]# curl -Is 10.240.1.94 |grep -i server
Server: nginx/1.17.2
[root@manage-10 deployment]# kubectl set image deployment/nginx-deployment nginx=registry.yfklife.cn/nginx:1.20.2
deployment.apps/nginx-deployment image updated
[root@manage-10 deployment]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-5f4865fd4b-54qq8 1/1 Running 0 22s 10.240.2.92 hdss-22 <none> <none>
nginx-deployment-5f4865fd4b-qqltr 1/1 Running 0 23s 10.240.1.96 hdss-21 <none> <none>
nginx-deployment-5f4865fd4b-wxnkj 1/1 Running 0 18s 10.240.1.97 hdss-21 <none> <none>
[root@manage-10 deployment]# curl -Is 10.240.1.96 |grep -i server
Server: nginx/1.20.2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 在线编辑修改(edit)
可以看到许多默认的参数
kubectl edit deployments.apps nginx-deployment
一旦镜像名(或Pod定义)发生了修改,则将触发系统变更,Deployment所有运行Pod的滚动升级操作,可以使用kubectl rollout status 命令查看Deployment的更新过程
实时查看升级过程:kubectl rollout status deployment nginx-deployment
查看更新记录:kubectl describe deployments.apps nginx-deployment
查看ReplicaSet: kubectl get rs
创建deployment 的时候ReplicaSet(nginx-deployment-5f4865fd4b),按照replicas设定的启动数目
当更新Deployment时,系统创建了一个新的ReplicaSet(nginx-deployment-5f4865fd4b),并将其副本数量扩展到1,然后将旧的ReplicaSet缩减为2。
之后,系统继续按照相同的更新策略对新旧两个ReplicaSet进行逐个调整。
最后,新的ReplicaSet运行了3个新版本Pod副本,旧的ReplicaSet副本数量则缩减为0
Deployment需要确保在整个更新过程中只有一定数量的Pod可能处于不可用状态。
在默认情况下,Deployment确保可用的Pod总数至少为所需的副本数量(DESIRED)减1,也就是最多1个不可用(maxUnavailable=1)。
Deployment还需要确保在整个更新过程中Pod的总数量不会超过所需的副本数量太多。在默认情况下,Deployment确保Pod的总数最多比所需的Pod数多1个,也就是最多1个浪涌值(maxSurge=25%)
# 更新策略strategy
- strategy
shell> kubectl explain Deployment.spec.strategy
在deployment中,可以通过spec.strategy 指定pod的更新策略,目前支持两种策略:Recreate(重建)和RollingUpdate(滚动更新),默认值为RollingUpdate。
Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新Pod时,会先杀掉所有正在运行的Pod,然后创建新的Pod。
RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更新Pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavailable和maxSurge)来控制滚动更新的过程。
shell> kubectl explain Deployment.spec.strategy.rollingUpdate
- strategy.rollingUpdate
默认值
revisionHistoryLimit: 10 #保留history 10条
minReadySeconds:30 #间隔30s
strategy:
rollingUpdate:
maxSurge: 25% #更新过程中总数不超过
maxUnavailable: 25% #不可用状态pod上限
type: RollingUpdate
2
3
4
5
6
7
maxUnavailable:
用于指定Deployment在更新过程中不可用状态的Pod数量的上限。
该maxUnavailable的数值可以是绝对值(例如5)或Pod期望的副本数的百分比(例如10%),如果被设置为百分比,那么系统会先以向下取整的方式计算出绝对值(整数)。
maxSurge:
用于指定在Deployment更新Pod的过程中Pod总数超过Pod期望副本数部分的最大值。
该maxSurge的数值可以是绝对值(例如5)或Pod期望副本数的百分比(例如10%)。如果设置为百分比,那么系统会先按照向上取整的方式计算出绝对数值(整数)。
# Label Selector
不建议更新Deployment的标签选择器,因为这样会导致Deployment选择的Pod列表发生变化,也可能与其他控制器产生冲突。
添加选择器标签时,必须同步修改Deployment配置的Pod的标签,为Pod添加新的标签,否则Deployment的更新会报验证错误而失败
添加标签选择器是无法向后兼容的,这意味着新的标签选择器不会匹配和使用旧选择器创建的ReplicaSets和Pod,因此添加选择器将会导致所有旧版本的ReplicaSets和由旧ReplicaSets创建的Pod处于孤立状态(不会被系统自动删除,也不受新的ReplicaSet控制)。
更新标签选择器,即更改选择器中标签的键或者值,也会产生与添加选择器标签类似的效果删除标签选择器,即从Deployment的标签选择器中删除一个或者多个标签,该Deployment的ReplicaSet和Pod不会受到任何影响。
但需要注意的是,被删除的标签仍会存在于现有的Pod和ReplicaSets上。
# Deployment的回滚
实时查看升级过程:kubectl rollout status deployment nginx-deployment
在创建Deployment时使用--record参数,就可以在CHANGECAUSE列看到每个版本使用的命令了,不加显示为“<none>”
Deployment的更新操作是在Deployment进行部署(Rollout)时被触发的,这意味着当且仅当Deployment的Pod模板(即spec.template)被更改时才会创建新的修订版本,
例如更新模板标签或容器镜像。其他更新操作(如扩展副本数)将不会触发Deployment的更新操作,这也意味着我们将Deployment回滚到之前的版本时,只有Deployment的Pod模板部分会被修改
revisionHistoryLimit:改参数与--record配合使用,即history查看记录的时候保留多少条记录,默认10条
minReadySeconds:如果是nginx服务,起来也就2,3秒,但如果是java服务起来可能需要1-2分钟,这个时候,如果没有该参数,服务还没完全起来就起另一个,会出现业务无法访问,就需要通过设置间隔时间来避免
- 记录变更信息
#创建dp加入--record
kubectl apply -f nginx-dp.yaml --record=true
#或者创建后set
kubectl set image deployment/nginx-deployment nginx=registry.yfklife.cn/nginx:1.20.2 --record
2
3
4
- 查看变更记录
kubectl rollout history deployment nginx-deployment
- 查看特定版本详细信息
kubectl rollout history deployment nginx-deployment --revision=2
- 回退到版本
回退到上一个版本
kubectl rollout undo deployment nginx-deployment
回退到指定版本,例如第一个
kubectl rollout undo deployment nginx-deployment --to-revision=1
查看操作信息
kubectl describe deployments.apps nginx-deployment
# Deployment的暂停和恢复
例如我们需要做多次修改,(修改镜像,限制资源,修改端口等等),如果在不暂停的情况下,修改一次,就会重新创建一次,这个时候我们就可以通过暂停更新操作,修改完再一次性更替
- 暂停更新
kubectl rollout pause deployment nginx-deployment
- 进行多次修改
kubectl set image deployment/nginx-deployment nginx=registry.yfklife.cn/nginx:1.20.2
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
2
- 恢复更新
kubectl rollout resume deployment nginx-deployment
- 查看信息
kubectl rollout history deployment nginx-deployment
kubectl get rs
kubectl describe rs nginx-deployment-7c48b6f986
2
3
# RC的滚动升级(rolling-update)
kubectl rolling-update 在1.11版开始过时的
该命令创建了一个新的RC,然后自动控制旧的RC中的Pod副本数量逐渐减少到0,同时新的RC中的Pod副本数量从0逐步增加到目标值,来完成Pod的升级。
需要注意的是,
1.系统要求新的RC与旧的RC都在相同的命名空间内
2.RC的名字(name)不能与旧RC的名字相同
3.在selector中应至少有一个Label与旧RC的Label不同,以标识其为新RC
# DaemonSet更新策略
explain查看:kubectl explain DaemonSet.spec.updateStrategy
Daemonset的升级策略有两种:"RollingUpdate" or "OnDelete",
OnDelete:
DaemonSet的默认升级策略,与1.5及以前版本的Kubernetes保持一致。
当使用OnDelete作为升级策略时,在创建好新的DaemonSet配置之后,新的Pod并不会被自动创建,直到用户手动删除旧版本的Pod,才触发新建操作。
RoolingUpdate:
从Kubernetes 1.6版本开始引入。当使用RollingUpdate作为升级策略对DaemonSet进行更新时,旧版本的Pod将被自动杀掉,然后自动创建新版本的DaemonSet Pod。
整个过程与普通Deployment的滚动升级一样是可控的。
不过有两点不同于普通Pod的滚动升级:
1.目前Kubernetes还不支持查看和管理DaemonSet的更新历史记录;
2.是DaemonSet的回滚(Rollback)并不能如同Deployment一样直接通过kubectl rollback命令来实现,必须通过再次提交旧版本配置的方式实现。
# StatefulSet更新策略
RollingUpdate 更新策略是 StatefulSet 默认策略。
OnDelete 更新策略实现了传统(1.7 之前)行为,它也是默认的更新策略。 当你选择这个更新策略并修改 StatefulSet 的 .spec.template 字段时,StatefulSet 控制器将不会自动更新 Pod
# Pod的扩缩容
资源的扩容缩容是我们常做的一件事,资源多使用率低成本就高,就需要收缩,资源少使用率超负荷,就需要扩容防止业务异常
Kubernetes对Pod的扩缩容操作提供了手动和自动两种模式,手动模式通过执行kubectl scale命令或通过apply I对一个Deployment/RC进行Pod副本数量的设置,即可一键完成。
自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整
# 手动扩缩容
方式一: 通过kubectl scale命令可以将已经创建的deployment更新pod数,通过replicas指定,
kubectl scale deployment nginx-deployment --replicas=5
如果是缩容,将按时间最新的pod来删除(比如从3个扩容到5个,再从5个收缩到3个,这个时候删除的pod就是刚刚创建的那最年轻的两个),当replicas=0 ,删除该dp下所有的pod,
方式二: 通过修改yml,重新apply文件去配置
kubectl apply -f nginx-dp.yml
# 自动扩缩容(HPA)
Kubernetes从1.1版本开始,新增了名为Horizontal Pod Autoscaler(HPA)的控制器,用于实现基于CPU使用率进行自动Pod扩缩容的功能。
HPA控制器基于Master的kube-controller-manager服务启动参数--horizontal-pod-autoscaler-sync-period定义的探测周期(默认值为15s),周期性地监测目标Pod的资源性能指标,并与HPA资源对象中的扩缩容条件进行对比,在满足条件时对Pod副本数量进行调整
# k8s之meric-server(HPA环境)
# 创建一个HorizontalPodAutoscaler
HorizontalPodAutoscaler资源对象处于Kubernetes的API组“autoscaling”中,目前包括v1和v2两个版本。
autoscaling/v1仅支持基于CPU使用率的自动扩缩容,
autoscaling/v2则用于支持基于任意指标的自动扩缩容配置,包括基于资源使用率、Pod指标、其他指标等类型的指标数据,当前版本为autoscaling/v2beta2
这里的例子还是使用上面的nginx-deployment,前提预先安装Heapster组件或Metrics Server
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=10
默认配置:vi hpa-nginx-dp.yml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: nginx-deployment
namespace: default
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
targetCPUUtilizationPercentage: 50
status:
currentCPUUtilizationPercentage: 0
currentReplicas: 1
desiredReplicas: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
- 参数说明
参数 | 说明 |
---|---|
scaleTargetRef | 目标作用对象,可以是Deployment、ReplicationController或ReplicaSet |
targetCPUUtilizationPercentage | 期望每个Pod的CPU使用率都为50%,该使用率基于Pod设置的CPU Request值进行计算 |
minReplicas和maxReplicas | Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的CPU使用率为50% |
- 压力测试
yum -y install httpd-tools
kubectl get svc |grep nginx
ab -n 1000000 -c 100 http://10.2.115.239/index.html # 压测svcIP
#查看变化
kubectl get hpa nginx-deployment --watch
2
3
4
5
6
# 基于多项度量指标和自定义度量指标自动扩缩
需要注意的是,targetCPUUtilizationPercentage 字段已经被名为 metrics 的数组所取代。
CPU 利用率这个度量指标是一个 resource metric(资源度量指标),因为它表示容器上指定资源的百分比。
除 CPU 外,你还可以指定其他资源度量指标。默认情况下,目前唯一支持的其他资源度量指标为内存。
只要 metrics.k8s.io API 存在,这些资源度量指标就是可用的,并且他们不会在不同的 Kubernetes 集群中改变名称。
你还可以指定资源度量指标使用绝对数值,而不是百分比,你需要将 target.type 从 Utilization 替换成 AverageValue,同时设置 target.averageValue 而非 target.averageUtilization 的值。
- metrics 度量指标类型
如果你指定了多个上述类型的度量指标,HorizontalPodAutoscaler 将会依次考量各个指标。
HorizontalPodAutoscaler 将会计算每一个指标所提议的副本数量,然后最终选择一个最高值。
1.Resource:基于资源的指标值,可以设置的资源为CPU和内存。
2.Pods:基于Pod的指标,系统将对全部Pod副本的指标值进行平均值计算。
3.Object:基于某种资源对象(如Ingress)的指标或应用系统的任意自定义指标。
查看内存描述
kubectl explain --api-version=autoscaling/v2beta2 horizontalpodautoscaler.spec.metrics.resource.target.averageValue
查看cpu描述
kubectl explain --api-version=autoscaling/v2beta2 horizontalpodautoscaler.spec.metrics.resource.target.averageUtilization
- 创建一个v2的hpa
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-deployment
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
metrics:
- type: Resource
resource:
name: cpu
target:
averageUtilization: 50
type: Utilization
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 50Mi
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 2k
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
学习借鉴:kubernetes官方文档 (opens new window)和Kubernetes权威指南第4版.pdf