工作负载型控制器是什么

工作负载控制器的概念

工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。

K8S工作负载创建多个容器 k8s工作负载形式_docker

常用的工作负载控制器

Deployment :无状态应用部署
StatefulSet :有状态应用部署
DaemonSet :确保所有Node运行同一个Pod
Job :一次性任务
Cronjob :定时任务

控制器的作用

管理Pod对象
使用标签与Pod关联
控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等

项目生命周期介绍

实际的项目部署流程如下,接下来的内容,会按照应用程序部署、滚动升级、回滚、项目下线的顺序依次介绍一个项目在K8S集群中的整个生命周期。而本次文章主要是针对无状态应用进行部署和生命周期管理,因此实际上介绍的是Deployment控制器在项目生命周期管理中的具体使用方式。

项目生命周期介绍

实际的项目部署流程如下,接下来的内容,会按照应用程序部署、滚动升级、回滚、项目下线的顺序依次介绍一个项目在K8S集群中的整个生命周期。而本次文章主要是针对无状态应用进行部署和生命周期管理,因此实际上介绍的是Deployment控制器在项目生命周期管理中的具体使用方式。

K8S工作负载创建多个容器 k8s工作负载形式_运维_02

Deployments(无状态应用部署)

Deployments介绍

一个 Deployment 控制器为 PodsReplicaSets 提供声明式的更新能力。

你负责描述 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。

注意:

所有 CronJobschedule: 时间都是基于 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