1 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:管理有状态应用
2 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: 802.1 增删查
# 创建 rs
[ root@k8s-master01 ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
# 查看 rs
[ root@k8s-master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3 3 3 22s nginx nginx:1.17.1 app=nginx-pod
# 查看当前控制器创建出来的 pod (名称是在控制器名称后面拼接了-xxxxx 随机码)
[ root@k8s-master01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-6vmvt 1/1 Running 0 54s
pc-replicaset-fmb8f 1/1 Running 0 54s
pc-replicaset-snrk2 1/1 Running 0 54s
# 使用 kubectl delete 命令会删除此 RS 以及它管理的 Pod
# 在 kubernetes 删除 RS 前,会将 RS 的 replicasclear 调整为 0,等待所有的 Pod 被删除后,在执行 RS 对象的删除
kubectl delete rs pc-replicaset -n dev
# 如果希望仅仅删除 RS 对象(保留 Pod),可以使用 kubectl delete 命令时添加--cascade=false 选项(不推荐)。
kubectl delete rs pc-replicaset -n dev --cascade=false
# 也可以使用 yaml 直接删除(推荐)
kubectl delete -f pc-replicaset.yaml2.2 扩缩容
# 编辑配置文件进行扩缩容,修改 spec:replicas: 6 即可
kubectl edit rs pc-replicaset -n dev
# 使用 scale 命令实现扩缩容
kubectl scale rs pc-replicaset --replicas=2 -n dev
# 立刻查看 Pod 状态,发现已有 Pod 开始 Terminating
kubectl get pods -n dev2.3 镜像升级
# 编辑配置文件进行镜像升级, - image: nginx:1.17.2
kubectl edit rs pc-replicaset -n dev
# 同样的道理,也可以使用命令完成这个工作
kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev3 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: # 滚动更新
违规词汇: 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创建 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# 命令格式: kubectl create deployment 名称 [参数]
# --image 指定 pod 的镜像
# --port 指定端口
# --replicas 指定创建 pod 数量
# --namespace 指定 namespace
kubectl run nginx --image=nginx:latest --port=80 --replicas=3 -n dev
# 创建 Deployment
kubectl create deployment mytomcat --image=tomcat:8.5.68
# 创建多副本 Deployment
kubectl create deployment my-dep --image=nginx --replicas=3
# 查看创建的 Pod
kubectl get pods -n dev
# 查看 deployment 的信息
kubectl get deploy -n dev
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
kubectl get deploy -n dev -o wide
# 查看 deployment 的详细信息
kubectl describe deploy nginx -n dev
# 删除
kubectl delete deploy nginx -n dev
# 配置文件
kubectl create -f pc-deployment.yaml
kubectl delete -f pc-deployment.yaml3.1 扩缩容
# 变更副本数量为 5 个
kubectl scale deploy pc-deployment --replicas=5 -n dev
# 编辑 deployment 的副本数量,修改 spec:replicas: 4 即可
kubectl edit deploy pc-deployment -n dev
# 扩缩容,修改 replicas 属性
kubectl scale deployment/my-dep --replicas=5
kubectl scale deployment/my-dep --replicas=2
# vim 式修改扩缩容(修改 replicas 属性)
kubectl edit deployment my-dep3.2 镜像更新
假如有 3 个副本,执行滚动更新的过程为:
- 在一个 node 上创建一个 v2 版本的 pod,当该 pod 为 running 状态后(deployment 链接到 v2 版本的 pod) ,将该 node 上的 v1 版本的 pod 下掉。
- 依次重复“创建一个新版本的 pod,更新一个链接的 pod,下掉一个旧版本的 pod”
- 可以在尝试的时候,使用
watch -n 1 kubectl get pod来实时查看变化过程。
deployment 支持两种更新策略: 重建更新 和 滚动更新,可以通过 strategy 指定策略类型,支持两个属性:
type:指定策略类型,支持两种策略Recreate:在创建出新的 Pod 之前会先杀掉所有已存在的 PodRollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本 Pod
rollingUpdate:当 type 为 RollingUpdate 时生效,用于为 RollingUpdate 设置参数,支持两个属性:maxUnavailable:用来指定在升级过程中不可用 Pod 的最大数量,默认为 25%。违规词汇: 用来指定在升级过程中可以超过期望的 Pod 的最大数量,默认为 25%。
# 滚动更新(--record 记录版本更新记录,通过 history 查看)
kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record
kubectl rollout status deployment/my-dep
# vim 式修改滚动更新(直接修改版本号)
kubectl edit deployment/my-dep重建更新
spec:
strategy: # 策略
type: Recreate # 重建更新# 观察升级过程
[ root@k8s-master01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-65qcw 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-w5nzv 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 Running 0 31s
pc-deployment-5d89bdfbf9-xpt7w 1/1 Terminating 0 41s
pc-deployment-5d89bdfbf9-65qcw 1/1 Terminating 0 41s
pc-deployment-5d89bdfbf9-w5nzv 1/1 Terminating 0 41s
pc-deployment-675d469f8b-grn8z 0/1 Pending 0 0s
pc-deployment-675d469f8b-hbl4v 0/1 Pending 0 0s
pc-deployment-675d469f8b-67nz2 0/1 Pending 0 0s
pc-deployment-675d469f8b-grn8z 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-hbl4v 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-67nz2 0/1 ContainerCreating 0 0s
pc-deployment-675d469f8b-grn8z 1/1 Running 0 1s
pc-deployment-675d469f8b-67nz2 1/1 Running 0 1s
pc-deployment-675d469f8b-hbl4v 1/1 Running 0 2s镜像更新中 rs 的变化
# 查看 rs,发现原来的 rs 的依旧存在,只是 pod 数量变为了 0,而后又新产生了一个 rs,pod 数量为 4
# 其实这就是 deployment 能够进行版本回退的奥妙所在,后面会详细解释
[ root@k8s-master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 0 0 0 7m37s
pc-deployment-6696798b11 0 0 0 5m37s
pc-deployment-c848d76789 4 4 4 72s滚动更新
spec:
strategy: # 策略
type: RollingUpdate # 滚动更新策略
rollingUpdate:
违规词汇: 25%
maxUnavailable: 25%# 观察升级过程
[ root@k8s-master01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-deployment-c848d767-8rbzt 1/1 Running 0 31m
pc-deployment-c848d767-h4p68 1/1 Running 0 31m
pc-deployment-c848d767-hlmz4 1/1 Running 0 31m
pc-deployment-c848d767-rrqcn 1/1 Running 0 31m
pc-deployment-966bf7f44-226rx 0/1 Pending 0 0s
pc-deployment-966bf7f44-226rx 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-226rx 1/1 Running 0 1s
pc-deployment-c848d767-h4p68 0/1 Terminating 0 34m
pc-deployment-966bf7f44-cnd44 0/1 Pending 0 0s
pc-deployment-966bf7f44-cnd44 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-cnd44 1/1 Running 0 2s
pc-deployment-c848d767-hlmz4 0/1 Terminating 0 34m
pc-deployment-966bf7f44-px48p 0/1 Pending 0 0s
pc-deployment-966bf7f44-px48p 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-px48p 1/1 Running 0 0s
pc-deployment-c848d767-8rbzt 0/1 Terminating 0 34m
pc-deployment-966bf7f44-dkmqp 0/1 Pending 0 0s
pc-deployment-966bf7f44-dkmqp 0/1 ContainerCreating 0 0s
pc-deployment-966bf7f44-dkmqp 1/1 Running 0 2s
pc-deployment-c848d767-rrqcn 0/1 Terminating 0 34m3.3 版本回退
deployment 支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,
kubectl rollout:版本升级相关功能,支持下面的选项:
- status 显示当前升级状态
- history 显示升级历史记录
- pause 暂停版本升级过程
- resume 继续已经暂停的版本升级过程
- restart 重启版本升级过程
- undo 回滚到上一级版本(可以使用—to-revision 回滚到指定版本)
# 查看所有的历史记录
kubectl rollout history deployment/my-dep
# 查看某个历史详情
kubectl rollout history deployment/my-dep --revision=2
# 回滚(回到上次,也是滚动更新)
kubectl rollout undo deployment/my-dep
# 回滚(回到指定版本,也是滚动更新)
kubectl rollout undo deployment/my-dep --to-revision=2
# 查看当前升级版本的状态
[ root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out
# 查看升级历史记录
[ root@k8s-master01 ~]# 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@k8s-master01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back
# 查看发现,通过 nginx 镜像版本可以发现到了第一版
[ root@k8s-master01 ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
pc-deployment 4/4 4 4 74m nginx nginx:1.17.1
# 查看 rs,发现第一个 rs 中有 4 个 pod 运行,后面两个版本的 rs 中 pod 为运行
# 其实 deployment 之所以可是实现版本的回滚,就是通过记录下历史 rs 来实现的,
# 一旦想回滚到哪个版本,只需要将当前版本 pod 数量降为 0,然后将回滚版本的 pod 提升为目标数量就可以了
[ root@k8s-master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6696798b78 4 4 4 78m
pc-deployment-966bf7f44 0 0 0 37m
pc-deployment-c848d767 0 0 0 71m3.4 金丝雀发布
Deployment 控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。
比如有一批新的 Pod 资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的 Pod 应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的 Pod 资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
# 更新 deployment 的版本,并配置暂停 deployment
[ root@k8s-master01 ~]# 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@k8s-master01 ~]# 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@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4
[ root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
pc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
pc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 确保更新的 pod 没问题了,继续更新
[ root@k8s-master01 ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
# 查看最后的更新情况
[ root@k8s-master01 ~]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
pc-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1
pc-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2
pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4
[ root@k8s-master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s
pc-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37s4 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 的实现原理。

4.1 安装 metrics-server
metrics-server 可以用来收集集群中的资源使用情况
# 安装 git
[ root@k8s-master01 ~]# yum install git -y
# 获取 metrics-server, 注意使用的版本
[ root@k8s-master01 ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
# 修改 deployment, 注意修改的是镜像和初始化参数
[ root@k8s-master01 ~]# cd /root/metrics-server/deploy/1.8+/
[ root@k8s-master01 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@k8s-master01 1.8+]# kubectl apply -f ./
# 查看 pod 运行情况
[ root@k8s-master01 1.8+]# kubectl get pod -n kube-system
metrics-server-6b976979db-2xwbj 1/1 Running 0 90s
# 使用 kubectl top node 查看资源使用情况
[ root@k8s-master01 1.8+]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master01 289m 14% 1582Mi 54%
k8s-node01 81m 4% 1195Mi 40%
k8s-node02 72m 3% 1211Mi 41%
[ root@k8s-master01 1.8+]# kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-6955765f44-7ptsb 3m 9Mi
coredns-6955765f44-vcwr5 3m 8Mi
etcd-master 14m 145Mi
...
# 至此,metrics-server 安装完成4.2 准备 deployment 和 service
创建 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
kubectl run nginx --image=nginx:1.17.1 --requests=cpu=100m -n dev
# 创建 service
kubectl expose deployment nginx --type=NodePort --port=80 -n dev# 查看
[ root@k8s-master01 1.8+]# kubectl get deployment,pod,svc -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 47s
NAME READY STATUS RESTARTS AGE
pod/nginx-7df9756ccc-bh8dr 1/1 Running 0 47s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx NodePort 10.101.18.29 <none> 80:31830/TCP 35s4.3 部署 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
[ root@k8s-master01 1.8+]# kubectl create -f pc-hpa.yaml
horizontalpodautoscaler.autoscaling/pc-hpa created
# 查看 hpa
[ root@k8s-master01 1.8+]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 62s4.4 测试
使用压测工具对 service 地址 192.168.5.4:31830 进行压测,然后通过控制台查看 hpa 和 pod 的变化
hpa 变化
[ root@k8s-master01 ~]# kubectl get hpa -n dev -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 4m11s
pc-hpa Deployment/nginx 0%/3% 1 10 1 5m19s
pc-hpa Deployment/nginx 22%/3% 1 10 1 6m50s
pc-hpa Deployment/nginx 22%/3% 1 10 4 7m5s
pc-hpa Deployment/nginx 22%/3% 1 10 8 7m21s
pc-hpa Deployment/nginx 6%/3% 1 10 8 7m51s
pc-hpa Deployment/nginx 0%/3% 1 10 8 9m6s
pc-hpa Deployment/nginx 0%/3% 1 10 8 13m
pc-hpa Deployment/nginx 0%/3% 1 10 1 14mdeployment 变化
[ root@k8s-master01 ~]# kubectl get deployment -n dev -w
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 11m
nginx 1/4 1 1 13m
nginx 1/4 1 1 13m
nginx 1/4 1 1 13m
nginx 1/4 4 1 13m
nginx 1/8 4 1 14m
nginx 1/8 4 1 14m
nginx 1/8 4 1 14m
nginx 1/8 8 1 14m
nginx 2/8 8 2 14m
nginx 3/8 8 3 14m
nginx 4/8 8 4 14m
nginx 5/8 8 5 14m
nginx 6/8 8 6 14m
nginx 7/8 8 7 14m
nginx 8/8 8 8 15m
nginx 8/1 8 8 20m
nginx 8/1 8 8 20m
nginx 1/1 1 1 20mpod 变化
[ root@k8s-master01 ~]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
nginx-7df9756ccc-bh8dr 1/1 Running 0 11m
nginx-7df9756ccc-cpgrv 0/1 Pending 0 0s
nginx-7df9756ccc-8zhwk 0/1 Pending 0 0s
nginx-7df9756ccc-rr9bn 0/1 Pending 0 0s
nginx-7df9756ccc-cpgrv 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-8zhwk 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-rr9bn 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-m9gsj 0/1 Pending 0 0s
nginx-7df9756ccc-g56qb 0/1 Pending 0 0s
nginx-7df9756ccc-sl9c6 0/1 Pending 0 0s
nginx-7df9756ccc-fgst7 0/1 Pending 0 0s
nginx-7df9756ccc-g56qb 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-m9gsj 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-sl9c6 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-fgst7 0/1 ContainerCreating 0 0s
nginx-7df9756ccc-8zhwk 1/1 Running 0 19s
nginx-7df9756ccc-rr9bn 1/1 Running 0 30s
nginx-7df9756ccc-m9gsj 1/1 Running 0 21s
nginx-7df9756ccc-cpgrv 1/1 Running 0 47s
nginx-7df9756ccc-sl9c6 1/1 Running 0 33s
nginx-7df9756ccc-g56qb 1/1 Running 0 48s
nginx-7df9756ccc-fgst7 1/1 Running 0 66s
nginx-7df9756ccc-fgst7 1/1 Terminating 0 6m50s
nginx-7df9756ccc-8zhwk 1/1 Terminating 0 7m5s
nginx-7df9756ccc-cpgrv 1/1 Terminating 0 7m5s
nginx-7df9756ccc-g56qb 1/1 Terminating 0 6m50s
nginx-7df9756ccc-rr9bn 1/1 Terminating 0 7m5s
nginx-7df9756ccc-m9gsj 1/1 Terminating 0 6m50s
nginx-7df9756ccc-sl9c6 1/1 Terminating 0 6m50s
5 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,内容如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pc-daemonset
namespace: dev
spec:
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1# 创建 daemonset
kubectl create -f pc-daemonset.yaml
# 查看 daemonset
kubectl get ds -n dev -o wide
# 查看 pod,发现在每个 Node 上都运行一个 pod
kubectl get pods -n dev -o wide
# 删除 daemonset
kubectl delete -f pc-daemonset.yaml6 Job
Job,主要用于负责批量处理(一次要处理指定数量任务) 短暂的一次性(每个任务仅运行一次就结束) 任务。
Job 特点如下:
- 当 Job 创建的 pod 执行成功结束时,Job 将记录成功结束的 pod 数量
- 当成功结束的 pod 达到指定的数量时,Job 将完成执行

Job 的资源清单文件:
apiVersion: batch/v1 # 版本号
kind: Job # 类型
metadata: # 元数据
name: # rs 名称
namespace: # 所属命名空间
labels: #标签
controller: job
spec: # 详情描述
completions: 1 # 指定 job 需要成功运行 Pods 的次数。默认值: 1
parallelism: 1 # 指定 job 在任一时刻应该并发运行 Pods 的数量。默认值: 1
activeDeadlineSeconds: 30 # 指定 job 可运行的时间期限,超过时间还未结束,系统将会尝试进行终止。
backoffLimit: 6 # 指定 job 失败后进行重试的次数。默认是 6
manualSelector: true # 是否可以使用 selector 选择器选择 pod,默认是 false
selector: # 选择器,通过它指定该控制器管理哪些 pod
matchLabels: # Labels 匹配规则
app: counter-pod
matchExpressions: # Expressions 匹配规则
- { key: app, operator: In, values: [counter-pod] }
template: # 模板,当副本数量不足时,会根据下面的模板创建 pod 副本
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never # 重启策略只能设置为 Never 或者 OnFailure
containers:
- name: counter
image: busybox:1.30
command:
[
"bin/sh",
"-c",
"for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 2;done",
]关于重启策略设置的说明:
OnFailure,则 job 会在 pod 出现故障时重启容器,而不是创建 pod,failed 次数不变Never,则 job 会在 pod 出现故障时创建新的 pod,并且故障 pod 不会消失,也不会重启,failed 次数加 1Always的话,就意味着一直重启,意味着 job 任务会重复去执行了,当然不对,所以不能设置为 Always
创建 pc-job.yaml,内容如下:
apiVersion: batch/v1
kind: Job
metadata:
name: pc-job
namespace: dev
spec:
manualSelector: true
selector:
matchLabels:
app: counter-pod
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command:
[
"bin/sh",
"-c",
"for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done",
]# 创建 job
kubectl create -f pc-job.yaml
# 查看 job
kubectl get job -n dev -o wide -w
# 通过观察 pod 状态可以看到,pod 在运行完毕任务后,就会变成 Completed 状态
kubectl get pods -n dev -w
# 接下来,调整下 pod 运行的总数量和并行数量即:在 spec 下设置下面两个选项
# completions: 6 # 指定 job 需要成功运行 Pods 的次数为 6
# parallelism: 3 # 指定 job 并发运行 Pods 的数量为 3
# 然后重新运行 job,观察效果,此时会发现,job 会每次运行 3 个 pod,总共执行了 6 个 pod
kubectl get pods -n dev -w
# 删除 job
kubectl delete -f pc-job.yaml7 CronJob (CJ)
CronJob 控制器以 Job 控制器资源为其管控对象,并借助它管理 pod 资源对象,Job 控制器定义的作业任务在其控制器资源创建之后便会立即执行,但 CronJob 可以以类似于 Linux 操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。也就是说,CronJob 可以在特定的时间点(反复的)去运行 job 任务。

CronJob 的资源清单文件:
apiVersion: batch/v1beta1 # 版本号
kind: CronJob # 类型
metadata: # 元数据
name: # rs 名称
namespace: # 所属命名空间
labels: #标签
controller: cronjob
spec: # 详情描述
schedule: # cron 格式的作业调度运行时间点,用于控制任务在什么时间执行
concurrencyPolicy: # 并发执行策略,用于定义前一次作业运行尚未完成时是否以及如何运行后一次的作业
failedJobHistoryLimit: # 为失败的任务执行保留的历史记录数,默认为 1
successfulJobHistoryLimit: # 为成功的任务执行保留的历史记录数,默认为 3
startingDeadlineSeconds: # 启动作业错误的超时时长
jobTemplate: # job 控制器模板,用于为 cronjob 控制器生成 job 对象;下面其实就是 job 的定义
metadata:
spec:
completions: 1
parallelism: 1
activeDeadlineSeconds: 30
backoffLimit: 6
manualSelector: true
selector:
matchLabels:
app: counter-pod
matchExpressions: 规则
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 20;done"]需要重点解释的几个选项:
schedule: cron 表达式,用于指定任务的执行时间
_/1 _ \* \* \*
<分钟> <小时> <日> <月份> <星期>
分钟值从 0 到 59.
小时值从 0 到 23.
日值从 1 到 31.
月值从 1 到 12.
星期值从 0 到 6, 0 代表星期日
多个时间可以用逗号隔开;范围可以用连字符给出;*可以作为通配符; /表示每...
concurrencyPolicy:
Allow: 允许 Jobs 并发运行(默认)
Forbid: 禁止并发运行,如果上一次运行尚未完成,则跳过下一次运行
Replace: 替换,取消当前正在运行的作业并用新作业替换它创建 pc-cronjob.yaml,内容如下:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: pc-cronjob
namespace: dev
labels:
controller: cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
metadata:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command:
[
"bin/sh",
"-c",
"for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done",
]# 创建 cronjob
kubectl create -f pc-cronjob.yaml
# 查看 cronjob
kubectl get cronjobs -n dev
# 查看 job
kubectl get jobs -n dev
# 查看 pod
kubectl get pods -n dev
# 删除 cronjob
kubectl delete -f pc-cronjob.yaml