目录
五、Horizontal Pod Autoscaler(HPA)
一、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 :管理有状态应用
总体来说,K8S有五种控制器,分别对应处理无状态应用、有状态应用、守护型应用和批处理应用
二、pod与控制器之间的关系

三、 ReplicaSet(RS)
ReplicaSet的资源清单文件:
apiVersion : apps/v1 # 版本号kind : ReplicaSet # 类型metadata : # 元数据name : # rs 名称namespace : # 所属命名空间labels : # 标签controller : rsspec : # 详情描述replicas : 3 # 副本数量selector : # 选择器,通过它指定该控制器管理哪些 podmatchLabels : # Labels 匹配规则app : nginx-podmatchExpressions : # Expressions 匹配规则- { key : app , operator : In , values : [ nginx-pod ]}template : # 模板,当副本数量不足时,会根据下面的模板创建 pod 副本metadata :labels :app : nginx-podspec :containers :- name : nginximage : nginx : 1.17.1ports :- containerPort : 80
replicas :指定副本数量,其实就是当前 rs 创建出来的 pod 的数量,默认为 1selector :选择器,它的作用是建立 pod 控制器和 pod 之间的关联关系,采用的 Label Selector 机制在 pod 模板上定义 label ,在控制器上定义选择器,就可以表明当前控制器能管理哪些 pod 了template :模板,就是当前控制器创建 pod 所使用的模板板,里面其实就是前一章学过的 pod 的定义
1.创建ReplicaSet
[root@k8s-master01 k8s_test]# vim pc-relicaset.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
# 创建rs
[root@k8s-master01 k8s_test]# kubectl create -f pc-relicaset.yaml
replicaset.apps/pc-replicaset created
# 查看rs
# DESIRED:期望副本数量
# CURRENT:当前副本数量
# READY:已经准备好提供服务的副本数量
[root@k8s-master01 k8s_test]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3 3 3 50s nginx nginx:1.17.1 app=nginx-pod
# 查看当前控制器创建出来的pod
# 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码
[root@k8s-master01 k8s_test]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-vdvfd 1/1 Running 0 2m
pc-replicaset-vwbhw 1/1 Running 0 2m
pc-replicaset-z29q7 1/1 Running 0 2m
pod-nodeaffinity-preferred 1/1 Running 1 (75m ago) 16h
2. 扩缩容
# 编辑rs的副本数量,修改spec:replicas: 6即可
[root@k8s-master01 k8s_test]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
[root@k8s-master01 k8s_test]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-2llf8 1/1 Running 0 40s
pc-replicaset-gdtsz 1/1 Running 0 40s
pc-replicaset-rxdsb 1/1 Running 0 40s
pc-replicaset-vdvfd 1/1 Running 0 4m27s
pc-replicaset-vwbhw 1/1 Running 0 4m27s
pc-replicaset-z29q7 1/1 Running 0 4m27s
# 当然也可以直接使用命令实现
# 使用scale命令实现扩缩容, 后面--replicas=n直接指定目标数量即可
[root@k8s-master01 k8s_test]# kubectl scale rs pc-replicaset --replicas=2 -n dev
replicaset.apps/pc-replicaset scaled
#稍等片刻,就只剩下2个了
[root@k8s-master01 k8s_test]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-vdvfd 1/1 Running 0 6m11s
pc-replicaset-vwbhw 1/1 Running 0 6m11s
3. 镜像升级
# 编辑rs的容器镜像 - image: nginx:1.17.2
[root@k8s-master01 k8s_test]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
# 再次查看,发现镜像版本已经变更了
[root@k8s-master01 k8s_test]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 2 2 2 8m56s nginx nginx:1.17.2 app=nginx-pod
# 同样的道理,也可以使用命令完成这个工作
# kubectl set image rs rs名称 容器=镜像版本 -n namespace
[root@k8s-master01 k8s_test]# kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev
repli
caset.apps/pc-replicaset image updated
# 再次查看,发现镜像版本已经变更了
[root@k8s-master01 k8s_test]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 2 2 2 10m nginx nginx:1.17.1 app=nginx-pod
4. 删除ReplicaSet
# 使用kubectl delete命令会删除此RS以及它管理的Pod
# 在kubernetes删除RS前,会将RS的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象
的删除
[root@k8s-master01 k8s_test]# kubectl delete rs pc-replicaset -n dev
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 k8s_test]# kubectl get pod -n dev -o wide
No resources found in dev namespace.
# 如果希望仅仅删除RS对象(保留Pod),可以使用kubectl delete命令时添加--cascade=false选项
(不推荐)。
[root@k8s-master01 k8s_test]# kubectl delete rs pc-replicaset -n dev --cascade=false
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
replicaset.apps "pc-replicaset" deleted
[root@k8s-master01 k8s_test]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-7nbfz 1/1 Running 0 32s
pc-replicaset-txgcq 1/1 Running 0 32s
pc-replicaset-vttdr 1/1 Running 0 32s
# 也可以使用yaml直接删除(推荐)
[root@k8s-master01 k8s_test]# kubectl delete -f pc-relicaset.yaml
replicaset.apps "pc-replicaset" deleted
四、Deployment(Deploy)

支持 ReplicaSet 的所有功能支持发布的停止、继续支持滚动升级和回滚版本
Deployment的资源清单文件:
apiVersion : apps/v1 # 版本号kind : Deployment # 类型metadata : # 元数据name : # rs 名称namespace : # 所属命名空间labels : # 标签controller : deployspec : # 详情描述replicas : 3 # 副本数量revisionHistoryLimit : 3 # 保留历史版本paused : false # 暂停部署,默认是 falseprogressDeadlineSeconds : 600 # 部署超时时间( s ),默认是 600strategy : # 策略type : RollingUpdate # 滚动更新策略rollingUpdate : # 滚动更新maxSurge : 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数maxUnavailable : 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数selector : # 选择器,通过它指定该控制器管理哪些 podmatchLabels : # Labels 匹配规则app : nginx-podmatchExpressions : # Expressions 匹配规则- { key : app , operator : In , values : [ nginx-pod ]}template : # 模板,当副本数量不足时,会根据下面的模板创建 pod 副本metadata :labels :app : nginx-podspec :containers :- name : nginximage : nginx : 1.17.1ports :- containerPort : 80
1. 创建deployment
创建pc-deployment.yaml,内容如下:
[root@k8s-master01 deployment]# vim 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@k8s-master01 deployment]# kubectl create -f pc-deployment.yaml --record=true
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/pc-deployment created
# 查看deployment
# UP-TO-DATE 最新版本的pod的数量
# AVAILABLE 当前可用的pod的数量
[root@k8s-master01 deployment]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 3/3 3 3 71s
# 查看rs
# 发现rs的名称是在原来deployment的名字后面添加了一个10位数的随机串
[root@k8s-master01 deployment]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-6cb555c765 3 3 3 2m3s
# 查看pod
[root@k8s-master01 deployment]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6cb555c765-59kpf 1/1 Running 0 3m1s
pc-deployment-6cb555c765-ppvzj 1/1 Running 0 3m1s
pc-deployment-6cb555c765-x5lkh 1/1 Running 0 3m1s
2. 扩缩容
# 变更副本数量为5个
[root@k8s-master01 deployment]# kubectl scale deploy pc-deployment --replicas=5 -n dev
deployment.apps/pc-deployment scaled
# 查看deployment
[root@k8s-master01 deployment]# kubectl get deploy pc-deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
pc-deployment 5/5 5 5 5m15s
# 查看pod
[root@k8s-master01 deployment]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6cb555c765-59kpf 1/1 Running 0 5m45s
pc-deployment-6cb555c765-9wg5x 1/1 Running 0 48s
pc-deployment-6cb555c765-ppvzj 1/1 Running 0 5m45s
pc-deployment-6cb555c765-x5lkh 1/1 Running 0 5m45s
pc-deployment-6cb555c765-xkrfw 1/1 Running 0 48s
# 编辑deployment的副本数量,修改spec:replicas: 4即可
[root@k8s-master01 deployment]# kubectl edit deploy pc-deployment -n dev
deployment.apps/pc-deployment edited
# 查看pod
[root@k8s-master01 deployment]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6cb555c765-59kpf 1/1 Running 0 7m12s
pc-deployment-6cb555c765-9wg5x 1/1 Running 0 2m15s
pc-deployment-6cb555c765-ppvzj 1/1 Running 0 7m12s
pc-deployment-6cb555c765-x5lkh 1/1 Running 0 7m12s
3. 镜像更新
strategy :指定新的 Pod 替换旧的 Pod 的策略, 支持两个属性:type:指定策略类型,支持两种策略Recreate:在创建出新的Pod 之前会先杀掉所有已存在的 PodRollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本PodrollingUpdate:当 type 为 RollingUpdate 时生效,用于为 RollingUpdate 设置参数,支持两个属性:maxUnavailable:用来指定在升级过程中不可用Pod 的最大数量,默认为 25% 。maxSurge: 用来指定在升级过程中可以超过期望的Pod 的最大数量,默认为 25% 。
3.1 重建更新
spec :strategy : # 策略type : Recreate # 重建更新

2. 创建deploy进行验证
# 变更镜像
[root@k8s-master01 deployment]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev
deployment.apps/pc-deployment image updated
# 观察升级过程
[root@k8s-master01 deployment]# kubectl get pods -n dev -w
3.2 滚动更新
spec :strategy : # 策略type : RollingUpdate # 滚动更新策略rollingUpdate :maxSurge : 25%maxUnavailable : 25%
2. 创建deploy进行验证
[root@k8s-master01 deployment]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev
deployment.apps/pc-deployment image updated
# 观察升级过程
[root@k8s-master01 deployment]# kubectl get pods -n dev -w
滚动更新的过程:
# 查看rs,发现原来的rs的依旧存在,只是pod数量变为了0,而后又新产生了一个rs,pod数量为4
# 其实这就是deployment能够进行版本回退的奥妙所在,后面会详细解释
[root@k8s-master01 deployment]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-5967bb44bb 0 0 0 19m
pc-deployment-6478867647 4 4 4 13m
pc-deployment-6cb555c765 0 0 0 30m
3.3 版本回退
status 显示当前升级状态history 显示 升级历史记录pause 暂停版本升级过程resume 继续已经暂停的版本升级过程restart 重启版本升级过程undo 回滚到上一级版本(可以使用 --to-revision 回滚到指定版本)
# 查看当前升级版本的状态
[root@k8s-master01 deployment]# 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 deployment]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back
# 查看发现,通过nginx镜像版本可以发现到了第一版
[root@k8s-master01 deployment]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
pc-deployment 4/4 4 4 34m nginx nginx:1.17.1 app=nginx-pod
# 查看rs,发现第一个rs中有4个pod运行,后面两个版本的rs中pod为运行
# 其实deployment之所以可是实现版本的回滚,就是通过记录下历史rs来实现的,
# 一旦想回滚到哪个版本,只需要将当前版本pod数量降为0,然后将回滚版本的pod提升为目标数量就可以了
[root@k8s-master01 deployment]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-5967bb44bb 0 0 0 23m
pc-deployment-6478867647 0 0 0 17m
pc-deployment-6cb555c765 4 4 4 34m
3.4 金丝雀发布
# 更新deployment的版本,并配置暂停deployment
[root@k8s-master01 deployment]# 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 deployment]# 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 deployment]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-deployment-5967bb44bb 0 0 0 29m nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=5967bb44bb
pc-deployment-6478867647 0 0 0 22m nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=6478867647
pc-deployment-6cb555c765 3 3 3 40m nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=6cb555c765
pc-deployment-6db6cc7d48 2 2 0 3m11s nginx nginx:1.17.4 app=nginx-pod,pod-template-hash=6db6cc7d48
[root@k8s-master01 deployment]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6cb555c765-9p6sf 1/1 Running 0 6m49s
pc-deployment-6cb555c765-dsxqg 1/1 Running 0 6m49s
pc-deployment-6cb555c765-lnxlh 1/1 Running 0 6m47s
pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
# 确保更新的pod没问题了,继续更新
[root@k8s-master01 deployment]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
# 查看最后的更新情况
[root@k8s-master01 deployment]# kubectl get rs -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-deployment-5967bb44bb 0 0 0 35m nginx nginx:1.17.2 app=nginx-pod,pod-template-hash=5967bb44bb
pc-deployment-6478867647 0 0 0 29m nginx nginx:1.17.3 app=nginx-pod,pod-template-hash=6478867647
pc-deployment-6cb555c765 0 0 0 46m nginx nginx:1.17.1 app=nginx-pod,pod-template-hash=6cb555c765
pc-deployment-6db6cc7d48 4 4 4 9m37s nginx nginx:1.17.4 app=nginx-pod,pod-template-hash=6db6cc7d48
[root@k8s-master01 deployment]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-6db6cc7d48-2kjtk 1/1 Running 0 2m44s
pc-deployment-6db6cc7d48-hhbxj 1/1 Running 0 9m41s
pc-deployment-6db6cc7d48-hj9lz 1/1 Running 0 2m45s
pc-deployment-6db6cc7d48-l79kq 1/1 Running 0 9m41s
4. 删除Deployment
# 删除deployment,其下的rs和pod也将被删除
[root@k8s-master01 deployment]# kubectl delete -f pc-deployment.yaml
deployment.apps "pc-deployment" deleted
五、Horizontal Pod Autoscaler(HPA)

1 安装metrics-server
注意:
0 .3 版本只支持到 1.21 ,本文使用 1.25 需要使用新版本。下载:-O metrics-server-components.yaml修改镜像地址:sed -i 's#k8s.gcr.io/metrics-server#registry.cn-hangzhou.aliyuncs.com/google_containers#g' metrics-server-components.yaml修改 components.yaml 文件,增加参数 –kubelet-insecure-tls 即可,否则出现 500 错误- --kubelet-insecure-tls因为我们发现无法联网下载k8s官方镜像,所以将image: k8s.gcr.io/metrics-server/metrics-server:v0.7.1改为阿里云的镜像
image: registry.aliyuncs.com/google_containers/metrics-server:v0.7.1
# 安装metrics-server
[root@k8s-master01 HPA]# kubectl apply -f metrics-server-components.yaml
[root@k8s-master01 HPA]# kubectl get pod -n kube-system | grep metrics-server
metrics-server-768c789bff-rcmk9 1/1 Running 0 80m
# 使用kubectl top node 查看资源使用情况
[root@k8s-master01 HPA]# kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master01 121m 3% 1309Mi 39%
k8s-node01 53m 1% 775Mi 23%
k8s-node02 91m 2% 1003Mi 30%
[root@k8s-master01 HPA]# kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
calico-kube-controllers-7cb4fd5784-47k7j 2m 25Mi
calico-node-mxhm4 17m 182Mi
calico-node-wgtwl 17m 184Mi
calico-node-ws52x 21m 179Mi
coredns-66f779496c-d2ljj 2m 22Mi
coredns-66f779496c-ftjlt 1m 71Mi
etcd-k8s-master01 14m 189Mi
kube-apiserver-k8s-master01 34m 396Mi
kube-controller-manager-k8s-master01 8m 151Mi
kube-proxy-65vrr 7m 83Mi
kube-proxy-fl8f8 1m 83Mi
kube-proxy-xwkjp 3m 83Mi
kube-scheduler-k8s-master01 2m 73Mi
metrics-server-768c789bff-rcmk9 3m 22Mi
# 至此,metrics-server安装完成
2.HPA API对象
[root@k8s-master01 HPA]# kubectl api-versions | grep autoscal
autoscaling/v1
autoscaling/v2
3.kubectl对HPA的支持
通过 kubectl create 命令创建一个 HPA 对象通过 kubectl get hpa 命令来获取所有 HPA 对象通过 kubectl describe hpa 命令来查看 HPA 对象的详细信息通过 kubectl delete hpa 命令删除对象。
此外,还有个简便的命令 kubectl autoscale 来创建 HPA 对象。
例如,命令 kubectl autoscale rs foo --min=2 --max=5 --cpu-percent=80 将会为名 为 foo 的 ReplicationSet 创建一个 HPA 对象, 目标 CPU 使用率为 80%,副本数量配置为 2 到 5 之间。
4. 准备deployment和servie
# 创建deployment
[root@k8s-master01 HPA]# vim pod4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
resources:
requests:
memory: "100Mi"
cpu: "1"
[root@k8s-master01 HPA]# kubectl create -f pod4.yaml
deployment.apps/nginx created
# 创建service
[root@k8s-master01 HPA]# kubectl expose deployment nginx --type=NodePort --port=80 -n dev
service/nginx exposed
# 查看
[root@k8s-master01 HPA]# kubectl get deployments.apps,svc,pod -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 2m47s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx NodePort 10.111.63.198 <none> 80:32308/TCP 43s
NAME READY STATUS RESTARTS AGE
pod/nginx-5966b4469f-tqz6c 1/1 Running 0 2m47s
5 部署HPA
[root@k8s-master01 HPA]# vim 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 HPA]# kubectl create -f pc-hpa.yaml
horizontalpodautoscaler.autoscaling/pc-hpa created
# 查看hpa
[root@k8s-master01 HPA]# kubectl get hpa -n dev
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
pc-hpa Deployment/nginx 0%/3% 1 10 1 92s
6 测试
# 使用 ab 压力测试:语法格式 :ab [OPTIONS] URL常用参数 :-n :总请求数-c :模拟的并行数-k :以持久连接模式测试[root@k8s-master01 HPA]# yum install httpd-tools -[root@k8s-master01 HPA]# ab -c 1000 -n 300000 http://192.168.186.100:31230/
hpa变化
[root@k8s-master01 HPA]# kubectl get hpa -n dev -w
deployment变化
[root@k8s-master01 HPA]# kubectl get deployment -n dev -w
pod变化
[root@k8s-master01 HPA]# kubectl get pods -n dev -w
六、DaemonSet(DS)

DaemonSet控制器的特点:
每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上当节点从集群中移除时, Pod 也就被垃圾回收了
apiVersion : apps/v1 # 版本号kind : DaemonSet # 类型metadata : # 元数据name : # rs 名称namespace : # 所属命名空间labels : # 标签controller : daemonsetspec : # 详情描述revisionHistoryLimit : 3 # 保留历史版本updateStrategy : # 更新策略type : RollingUpdate # 滚动更新策略rollingUpdate : # 滚动更新maxUnavailable : 1 # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数selector : # 选择器,通过它指定该控制器管理哪些 podmatchLabels : # Labels 匹配规则app : nginx-podmatchExpressions : # Expressions 匹配规则- { key : app , operator : In , values : [ nginx-pod ]}template : # 模板,当副本数量不足时,会根据下面的模板创建 pod 副本metadata :labels :app : nginx-podspec :containers :- name : nginximage : nginx : 1.17.1ports :- containerPort : 80
创建pc-daemonset.yaml,内容如下:
[root@k8s-master01 DS]# vim 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
[root@k8s-master01 DS]# kubectl create -f pc-daemonset.yaml
daemonset.apps/pc-daemonset created
# 查看daemonset
[root@k8s-master01 DS]# kubectl get ds -n dev -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
pc-daemonset 2 2 2 2 2 <none> 31s nginx nginx:1.17.1 app=nginx-pod
# 查看pod,发现在每个Node上都运行一个pod
[root@k8s-master01 DS]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5966b4469f-tqz6c 1/1 Running 0 44m 10.244.58.199 k8s-node01 <none> <none>
pc-daemonset-phc5z 1/1 Running 0 2m6s 10.244.58.205 k8s-node02 <none> <none>
# 删除daemonset
[root@k8s-master01 DS]# kubectl delete -f pc-daemonset.yaml
daemonset.apps "pc-daemonset" deleted
七、Job
当 Job 创建的 pod 执行成功结束时, Job 将记录成功结束的 pod 数量当成功结束的 pod 达到指定的数量时, Job 将完成执行
Job的资源清单文件:
apiVersion : batch/v1 # 版本号kind : Job # 类型metadata : # 元数据name : # rs 名称namespace : # 所属命名空间labels : # 标签controller : jobspec : # 详情描述completions : 1 # 指定 job 需要成功运行 Pods 的次数。默认值 : 1parallelism : 1 # 指定 job 在任一时刻应该并发运行 Pods 的数量。默认值 : 1activeDeadlineSeconds : 30 # 指定 job 可运行的时间期限,超过时间还未结束,系统将会尝试进行终止。backoffLimit : 6 # 指定 job 失败后进行重试的次数。默认是 6manualSelector : true # 是否可以使用 selector 选择器选择 pod ,默认是 falseselector : # 选择器,通过它指定该控制器管理哪些 podmatchLabels : # Labels 匹配规则app : counter-podmatchExpressions : # Expressions 匹配规则- { key : app , operator : In , values : [ counter-pod ]}template : # 模板,当副本数量不足时,会根据下面的模板创建 pod 副本metadata :labels :app : counter-podspec :restartPolicy : Never # 重启策略只能设置为 Never 或者 OnFailurecontainers :- name : counterimage : busybox : 1.30command : [ "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次数加 1如果指定为Always 的话,就意味着一直重启,意味着 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
[root@k8s-master01 DS]# kubectl create -f pd-job.yaml
job.batch/pc-job created
# 查看job
[root@k8s-master01 DS]# kubectl get jobs -n dev -o wide -w
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
pc-job 0/1 21s 21s counter busybox:1.30 app=counter-pod
pc-job 1/1 31s 79s counter busybox:1.30 app=counter-pod
# 通过观察pod状态可以看到,pod在运行完毕任务后,就会变成Completed状态
[root@k8s-master01 DS]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
pc-job-rxg96 1/1 Running 0 66m
pc-job-4zs22 0/1 Completed 0 6m44s
# 接下来,调整下pod运行的总数量和并行数量 即:在spec下设置下面两个选项
# completions: 6 # 指定job需要成功运行Pods的次数为6
# parallelism: 3 # 指定job并发运行Pods的数量为3
# 然后重新运行job,观察效果,此时会发现,job会每次运行3个pod,总共执行了6个pod
[root@k8s-master01 DS]# kubectl delete -f pd-job.yaml
job.batch "pc-job" deleted
[root@k8s-master01 DS]# kubectl create -f pd-job.yaml
job.batch/pc-job created
[root@k8s-master01 DS]# kubectl get pods -n dev -w
NAME READY STATUS RESTARTS AGE
nginx-5966b4469f-tqz6c 1/1 Running 0 72m
pc-job-4gjmw 0/1 Completed 0 46s
pc-job-dc5vt 0/1 Completed 0 78s
pc-job-p57t8 0/1 Completed 0 78s
pc-job-q8mhp 0/1 Completed 0 46s
pc-job-wzl4r 0/1 Completed 0 46s
pc-job-xz9l9 0/1 Completed 0 78s
# 删除job
[root@k8s-master01 DS]# kubectl delete -f pd-job.yaml
job.batch "pc-job" deleted
八、 CronJob(CJ)

CronJob的资源清单文件:
apiVersion : batch/v1beta1 # 版本号kind : CronJob # 类型metadata : # 元数据name : # rs 名称namespace : # 所属命名空间labels : # 标签controller : cronjobspec : # 详情描述schedule : # cron 格式的作业调度运行时间点 , 用于控制任务在什么时间执行concurrencyPolicy : # 并发执行策略,用于定义前一次作业运行尚未完成时是否以及如何运行后一次的作业failedJobHistoryLimit : # 为失败的任务执行保留的历史记录数,默认为 1successfulJobHistoryLimit : # 为成功的任务执行保留的历史记录数,默认为 3startingDeadlineSeconds : # 启动作业错误的超时时长jobTemplate : # job 控制器模板,用于为 cronjob 控制器生成 job 对象 ; 下面其实就是 job 的定义metadata :spec :completions : 1parallelism : 1activeDeadlineSeconds : 30backoffLimit : 6manualSelector : trueselector :matchLabels :app : counter-podmatchExpressions : 规则- { key : app , operator : In , values : [ counter-pod ]}template :metadata :labels :app : counter-podspec :restartPolicy : Nevercontainers :- name : counterimage : busybox : 1.30command : [ "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: 替换,取消当前正在运行的作业并用新作业替换它
apiVersion: batch/v1
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
[root@k8s-master01 CJ]# kubectl create -f pc-cronjob.yaml
cronjob.batch/pc-cronjob created
# 查看cronjob
[root@k8s-master01 CJ]# kubectl get cronjobs -n dev
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
pc-cronjob */1 * * * * False 1 18s 85s
# 查看job
[root@k8s-master01 CJ]# kubectl get jobs -n dev
NAME COMPLETIONS DURATION AGE
pc-cronjob-28597386 1/1 31s 2m51s
pc-cronjob-28597387 1/1 30s 111s
pc-cronjob-28597388 1/1 30s 51s
# 查看pod
[root@k8s-master01 CJ]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-cronjob-28597387-pq4j7 0/1 Completed 0 2m44s
pc-cronjob-28597388-9qnzp 0/1 Completed 0 104s
pc-cronjob-28597389-5lqdj 0/1 Completed 0 44s
九、StatefulSet(有状态)
● 无状态应用:○ 认为 Pod 都是一样的。○ 没有顺序要求。○ 不用考虑在哪个 Node 节点上运行。○ 随意进行伸缩和扩展。● 有状态应用:○ 有顺序的要求。○ 认为每个 Pod 都是不一样的。○ 需要考虑在哪个 Node 节点上运行。○ 需要按照顺序进行伸缩和扩展。○ 让每个 Pod 都是独立的,保持 Pod 启动顺序和唯一性。● StatefulSet 是 Kubernetes 提供的管理有状态应用的负载管理控制器。● StatefulSet 部署需要 HeadLinessService (无头服务)。为什么需要 HeadLinessService (无头服务)?● 在用 Deployment 时,每一个 Pod 名称是没有顺序的,是随机字符串,因此是 Pod 名称是无序的,但是在StatefulSet 中要求必须是有序 ,每一个 Pod 不能被随意取代, Pod 重建后 pod 名称还是一样的。● 而 Pod IP 是变化的,所以是以 Pod 名称来识别。 Pod 名称是 Pod 唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个 Pod 一个唯一的名称 。● StatefulSet 常用来部署 RabbitMQ 集群、 Zookeeper 集群、 MySQL 集群、 Eureka 集群等
apiVersion: v1
kind: Service
metadata:
name: service-headliness
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
type: ClusterIP
ports:
- port: 80 # Service的端口
targetPort: 80 # Pod的端口
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: pc-statefulset
namespace: dev
spec:
replicas: 3
serviceName: service-headliness
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
创建StatefulSet:
[root@k8s-master01 SatafulSet]# kubectl create -f pc-stateful.yaml
查看StatefulSet
[root@k8s-master01 SatafulSet]# kubectl get statefulsets.apps pc-statefulset -n dev -o wide
NAME READY AGE CONTAINERS IMAGES
pc-statefulset 3/3 43s nginx nginx:1.17.1
查看Pod:
[root@k8s-master01 SatafulSet]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pc-statefulset-0 1/1 Running 0 2m19s 10.244.58.213 k8s-node02 <none> <none>
pc-statefulset-1 1/1 Running 0 2m18s 10.244.58.215 k8s-node02 <none> <none>
pc-statefulset-2 1/1 Running 0 2m17s 10.244.58.216 k8s-node02 <none> <none>
删除StatefulSet
[root@k8s-master01 SatafulSet]# kubectl delete -f pc-stateful.yaml
● Deployment 和 StatefulSet 的区别: Deployment 没有唯一标识而 StatefulSet 有唯一标识。● StatefulSet 的唯一标识是根据主机名 + 一定规则生成的。● StatefulSet 的唯一标识是主机名 . 无头 Service 名称 . 命名空间 .svc.cluster.local 。