工作负载型控制器是什么
工作负载控制器的概念
工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。
常用的工作负载控制器
Deployment :无状态应用部署
StatefulSet :有状态应用部署
DaemonSet :确保所有Node运行同一个Pod
Job :一次性任务
Cronjob :定时任务
控制器的作用
管理Pod对象
使用标签与Pod关联
控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等
项目生命周期介绍
实际的项目部署流程如下,接下来的内容,会按照应用程序部署、滚动升级、回滚、项目下线的顺序依次介绍一个项目在K8S集群中的整个生命周期。而本次文章主要是针对无状态应用进行部署和生命周期管理,因此实际上介绍的是Deployment控制器在项目生命周期管理中的具体使用方式。
项目生命周期介绍
实际的项目部署流程如下,接下来的内容,会按照应用程序部署、滚动升级、回滚、项目下线的顺序依次介绍一个项目在K8S集群中的整个生命周期。而本次文章主要是针对无状态应用进行部署和生命周期管理,因此实际上介绍的是Deployment控制器在项目生命周期管理中的具体使用方式。
Deployments(无状态应用部署)
Deployments介绍
一个 Deployment 控制器为 Pods 和 ReplicaSets 提供声明式的更新能力。
你负责描述 Deployment 中的 目标状态,而 Deployment 控制器以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
说明: 不要管理 Deployment 所拥有的 ReplicaSet 。 如果存在下面未覆盖的使用场景,请考虑在 Kubernetes 仓库中提出 Issue。
基本写法
[root@master manifest]# cat busybox.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: xx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: b4
image: busybox
command: ["/bin/sh","-c","sleep 9000"]
[root@master manifest]# kubectl apply -f busybox.yaml
deployment.apps/xx created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
xx-758696cd47-2k2wv 1/1 Running 0 13s
xx-758696cd47-q2tqk 1/1 Running 0 13s
xx-758696cd47-wjtjr 1/1 Running 0 13s
Deployment实现滚动升级
[root@master manifest]# vim apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
strategy:
rollingUpdate:
maxSurge: 20%
maxUnavailable: 20%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: hyhxy0206/apache:v1
imagePullPolicy: IfNotPresent
# maxSurge: 20% //更新时,启动的Pod数量,占总数量的1/5
# maxUnavailable: 20% //更新时,关闭的Pod数量,占总数量的1/5
# replicas: 4 副本数量
[root@master manifest]# kubectl apply -f apache.yaml
deployment.apps/web created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-64bbf59bf8-8c8q2 1/1 Running 0 11s
web-64bbf59bf8-ll6tg 1/1 Running 0 11s
web-64bbf59bf8-qk5j7 1/1 Running 0 11s
web-64bbf59bf8-vkrr6 1/1 Running 0 11s
//修改vim apache.yaml v2版本号直接升级
[root@master manifest]# kubectl apply -f apache.yaml
deployment.apps/web configured
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-64bbf59bf8-8c8q2 1/1 Running 0 77s
web-64bbf59bf8-ll6tg 1/1 Terminating 0 77s
web-64bbf59bf8-qk5j7 1/1 Running 0 77s
web-64bbf59bf8-vkrr6 1/1 Terminating 0 77s
web-6d5489d59f-j42tq 1/1 Running 0 6s
web-6d5489d59f-ppgn9 1/1 Running 0 3s
web-6d5489d59f-r4kjm 0/1 ContainerCreating 0 1s
Deployment调控
[root@master manifest]# vim apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
revisionHistoryLimit: 4 //版本数
strategy:
rollingUpdate:
maxSurge: 20%
maxUnavailable: 20%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: hyhxy0206/apache:v1
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl apply -f apache.yaml
deployment.apps/web created
[root@master manifest]# vim apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
revisionHistoryLimit: 4
strategy:
rollingUpdate:
maxSurge: 20%
maxUnavailable: 20%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: hyhxy0206/apache:v2 //版本号已修改
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl apply -f apache.yaml
deployment.apps/web configured
//查看历史版本
[root@master manifest]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# revisionHistoryLimit:4,我们只有2个版本号
//回滚版本 1消失,说明已经变动
[root@master manifest]# kubectl rollout undo deployment/web
deployment.apps/web rolled back
[root@master manifest]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
2 <none>
3 <none>
//回滚到指定版本2消失,说明已经变动
[root@master manifest]# kubectl rollout undo deploy/web --to-revision 2
deployment.apps/web rolled back
[root@master manifest]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
3 <none>
4 <none>
Replicaset(副本控制器)
ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。
ReplicaSet 的工作原理
RepicaSet 是通过一组字段来定义的,包括一个用来识别可获得的 Pod 的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新 Pod 以满足副本个数条件时要使用的 Pod 模板等等。 每个 ReplicaSet 都通过根据需要创建和 删除 Pod 以使得副本个数达到期望值, 进而实现其存在价值。当 ReplicaSet 需要创建新的 Pod 时,会使用所提供的 Pod 模板。
ReplicaSet 通过 Pod 上的 metadata.ownerReferences 字段连接到附属 Pod,该字段给出当前对象的属主资源。 ReplicaSet 所获得的 Pod 都在其 ownerReferences 字段中包含了属主 ReplicaSet 的标识信息。正是通过这一连接,ReplicaSet 知道它所维护的 Pod 集合的状态, 并据此计划其操作行为。
ReplicaSet 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个 控制器,且其匹配到 某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。
何时使用 ReplicaSet
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非 你需要自定义更新业务流程或根本不需要更新。
这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义你的应用。
//Deployment每次发布都会创建一个RS作为记录,用于实现回滚
[root@master manifest]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-64bbf59bf8 4 4 4 9m57s
web-6d5489d59f 0 0 0 9m37s
[root@master manifest]# kubectl rollout history deployment web
deployment.apps/web
REVISION CHANGE-CAUSE
4 <none>
5 <none>
//更改版本号
[root@master manifest]# vim apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 4
revisionHistoryLimit: 4
strategy:
rollingUpdate:
maxSurge: 20%
maxUnavailable: 20%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: hyhxy0206/apache:v1
imagePullPolicy: IfNotPresent
[root@master manifest]# kubectl apply -f apache.yaml
deployment.apps/web configured
[root@master manifest]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-64bbf59bf8 4 4 4 10m
web-6d5489d59f 0 0 0 10m
DaemonSet(确保所以Node运行同一个pod)
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
[root@master manifest]# vim filebeat.yaml
---
apiVersion: apps/v1
kind: 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 manifest]# kubectl apply -f filebeat.yaml
daemonset.apps/filebeat created
[root@master manifest]# kubectl get pods -n kube-system -o wide | grep filebeat
filebeat-bcxq4 1/1 Running 0 7m58s 10.244.1.23 node2.example.com <none> <none>
filebeat-zzlfl 1/1 Running 0 7m58s 10.244.1.70 node1.example.com <none> <none>
Jobs(一次性服务)
Job 会创建一个或者多个 Pods,并确保指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。
一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
你也可以使用 Job 以并行的方式运行多个 Pod。
[root@master ~]# vi 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.23 node01 <none> <none>
CronJob(定时任务)
Cron Job 创建基于时间调度的 Jobs。
一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。
注意:
所有 CronJob 的
schedule:
时间都是基于 kube-controller-manager. 的时区。如果你的控制平面在 Pod 或是裸容器中运行了 kube-controller-manager, 那么为该容器所设置的时区将会决定 Cron Job 的控制器所使用的时区。
为 CronJob 资源创建清单时,请确保所提供的名称是一个合法的 DNS 子域名. 名称不能超过 52 个字符。 这是因为 CronJob 控制器将自动在提供的 Job 名称后附加 11 个字符,并且存在一个限制, 即 Job 名称的最大长度不能超过 63 个字符。
[root@master manifest]# vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" //分时日月周
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date;echo Hello aliang
restartPolicy: OnFailure
[root@master manifest]# kubectl apply -f cronjob.yaml
cronjob.batch/hello created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-lrgcs 0/1 ContainerCreating 0 10m
//等待一分钟后
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-1640363760-gvktn 0/1 ContainerCreating 0 25s
pi-lrgcs 0/1 ContainerCreating 0 11m