热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

k8s06_Pod控制器

Pod控制器介绍Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类:自主式pod:kubernetes直接创建出来的Pod,

Pod控制器介绍

Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类:



  • 自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建

  • 控制器创建的pod:kubernetes通过控制器创建的pod,这种pod删除了之后还会自动重建

什么是Pod控制器

Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。

在kubernetes中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有下面这些:



  • ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代

  • ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级

  • Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本

  • Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷

  • DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务

  • Job:它创建出来的pod只要完成任务就立即退出,不需要重启或重建,用于执行一次性任务

  • Cronjob:它创建的Pod负责周期性任务控制,不需要持续后台运行

  • StatefulSet:管理有状态应用


ReplicaSet(RS)

ReplicaSet的主要作用是保证一定数量的pod正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对pod数量的扩缩容和镜像版本的升降级。

ReplicaSet的资源清单文件:

apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: rs
spec: # 详情描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {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

在这里面,需要新了解的配置项就是spec下面几个选项:



  • replicas:指定副本数量,其实就是当前rs创建出来的pod的数量,默认为1



  • selector:选择器,它的作用是建立pod控制器和pod之间的关联关系,采用的Label Selector机制

    在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了



  • template:模板,就是当前控制器创建pod所使用的模板板,里面其实就是前一章学过的pod的定义




创建ReplicaSet

创建pc-replicaset.yaml文件,内容如下:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: pc-replicaset
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

[root@master ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 查看rs
# DESIRED:期望副本数量
# CURRENT:当前副本数量
# READY:已经准备好提供服务的副本数量
[root@master ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3 3 3 82s nginx nginx:1.17.1 app=nginx-pod
# 查看当前控制器创建出来的pod
# 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-69qs4 1/1 Running 0 2m3s
pc-replicaset-mvkp8 1/1 Running 0 2m3s
pc-replicaset-wrtf7 1/1 Running 0 2m3s

扩缩容

# 编辑rs的副本数量,修改spec:replicas: 6即可
[root@master ~]# kubectl edit rs pc-replicaset -n dev
# 查看pod
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-646bd 1/1 Running 0 3m27s
pc-replicaset-69qs4 1/1 Running 0 8m37s
pc-replicaset-6frmp 1/1 Running 0 3m27s
pc-replicaset-bxfss 1/1 Running 0 3m27s
pc-replicaset-mvkp8 1/1 Running 0 8m37s
pc-replicaset-wrtf7 1/1 Running 0 8m37s
# 当然也可以直接使用命令实现
# 使用scale命令实现扩缩容, 后面--replicas=n直接指定目标数量即可
[root@master ~]# kubectl scale rs pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
# 命令运行完毕,立即查看,发现已经有4个开始准备退出了
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-646bd 0/1 Terminating 0 6m31s
pc-replicaset-69qs4 1/1 Running 0 11m
pc-replicaset-6frmp 0/1 Terminating 0 6m31s
pc-replicaset-bxfss 0/1 Terminating 0 6m31s
pc-replicaset-mvkp8 1/1 Running 0 11m
pc-replicaset-wrtf7 0/1 Terminating 0 11m
#稍等片刻,就只剩下2个了
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-69qs4 1/1 Running 0 12m
pc-replicaset-mvkp8 1/1 Running 0 12m

可以看到这个这个在线编辑是在tmp目录下创建的一个临时文件


镜像升级

# 编辑rs的容器镜像 - image: nginx:1.17.2
[root@master ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 再次查看,发现镜像版本已经变更了
[root@master ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 2 2 2 14m nginx nginx:1.17.2 app=nginx-pod
# 同样的道理,也可以使用命令完成这个工作
# kubectl set image rs rs名称 容器=镜像版本 -n namespace
[root@master ~]# kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev
replicaset.apps/pc-replicaset image updated
# 再次查看,发现镜像版本已经变更了
[root@master ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 2 2 2 17m nginx nginx:1.17.1 app=nginx-pod

删除ReplicaSet

# 使用kubectl delete命令会删除此RS以及它管理的Pod
# 在kubernetes删除RS前,会将RS的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象的删除
[root@master ~]# kubectl delete rs pc-replicaset -n dev
replicaset.apps "pc-replicaset" deleted
[root@master ~]# kubectl get pod -n dev -o wide
No resources found in dev namespace.
# 如果希望仅仅删除RS对象(保留Pod),可以使用kubectl delete命令时添加--cascade=false选项(不推荐)。
# 先创建一份
[root@master ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 带参数删除
[root@master ~]# kubectl delete rs pc-replicaset -n dev --cascade=false
replicaset.apps "pc-replicaset" deleted
# 查看pod
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-ndqhv 1/1 Running 0 44s
pc-replicaset-ntp54 1/1 Running 0 44s
pc-replicaset-t9kxs 1/1 Running 0 44s

Deployment(Deploy)

为了更好的解决服务编排的问题,kubernetes在V1.2版本开始,引入了Deployment控制器。值得一提的是,这种控制器并不直接管理pod,而是通过管理ReplicaSet来简介管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。

Deployment主要功能有下面几个:



  • 支持ReplicaSet的所有功能

  • 支持发布的停止、继续

  • 支持滚动升级和回滚版本

Deployment的资源清单文件:

apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: deploy
spec: # 详情描述
replicas: 3 # 副本数量
revisionHistoryLimit: 3 # 保留历史版本
paused: false # 暂停部署,默认是false
progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600
strategy: # 策略
type: RollingUpdate # 滚动更新策略
rollingUpdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {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

创建deployment

创建pc-deployment.yaml,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
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

# 创建deployment
[[root@master ~]# kubectl create -f pc-deployment.yaml --record=true
deployment.apps/pc-deployment created
# 查看deployment
# UP-TO-DATE 最新版本的pod的数量
# AVAILABLE 当前可用的pod的数量
[root@master ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 3/3 3 3 19s
# 查看rs
# 发现rs的名称是在原来deployment的名字后面添加了一个10位数的随机串
[root@master ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-5d89bdfbf9 3 3 3 77s
# 查看pod
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-9tkgq 1/1 Running 0 2m15s
pc-deployment-5d89bdfbf9-gjq7r 1/1 Running 0 2m15s
pc-deployment-5d89bdfbf9-lvfff 1/1 Running 0 2m15s

扩缩容

# 变更副本数量为5个
[root@master ~]# kubectl scale deploy pc-deployment --replicas=5 -n dev
deployment.apps/pc-deployment scaled
# 查看deployment
[root@master ~]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 7m42s
# 查看pod
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-9tkgq 1/1 Running 0 8m40s
pc-deployment-5d89bdfbf9-gjq7r 1/1 Running 0 8m40s
pc-deployment-5d89bdfbf9-lvfff 1/1 Running 0 8m40s
pc-deployment-5d89bdfbf9-msmvw 1/1 Running 0 77s
pc-deployment-5d89bdfbf9-zkr5g 1/1 Running 0 77s
# 编辑deployment的副本数量,修改spec:replicas: 4即可
[root@master ~]# kubectl edit deploy pc-deployment -n dev
deployment.apps/pc-deployment edited
# 查看pod
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-9tkgq 1/1 Running 0 36m
pc-deployment-5d89bdfbf9-gjq7r 1/1 Running 0 36m
pc-deployment-5d89bdfbf9-lvfff 1/1 Running 0 36m
pc-deployment-5d89bdfbf9-zkr5g 1/1 Running 0 28m

镜像更新

deployment支持两种更新策略:重建更新滚动更新,可以通过strategy指定策略类型,支持两个属性:

strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性:
type:指定策略类型,支持两种策略
Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod
RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。

重建更新



  1. 编辑pc-deployment.yaml,在spec节点下添加更新策略

spec:
strategy: # 策略
type: Recreate # 重建更新


  1. 创建deploy进行验证

开两个窗口,一个窗口执行 kubectl get pods -n dev -w 观察更新现象,另一个窗口执行更新命令,当发生更新操作时,观察窗口可以同步看到变化。

窗口一,变更镜像

[root@master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated

窗口二,观察升级过程,注意看时间

[root@master ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-9tkgq 1/1 Running 0 44m
pc-deployment-5d89bdfbf9-gjq7r 1/1 Running 0 44m
pc-deployment-5d89bdfbf9-lvfff 1/1 Running 0 44m
pc-deployment-5d89bdfbf9-zkr5g 1/1 Running 0 36m
pc-deployment-675d469f8b-frfrn 0/1 Pending 0 0s
pc-deployment-675d469f8b-frfrn 0/1 Pending 0 0s
pc-deployment-5d89bdfbf9-zkr5g 1/1 Terminating 0 37m
pc-deployment-675d469f8b-frfrn 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-vq6pc 0/1 Pending 0 0s
pc-deployment-675d469f8b-vq6pc 0/1 Pending 0 0s
pc-deployment-675d469f8b-vq6pc 0/1 ContainerCreating 0 0s
pc-deployment-5d89bdfbf9-zkr5g 0/1 Terminating 0 37m
pc-deployment-675d469f8b-frfrn 1/1 Running 0 2s
pc-deployment-5d89bdfbf9-zkr5g 0/1 Terminating 0 37m
pc-deployment-675d469f8b-vq6pc 1/1 Running 0 2s
pc-deployment-5d89bdfbf9-9tkgq 1/1 Terminating 0 45m
pc-deployment-675d469f8b-vsv5g 0/1 Pending 0 0s
pc-deployment-675d469f8b-vsv5g 0/1 Pending 0 0s
pc-deployment-675d469f8b-vsv5g 0/1 ContainerCreating 0 0s
pc-deployment-5d89bdfbf9-gjq7r 1/1 Terminating 0 45m
pc-deployment-675d469f8b-chsdk 0/1 Pending 0 0s
pc-deployment-675d469f8b-chsdk 0/1 Pending 0 0s
pc-deployment-675d469f8b-chsdk 0/1 ContainerCreating 0 0s
pc-deployment-5d89bdfbf9-9tkgq 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-gjq7r 0/1 Terminating 0 45m
pc-deployment-675d469f8b-vsv5g 1/1 Running 0 2s
pc-deployment-5d89bdfbf9-lvfff 1/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-9tkgq 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-9tkgq 0/1 Terminating 0 45m
pc-deployment-675d469f8b-chsdk 1/1 Running 0 3s
pc-deployment-5d89bdfbf9-lvfff 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-lvfff 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-lvfff 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-lvfff 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-zkr5g 0/1 Terminating 0 37m
pc-deployment-5d89bdfbf9-zkr5g 0/1 Terminating 0 37m
pc-deployment-5d89bdfbf9-gjq7r 0/1 Terminating 0 45m
pc-deployment-5d89bdfbf9-gjq7r 0/1 Terminating 0 45m

滚动更新



  1. 编辑pc-deployment.yaml,在spec节点下添加更新策略

spec:
strategy: # 策略
type: RollingUpdate # 滚动更新策略
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%


  1. 创建deploy进行验证

窗口1,变更镜像

[root@master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev
deployment.apps/pc-deployment image updated

窗口二,观察升级过程,注意看时间

[root@master ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-675d469f8b-chsdk 1/1 Running 0 4m3s
pc-deployment-675d469f8b-frfrn 1/1 Running 0 4m5s
pc-deployment-675d469f8b-vq6pc 1/1 Running 0 4m5s
pc-deployment-675d469f8b-vsv5g 1/1 Running 0 4m3s
pc-deployment-7865c58bdf-nb57p 0/1 Pending 0 0s
pc-deployment-7865c58bdf-nb57p 0/1 Pending 0 0s
pc-deployment-675d469f8b-chsdk 1/1 Terminating 0 4m20s
pc-deployment-7865c58bdf-nb57p 0/1 ContainerCreating 0 0s
pc-deployment-7865c58bdf-vf7nq 0/1 Pending 0 0s
pc-deployment-7865c58bdf-vf7nq 0/1 Pending 0 0s
pc-deployment-7865c58bdf-vf7nq 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-chsdk 0/1 Terminating 0 4m21s
pc-deployment-675d469f8b-chsdk 0/1 Terminating 0 4m28s
pc-deployment-675d469f8b-chsdk 0/1 Terminating 0 4m28s
pc-deployment-7865c58bdf-nb57p 1/1 Running 0 38s
pc-deployment-675d469f8b-vsv5g 1/1 Terminating 0 4m58s
pc-deployment-7865c58bdf-xrbzw 0/1 Pending 0 0s
pc-deployment-7865c58bdf-xrbzw 0/1 Pending 0 0s
pc-deployment-7865c58bdf-xrbzw 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-vsv5g 0/1 Terminating 0 4m59s
pc-deployment-675d469f8b-vsv5g 0/1 Terminating 0 5m
pc-deployment-675d469f8b-vsv5g 0/1 Terminating 0 5m
pc-deployment-675d469f8b-vsv5g 0/1 Terminating 0 5m
pc-deployment-7865c58bdf-xrbzw 1/1 Running 0 2s
pc-deployment-675d469f8b-vq6pc 1/1 Terminating 0 5m2s
pc-deployment-7865c58bdf-864fd 0/1 Pending 0 0s
pc-deployment-7865c58bdf-864fd 0/1 Pending 0 1s
pc-deployment-7865c58bdf-864fd 0/1 ContainerCreating 0 1s
pc-deployment-675d469f8b-vq6pc 0/1 Terminating 0 5m3s
pc-deployment-7865c58bdf-864fd 1/1 Running 0 1s
pc-deployment-675d469f8b-frfrn 1/1 Terminating 0 5m4s
pc-deployment-675d469f8b-vq6pc 0/1 Terminating 0 5m5s
pc-deployment-675d469f8b-vq6pc 0/1 Terminating 0 5m5s
pc-deployment-675d469f8b-frfrn 0/1 Terminating 0 5m5s
pc-deployment-675d469f8b-frfrn 0/1 Terminating 0 5m10s
pc-deployment-675d469f8b-frfrn 0/1 Terminating 0 5m10s
pc-deployment-7865c58bdf-vf7nq 1/1 Running 0 61s

至此,新版本的pod创建完毕,就版本的pod销毁完毕,中间过程是滚动进行的,也就是边销毁边创建.

滚动更新的过程:

镜像中的rs变化

# 查看rs,发现原来的rs的依旧存在,只是pod数量变为了0,而后又新产生了一个rs,pod数量为4
# 其实这就是deployment能够进行版本回退的奥妙所在,后面会详细解释
[root@master ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-5d89bdfbf9 0 0 0 54m
pc-deployment-675d469f8b 0 0 0 9m40s
pc-deployment-7865c58bdf 4 4 4 5m18s

版本回退

deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,下面具体来看.

kubectl rollout: 版本升级相关功能,支持下面的选项:



  • status 显示当前升级状态

  • history 显示 升级历史记录

  • pause 暂停版本升级过程

  • resume 继续已经暂停的版本升级过程

  • restart 重启版本升级过程

  • undo 回滚到上一级版本(可以使用--to-revision回滚到指定版本)

# 查看当前升级版本的状态
[root@master ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out
# 查看升级历史记录
[root@master ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=pc-deployment.yaml --record=true
2 kubectl create --filename=pc-deployment.yaml --record=true
3 kubectl create --filename=pc-deployment.yaml --record=true
# 可以发现有三次版本记录,说明完成过两次升级
# 版本回滚
# 这里直接使用--to-revision=1回滚到了1版本, 如果省略这个选项,就是回退到上个版本,就是2版本
[root@master ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back
# 查看发现,通过nginx镜像版本可以发现到了第一版
[root@master ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
pc-deployment 4/4 4 4 60m nginx nginx:1.17.1 app=nginx-pod
# 查看rs,发现第一个rs中有4个pod运行,后面两个版本的rs中pod为运行
# 其实deployment之所以可是实现版本的回滚,就是通过记录下历史rs来实现的,
# 一旦想回滚到哪个版本,只需要将当前版本pod数量降为0,然后将回滚版本的pod提升为目标数量就可以了
[root@master ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-5d89bdfbf9 4 4 4 60m
pc-deployment-675d469f8b 0 0 0 15m
pc-deployment-7865c58bdf 0 0 0 11m

金丝雀发布

Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。

比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。

# 更新deployment的版本,并配置暂停deployment
[root@master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused
#观察更新状态
[root@master ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 4 new replicas have been updated...
# 监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令
[root@master ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-deployment-5d89bdfbf9 3 3 3 82m nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d89bdfbf9
pc-deployment-675d469f8b 0 0 0 37m nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=675d469f8b
pc-deployment-6c9f56fcfb 2 2 2 2m15s nginx nginx:1.17.4 app=nginx-pod,pod-template-hash=6c9f56fcfb
pc-deployment-7865c58bdf 0 0 0 32m nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=7865c58bdf
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-6qqh4 1/1 Running 0 23m
pc-deployment-5d89bdfbf9-qx4z7 1/1 Running 0 23m
pc-deployment-5d89bdfbf9-sml4b 1/1 Running 0 23m
pc-deployment-6c9f56fcfb-c5h2m 1/1 Running 0 3m51s
pc-deployment-6c9f56fcfb-pg6pg 1/1 Running 0 3m51s
# 确保更新的pod没问题了,继续更新
[root@master ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
# 查看最后的更新情况
[root@master ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-deployment-5d89bdfbf9 0 0 0 86m nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=5d89bdfbf9
pc-deployment-675d469f8b 0 0 0 41m nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=675d469f8b
pc-deployment-6c9f56fcfb 4 4 4 6m21s nginx nginx:1.17.4 app=nginx-pod,pod-template-hash=6c9f56fcfb
pc-deployment-7865c58bdf 0 0 0 36m nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=7865c58bdf
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6c9f56fcfb-bbw9r 1/1 Running 0 22s
pc-deployment-6c9f56fcfb-c5h2m 1/1 Running 0 6m31s
pc-deployment-6c9f56fcfb-nk2xw 1/1 Running 0 22s
pc-deployment-6c9f56fcfb-pg6pg 1/1 Running 0 6m31s

删除Deployment

# 删除deployment,其下的rs和pod也将被删除
[root@master ~]# kubectl delete -f pc-deployment.yaml
deployment.apps "pc-deployment" deleted

Horizontal Pod Autoscaler(HPA)

在前面的课程中,我们已经可以实现通过手工执行kubectl scale命令实现Pod扩容或缩容,但是这显然不符合Kubernetes的定位目标--自动化、智能化。 Kubernetes期望可以实现通过监测Pod的使用情况,实现pod数量的自动调整,于是就产生了Horizontal Pod Autoscaler(HPA)这种控制器。

HPA可以获取每个Pod利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。其实HPA与之前的Deployment一样,也属于一种Kubernetes资源对象,它通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。

接下来,我们来做一个实验


安装metrics-server

metrics-server可以用来收集集群中的资源使用情况

# 安装git
[root@master ~]# yum install git -y
# 获取metrics-server, 注意使用的版本
[root@master ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
# 修改deployment, 注意修改的是镜像和初始化参数
[root@master ~]# cd /root/metrics-server/deploy/1.8+/
[root@master 1.8+]# vim metrics-server-deployment.yaml
按图中添加下面选项
hostNetwork: true
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP

# 安装metrics-server
[root@master 1.8+]# kubectl apply -f ./
# 查看pod运行情况
[root@master 1.8+]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
......
metrics-server-6b976979db-v78rl 1/1 Running 0 47s
......
# 使用kubectl top node 查看资源使用情况
[root@master 1.8+]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 238m 11% 1072Mi 62%
node1 26m 1% 301Mi 17%
node2 28m 1% 384Mi 22%
[root@master 1.8+]# kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-9d85f5447-tjdlq 4m 17Mi
coredns-9d85f5447-vqzzv 4m 17Mi
etcd-master 18m 81Mi
......
# 至此,metrics-server安装完成

准备deployment和servie

在root目录下创建pc-hpa-pod.yaml文件,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
strategy: # 策略
type: RollingUpdate # 滚动更新策略
replicas: 1
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
resources: # 资源配额
limits: # 限制资源(上限)
cpu: "1" # CPU限制,单位是core数
requests: # 请求资源(下限)
cpu: "100m" # CPU限制,单位是core数

# 创建deployment
[root@master ~]# kubectl create -f pc-hpa-pod.yaml
deployment.apps/nginx created
# 创建service
[root@master ~]# kubectl expose deployment nginx --type=NodePort --port=80 -n dev
service/nginx exposed
# 查看
[root@master ~]# kubectl get deployment,pod,svc -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 106s
NAME READY STATUS RESTARTS AGE
pod/nginx-778cb5fb7b-7s428 1/1 Running 0 106s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx NodePort 10.99.99.131 80:30925/TCP 87s

部署HPA

创建pc-hpa.yaml文件,内容如下:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: pc-hpa
namespace: dev
spec:
minReplicas: 1 #最小pod数量
maxReplicas: 10 #最大pod数量
targetCPUUtilizationPercentage: 3 # CPU使用率指标,这个设定为这么小是为了方便测试
scaleTargetRef: # 指定要控制的nginx信息
apiVersion: apps/v1
kind: Deployment
name: nginx

注意:我在这里遇到一个大坑,当时hpa控制器部署文件中指定要操作的deployment时,我的版本号忘写apps,这个与前面我们创建的deployment控制器的版本不一致。执行下面的命令,后出现了unknown。

[root@master ~]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx /3% 1 10 0 15s

一开始收集信息可能会出现unknown,但是过了几分钟还是unknown状态,那就是有问题,于是我执行下面的命令进行查找

[root@master ~]# kubectl describe hpa pc-hpa -n dev
Name: pc-hpa
Namespace: dev
Labels:
Annotations:
CreationTimestamp: Sat, 12 Feb 2022 10:42:37 +0800
Reference: Deployment/nginx
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): / 3%
Min replicas: 1
Max replicas: 10
Deployment pods: 0 current / 0 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale False FailedGetScale the HPA controller was unable to get the target's current scale: no matches for kind "Deployment" in group ""
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetScale 1s horizontal-pod-autoscaler no matches for kind "Deployment" in group ""

这句话的意思时未能匹配到deployment控制器。此刻要么是hpa的配置文件的监控deployment部分写错了,要么是deployment文件写错了,他们的描述肯定是不一致的,我这里经过仔细排查发现是,hpa的配置文件写错了,这里少写了一个apps。

# 创建hpa
[root@master ~]# kubectl create -f pc-hpa.yaml
horizontalpodautoscaler.autoscaling/pc-hpa created
# 查看hpa
[root@master ~]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 27s

测试

使用压测工具对service地址192.168.5.4:31830进行压测,一共访问nginx1000次,然后通过控制台查看hpa和pod的变化,在这里我是用的postman,postman具体使用请自行百度。

这里开设两个窗口,一个监控hpa的变化,一个监控deployment的变化

hpa窗口:

[root@master ~]# kubectl get hpa -n dev -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 14m
pc-hpa Deployment/nginx 21%/3% 1 10 1 16m
pc-hpa Deployment/nginx 21%/3% 1 10 4 16m
pc-hpa Deployment/nginx 21%/3% 1 10 7 16m
pc-hpa Deployment/nginx 1%/3% 1 10 7 17m
pc-hpa Deployment/nginx 0%/3% 1 10 7 18m

注意cpu占用率从0到21又到了0,说明了请求从开始到结束

deploy窗口

[root@master ~]# kubectl get deploy -n dev -w
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 25m
nginx 1/4 1 1 26m
nginx 1/4 1 1 26m
nginx 1/4 1 1 26m
nginx 1/4 4 1 26m
nginx 2/4 4 2 26m
nginx 3/4 4 3 26m
nginx 4/4 4 4 26m
nginx 4/7 4 4 26m
nginx 4/7 4 4 26m
nginx 4/7 4 4 26m
nginx 4/7 7 4 26m
nginx 5/7 7 5 26m
nginx 6/7 7 6 26m
nginx 7/7 7 7 26m
nginx 7/1 7 7 32m
nginx 7/1 7 7 32m
nginx 1/1 1 1 32m

deploy窗口也说明了pod的数量一下猛增到了7,而后又回到了1,因为本身就至少有一台在工作。不过deploy窗口的数据变为1更慢一点,因为pod的创建销毁都需要时间,不能请求一结束pod的就立马销毁,会再等等,看看是否还有请求到达。

同时我们分别在压测前,压测中,压测后对dev这个名称空间下的pod进行查询,得到如下结果

# 压测前
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-547dd76d58-rq7rw 1/1 Running 0 28m
# 压测中
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-547dd76d58-b666m 1/1 Running 0 5m15s
nginx-547dd76d58-c95kg 1/1 Running 0 4m59s
nginx-547dd76d58-jfrxd 1/1 Running 0 5m15s
nginx-547dd76d58-qk74g 1/1 Running 0 4m59s
nginx-547dd76d58-rq7rw 1/1 Running 0 31m
nginx-547dd76d58-tbqxj 1/1 Running 0 5m15s
nginx-547dd76d58-z5nhm 1/1 Running 0 4m59s
# 压测后
[root@master ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-547dd76d58-rq7rw 1/1 Running 0 35m
# 注意压测后的查询必须等到deploy窗口的READY列数据重回为1才能看到效果,因为此时新创建的pod已经销毁了。

DaemonSet(DS)

DaemonSet类型的控制器可以保证在集群中的每一台(或指定)节点上都运行一个副本。一般适用于日志收集、节点监控等场景。也就是说,如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建。

DaemonSet控制器的特点:



  • 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上

  • 当节点从集群中移除时,Pod 也就被垃圾回收了

下面先来看下DaemonSet的资源清单文件

apiVersion: apps/v1 # 版本号
kind: DaemonSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: daemonset
spec: # 详情描述
revisionHistoryLimit: 3 # 保留历史版本
updateStrategy: # 更新策略
type: RollingUpdate # 滚动更新策略
rollingUpdate: # 滚动更新
maxUnavailable: 1 # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
selector: # 选择器,通过它指定该控制器管理哪些pod
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {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

创建pc-daemonset.yaml,内容如下:




推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文介绍了PHP常量的定义和使用方法,包括常量的命名规则、大小写敏感性、全局范围和标量数据的限制。同时还提到了应尽量避免定义resource常量,并给出了使用define()函数定义常量的示例。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
author-avatar
剧情归一_905
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有