文章目录
1 工作负载控制器是什么
工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。
无论你的负载是单一组件还是由多个一同工作的组件构成,在Kubernetes中你可以在一组Pods中运行它。在Kuberneres中,pod代表的是集群上处于运行状态的一组容器。
Kubernetes Pods有确定的生命周期。例如,当某Pod在你的集群中运行时,Pod运行所在的节点出现致命错误时,所有该节点上的Pods都会失败。Kubernetes将这类失败视为最终状态:即使该节点后来恢复正常运行,你也需要创建新的Pod来恢复应用。
不过,为了让用户的日子略微好过一点,你并不需要直接管理每个Pod。相反,你可以使用负载资源来替你管理一组Pods。这些资源配置控制器来确保合适类型的、处于运行状态的Pod个数是正确的,与你所指定的状态相一致。
1.2 常用工作负载控制器
- Deployment:无状态应用部署
- StatefulSet:有状态应用部署
- DaemonSet:确保所有Node运行同一个Pod
- Job:一次性任务
- Cronjob:定时任务
作用
- 管理Pod对象
- 使用标签与Pod关联
- 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等
2 Deployment
一个Deployment为Pods和ReplicaSets提供声明式的更新能力,基于ReplicaSet之上,可为Pod和ReplicaSet资源提供声明式更新
- 事件和状态查看:可以查看Deployment对象升级的详细进度和状态
- 回滚:当升级操作完成后发现问题时,支持将应用返回到指定的历史版本中
- 版本记录:对Deployment 对象的每一次操作都予以保存
- 暂停和启动:每一次升级,都可以随时暂停和启动
- 多种自动更新方案:Recreate-重建更新、RollingUpdate-滚动更新
2.1 Deployment的更新策略
RollingUpdate 策略:旧控制器的Pod数量不断减少,同时新控制器的Pod不断增加
- maxSurge:滚动更新过程中最大Pod副本数,确保在更新时启动的Pod数量比期望(replicsa)Pod数量最大多出25%
- maxUnavailable:滚动更新过程中最大不可用Pod副本数,确保在更新时最大25%Pod数量不可用,即确保75%Pod数量是可用状态
spec:
replicas: 3
revisionHistoryLimit: 10 # 历史版本保存数量,保存数量基于镜像数量
selector:
matchLabels:
app:web
strategy:
rollingUpdate:
maxSurge: 25% //更新时,启动的Pod数量,占总数量的1/4
maxUnavailable: 25% //更新时,关闭的Pod数量,占总数量的1/4
type: RollingUpdate
Deployment滚动升级
[root@master ~]# vi test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: zhaojie10/httpd:v0.1
imagePullPolicy: IfNotPresent
//先运行一个v1版本的pods
[root@master ~]# kubectl delete -f test.yaml
deployment.apps "web" deleted
[root@master ~]# kubectl get pods //此时都是v1版本
NAME READY STATUS RESTARTS AGE
web-66dc445c66-5sd42 1/1 Running 0 50s
web-66dc445c66-8fjld 1/1 Running 0 50s
web-66dc445c66-8wdc9 1/1 Running 0 50s
web-66dc445c66-fc9lf 1/1 Running 0 50s
// 更改版本镜像后应用部署
[root@master ~]# kubectl apply -f test.yaml
deployment.apps/web configured
[root@master ~]# kubectl get pods // 发现有五个正在创建或运行的,一个正在关闭,五个运行,其中包括了四个之前就创建过的
NAME READY STATUS RESTARTS AGE
web-66dc445c66-8gkcv 0/1 ContainerCreating 0 1s
web-66dc445c66-gv6gx 0/1 ContainerCreating 0 1s
web-689dbd69c9-l6t69 1/1 Running 0 2m25s
web-689dbd69c9-p8xtq 1/1 Running 0 2m25s
web-689dbd69c9-prdls 1/1 Running 0 2m23s
# 等待更新完毕
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-689dbd69c9-5mkm6 1/1 Running 0 13m
web-689dbd69c9-g4px6 1/1 Running 0 13m
web-689dbd69c9-hvh86 1/1 Running 0 13m
web-689dbd69c9-jc57n 1/1 Running 0 13m
2.2 版本记录
kubectl rollout history deployment/web //查看历史发布版本
kubectl rollout undo deployment/web //回滚上一个版本
kubectl rollout undo deployment/web --to-revision=2 //回滚历史指定版本
3 ReplicaSet
ReplicaSet的目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此,它通常用来保证给定数量的、完全相同的Pod的可用性。
3.1 ReplicaSet的工作原理
RepicaSet是通过一组字段来定义的,包括一个识别可获得的Pod的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新Pod以满足副本个数条件时要使用的Pod模板等等。每个ReplicaSet都通过根据需要创建新的Pod时,会使用所提供的Pod模板。
ReplicaSet通过Pod上的metadata.ownerReferences字段连接到附属Pod,该字段给出当前对象的属主资源。ReplicaSet所获得的Pod都在其ownerReferences字段中包含了属主ReplicaSet的标识信息。正是通过这一连接,ReplicaSet 知道它所维护的 Pod 集合的状态, 并据此计划其操作行为。
ReplicaSet 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个控制器,且其匹配到 某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非 你需要自定义更新业务流程或根本不需要更新。
[root@master ~]# kubectl get rs //查看RS记录
NAME DESIRED CURRENT READY AGE
web-66dc445c66 0 0 0 32s
web-689dbd69c9 4 4 3 3s
[root@master ~]# kubectl rollout history deployment web 版本对应RS记录
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@master ~]# vi test.yaml //变更版本
......
containers:
- name: httpd
image: zhaojie10/httpd:v0.2 //修改镜像版本
imagePullPolicy: IfNotPresent
......
[root@master ~]# kubectl apply -f test.yaml
deployment.apps/web configured
# 发现每次版本变更时对应一个RS,上一个版本被干掉了,新的版本会生成新的Rs
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-66dc445c66 4 4 4 2m7s
web-689dbd69c9 0 0 0 98s
4 DaemonSet
DaemonSet控制器确保集群中的每一个Node只运行一个特定的Pod副本,实现系统级的后台任务,也具有标签选择器。也可以指定部分满足条件的Node运行一个Pod副本,比如监控具有ssd存储的Node节点
DaemonSet 的用法
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
[root@master ~]# kubectl get pods
No resources found in default namespace.
[root@master ~]# cat test.yaml
---
apiVersion: apps/v1
kind: DaemonSet // 指定类型为DaemonSet
metadata:
name: filebeat
namespace: kube-system //指定系统命名空间
spec:
selector:
matchLabels:
name: filebeat
template:
metadata:
labels:
name: filebeat
spec:
containers: // 记录日志的镜像
- name: log
image: elastic/filebeat:7.16.2
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f test.yaml
daemonset.apps/filebeat created
[root@master ~]# kubectl get pods -n kube-system -o wide | grep filebeat
filebeat-crlnx 1/1 Running 0 8m1s 10.146.24.198 node2 <none> <none>
filebeat-hplmj 1/1 Running 0 8m1s 10.146.24.133 node1 <none> <none>
5 Job控制器
Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行
Job控制器用于Pod对象运行一次性任务,容器中的进程在正常运行结束后不会对其进行重启,而是将Pod对象置于"Completed"(完成)状态,若容器中的进程因错误而终止,则需要按照重启策略配置确定是否重启,未运行完成的Pod对象因其所在的节点故障而意外终止后会被调度
[root@master ~]# cat job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4 // 重试次数
[root@master ~]# kubectl apply -f job.yaml //创建
job.batch/pi created
[root@master ~]# kubectl get pods -o wide //此时为正在创建状态
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pi-dtgj6 0/1 ContainerCreating 0 8s <none> node01 <none> <none>
[root@master ~]# kubectl get pods -o wide //当进程运行完成后为完成状态,并不在运行了
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pi-dtgj6 0/1 Completed 0 5m7s 10.244.1.65 node01 <none> <none>
6 CronJob
CronJob控制器执行周期性任务作业,控制其运行的时间点及重复运行的方式,类似于Linux操作系统的周期性任务作业计划的方式控制其运行的时间点和重复运行的方式
CronJob 用于执行周期性的动作,例如备份、报告生成等。 这些任务中的每一个都应该配置为周期性重复的(例如:每天/每周/每月一次); 你可以定义任务开始执行的时间间隔
6.1 CronJob的配置
- obTemplate:Job控制器模板。
- schedule:Cron格式的作业调度运行的时间点。
- concurrencyPolicy:并发执行策略,用于定义前一次作业尚未完成时如何执行下一此任务。默认是Allow,即允许前后Job,甚至是属于同一个CrontJob的更多Job同时运行。如果设置为Forbid则禁止前后两个Job同时运行,如果前一个尚未结束,后一个不会启动(跳过),如果设置为Replace,则后一个Job会替代前一个Job,即终止前一个,启动后一个。
- failedJobHistoryLimit:为失败的任务执行保留的历史记录数,默认是1。
- successfulJobsHistoryLimit:为成功的任务执行保留的历史记录数,默认是3。
- startingDeadlineSeconds:因各种原因缺乏执行作业的时间点所导致的启动作业错误的超时时长,会被记入错误历史记录
- suspend:是否挂起后续的任务执行,默认是false。
[root@master ~]# vi cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" //每分钟进行一次
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date;echo Hello
restartPolicy: OnFailure
[root@master ~]# kubectl apply -f cronjob.yaml
cronjob.batch/hello created
[root@master ~]# kubectl get pods //完成,等待任务执行
NAME READY STATUS RESTARTS AGE
pi-dtgj6 0/1 Completed 0 9m42s
[root@master ~]# date //查看时间
2021年 12月 24日 星期五 20:42:22 CST
[root@master ~]# kubectl get pods //此时已经有一个任务了
NAME READY STATUS RESTARTS AGE
hello-27339037-qnvvx 0/1 ContainerCreating 0 14s
pi-dtgj6 0/1 Completed 0 10m
//过一会再查看
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27339037-qnvvx 0/1 Completed 0 63s
hello-27339038-9k2mj 0/1 ContainerCreating 0 3s
pi-dtgj6 0/1 Completed 0 11m
//查看日志输出
[root@master ]# kubectl logs hello-hello-27339037-qnvvx
Fri Dec 24 21:05:15 UTC 2021
Hello