目录
什么是控制器
之前创建了自主式 Pod,当Pod 退出后不会被创建,这就是生产环境不建议用的原因。如果加入了控制器,控制器管理的 Pod,在控制器的生命周期里,始终要维持 Pod 的副本数目,删除一个副本,控制器就会自动补一个副本,这样可以稳定的提供服务。
控制器是管理pod的中间层,只需要告诉Pod控制器,想要创建多少个什么样的Pod,它会创建出满足条件的Pod ; 控制器相当于一个状态机,用来控制Pod的具体状态和行为 ; controller会自动创建相应的pod资源,并在当pod发生故障的时候按照策略进行重新编排; 通过它来实现对pod的管理,比如启动pod、停止pod、扩展pod的数量等等 ; 通俗来说就是,控制器就是pod的幕后老板。
ReplicaSet控制器
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。主要被Deployments 用作协调 Pod 创建、删除和更新的机制
使用
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet, 除非你需要自定义更新业务流程或根本不需要更新。
这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义你的应用。
编辑 replicaset.yaml文件,副本数为6
[root@k8s2 pod]# vim replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: frontend
spec:
replicas: 6
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: myapp:v1
执行yaml文件
[root@k8s2 pod]# kubectl apply -f replicaset.yaml
查看pod的标签
[root@k8s2 pod]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-29jrr 1/1 Running 0 8s app=frontend
frontend-7wlhg 1/1 Running 0 8s app=frontend
frontend-996cs 1/1 Running 0 8s app=frontend
replicaset是通过标签匹配pod
[root@k8s2 pod]# kubectl label pod frontend-29jrr app=myapp --overwrite
再次查看,frontend-29jrr标签的副本app变成了myapp
[root@k8s2 pod]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-29jrr 1/1 Running 0 4m29s app=myapp
frontend-2b5gc 1/1 Running 0 3m6s app=frontend
frontend-7wlhg 1/1 Running 0 4m29s app=frontend
frontend-996cs 1/1 Running 0 4m29s app=frontend
frontend-bdmg2 1/1 Running 0 3m6s app=frontend
frontend-k8dhh 1/1 Running 0 3m6s app=frontend
frontend-vd8f2 1/1 Running 0 6s app=frontend
将标签改回来
[root@k8s2 pod]# kubectl label pod frontend-29jrr app=frontend --overwrite
[root@k8s2 pod]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-29jrr 1/1 Running 0 5m48s app=frontend
frontend-2b5gc 1/1 Running 0 4m25s app=frontend
frontend-7wlhg 1/1 Running 0 5m48s app=frontend
frontend-996cs 1/1 Running 0 5m48s app=frontend
frontend-bdmg2 1/1 Running 0 4m25s app=frontend
frontend-k8dhh 1/1 Running 0 4m25s app=frontend
删掉所有pod,查看是否能重新拉起
[root@k8s2 pod]# kubectl delete pod --all
pod "frontend-29jrr" deleted
pod "frontend-2b5gc" deleted
pod "frontend-7wlhg" deleted
pod "frontend-996cs" deleted
pod "frontend-bdmg2" deleted
pod "frontend-k8dhh" deleted
pod重新拉起,replicaset自动控制副本数量,pod可以自愈
[root@k8s2 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
frontend-4mrxh 1/1 Running 0 6s
frontend-7z5gt 1/1 Running 0 6s
frontend-jlxwt 1/1 Running 0 6s
frontend-jt48g 1/1 Running 0 6s
frontend-qs8bk 1/1 Running 0 6s
frontend-z6p7g 1/1 Running 0 6s
要删除 ReplicaSet 和它的所有 Pod,使用 kubectl delete 命令。 默认情况下,垃圾收集器 自动删除所有依赖的 Pod。
kubectl delete -f replicaset.yaml
Deployment控制器
用于部署应用的对象。它使Kubernetes中最常用的一个对象,它为ReplicaSet和Pod的创建提供了一种声明式的定义方法,Deployment对象拥有许多ReplicaSet没有的特性,例如滚动升级和回滚。
负责 Pod 的部署,并维护部署拓扑(创建、监控、自修复 Pod),保证 Pod 按照期望的状态运行。生成一个新的deployment控制器的pod,删除之后会自动重新生成不同id的pod
通过Deployment对象,你可以轻松的做到以下事情:
1.创建ReplicaSet和Pod
2.滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)
3.平滑地扩容和缩容
4.暂停和继续Deployment
编写deployment.yaml文件
[root@k8s2 pod]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
minReadySeconds: 5 #就绪时间
strategy: #更新策略
rollingUpdate:
maxSurge: 1 #最大为1,每次先上新一个,成功了再下一个旧
maxUnavailable: 0 #最大不可用数为0,更新不会动原先的副本
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
[root@k8s2 pod]# kubectl apply -f deployment.yaml
暂停,避免触发不必要的线上更新
[root@k8s2 pod]# kubectl rollout pause deployment myapp-deployment
调整副本数,不受影响
[root@k8s2 pod]# kubectl scale deployment myapp-deployment --replicas 6
版本迭代
[root@k8s2 pod]# kubectl set image deployment myapp-deployment myapp=myapp:v2
修改资源限制,
[root@k8s2 pod]# kubectl set resources deployment/myapp-deployment -c=myapp --limits=cpu=200m,memory=512Mi
查看可回退的版本
[root@k8s2 pod]# kubectl rollout resume deployment/myapp-deployment
DaemonSet控制器
用于每个 Nodes 都运行且只运行一个 Pod 副本的场景。DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。通常用于运行 daemon 服务进程。
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
如何实现这个功能
- 从etcd中获取所有node的信息,循环遍历每个node,没有守护容器的就新建,超过1个的就删除,正好就1个的就表示正常;
- 通过nodeAffinity节点亲和性来保证每个守护pod只会在和其亲和的节点上被调度运行;
- 通过tolerations声明,允许守护pod可以在被标记为污点的Node上调度运行;
一个典型用法是在每个节点上运行监控 DaemonSet,例如 zabbix agent等。保证每个节点做一次
编辑daemonset.yaml文件
[root@k8s2 pod]# vim daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
app: zabbix-agent
spec:
selector:
matchLabels:
app: zabbix-agent
template:
metadata:
labels:
app: zabbix-agent
spec:
tolerations:#容忍master上的污点,能够在master上运行
- operator: Exists
effect: NoSchedule
containers:
- name: zabbix-agent
image: zabbix-agent
执行yaml
[root@k8s2 pod]# kubectl apply -f daemonset.yaml
查看每个节点上分别有一个pod
[root@k8s2 pod]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-example-95gtq 1/1 Running 0 55s 10.244.2.55 k8s4 <none> <none>
daemonset-example-nx6zd 1/1 Running 0 53s 10.244.1.57 k8s3 <none> <none>
daemonset-example-vp44c 1/1 Running 0 59s 10.244.0.9 k8s2 <none> <none>
去掉pod
[root@k8s2 pod]# kubectl delete -f daemonset.yaml
StatefulSet控制器
保证 Pod 的所有副本的名称在其整个生命周期中是不变的。一般的,当 Pod 因为故障需要删除并重新启动时,它的名称是会发生变化的。StatefuleSet 还可以保证 Pod 的副本按照固定的顺序启动、更新或者删除。后面细讲
Job控制器
特殊的任务控制器,执行批处理任务,仅执行一次任务,保证任务的一个或多个Pod成功结束。用于 App 运行结束就可以立即删除 Pod 的场景。
Job 配置示例。负责计算 π 到小数点后 2000 位,并将结果打印出来。
[root@k8s2 pod]# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
parallelism: 2 #并行2个
completions: 6 #总共6个任务
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never #执行完推出
backoffLimit: 4 #在容器内尝试4次,,超过了就不重启了
用命令来运行此示例:
[root@k8s2 pod]# kubectl apply -f job.yaml
拉起pod并查看状态
[root@k8s2 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pi-6kpgz 0/1 Completed 0 28s
pi-c7lg5 0/1 Completed 0 39s
pi-dxcmx 0/1 Completed 0 39s
pi-h4cx6 0/1 Completed 0 18s
pi-pcxn8 0/1 Completed 0 28s
pi-zxkxb 0/1 Completed 0 18s
在pod日志里查看结果
删除pod
[root@k8s2 pod]# kubectl delete -f job.yaml
CronJob控制器
Cron Job 创建基于时间调度的 Jobs
CronJob 用于执行排期操作,例如备份、生成报告等。 一个 CronJob 对象就像 Unix 系统上的 crontab(cron table)文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。
编写cronjob.yaml文件
[root@k8s2 pod]# vim cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *" #每分钟
jobTemplate: #周期化创建job控制器,再用job控制器创建job
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster #定时输出这句话
restartPolicy: OnFailure
运行pod
[root@k8s2 pod]# kubectl apply -f cronjob.yaml
每分钟创建一个pod,可看见pod创建时间相差60s
[root@k8s2 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
hello-27891460-cx7wm 0/1 Completed 0 2m35s
hello-27891461-77m5s 0/1 Completed 0 95s
hello-27891462-vq8dq 0/1 Completed 0 35s
查看日志输出,每分钟打印出当前时间和问候消息
[root@k8s2 pod]# kubectl logs hello-27891460-cx7wm
Thu Jan 12 01:40:01 UTC 2023
Hello from the Kubernetes cluster
删除pod
[root@k8s2 pod]# kubectl delete -f cronjob.yaml
HPA
根据资源利用率自动调整service中Pod数量,实现Pod水平自动缩放。后面细讲