17. Pod 自动管理——DeamonSet 和 Job
本章讲解知识点
- DeamonSet
- Job
- Batch Job
<br>
1. DeamonSet
1.1. 前言
我们来假设一种场景,我们集群有很多个工作节点,我们需要在每一个工作节点上都运行一个监控程序,用以收集节点状态、日志等。
那么如果使用 Deployment、StatefulSet,我们就得设置各自标签、污点来保证每一个副本相互隔离开,并正确调度到各个工作节点,那样真的是太麻烦了。有没有一种更为简单的方法呢?当然有,那就是 DeamonSet。
1.2. 概念
DaemonSet 是 Kubernetes 中一种常见的控制器类型,它用于确保集群中的每个节点都运行一个 Pod 的副本。每个节点上运行的 Pod 的规范都是相同的,这与 ReplicaSet 等其他控制器类型不同。
DaemonSet 通常用于实现各种任务,例如运行日志收集器、网络代理、监视器、数据收集器等。在这些情况下,需要在每个节点上运行一个实例来收集或处理节点特定的数据。例如,我们可以使用 Prometheus Node Exporter,它是一个 Prometheus 插件,可以在节点上收集各种系统信息,并将其提供给 Prometheus 进行监控和分析。我们可以创建一个 DaemonSet 对象,描述 Prometheus Node Exporter 容器的运行方式,并将其部署到 Kubernetes 集群中的所有节点上。这样,我们就可以轻松地收集整个集群中所有节点的系统信息,以帮助我们更好地了解和监控集群的健康状况。
假设有一个用于收集应用程序日志的容器。如果我们使用 Deployment 或 ReplicaSet 来管理此容器,则可能会在同一节点上运行多个容器实例,这些实例可能会竞争有限的节点资源,并且在某些节点上可能完全没有容器实例。相比之下,如果我们使用 DaemonSet 来管理此容器,则每个节点上只会运行一个实例,从而保证资源利用率和数据完整性。
在创建 DaemonSet 时,可以指定要运行的 Pod 的规范,以及选择要运行 Pod 的节点标签。当新的节点加入到集群中时,Kubernetes 会自动在该节点上创建一个新的 Pod 实例,并确保每个节点上都有一个运行的 Pod 实例。如果节点被删除,则与该节点相关联的 Pod 也会被删除。
1.3. 实验
我们来创建一个 DeamonSet 定义文件,命名为 my-first-deamonset.yaml:
apiVersion: apps/v1 kind: DaemonSet metadata: name: my-first-daemonset spec: selector: matchLabels: app: my-first-daemonset template: metadata: labels: app: my-first-daemonset spec: containers: - name: my-first-container image: nginx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80
创建应用:
[root@master mtuser]# kubectl create -f my-first-deamonset.yaml daemonset.apps/my-first-daemonset created [root@master mtuser]# kubectl get pod NAME READY STATUS RESTARTS AGE my-first-daemonset-kg2z2 1/1 Running 0 46s [root@master mtuser]# [root@master mtuser]# kubectl get ds NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE my-first-daemonset 1 1 1 1 1 <none> 51s
可以看到我们在工作节点上创建了一个 Pod,因为我们只有一个工作节点。
同时创建了一个 ds 控制器,用于控制每一个节点上 Pod 的状态。
1.4. DeamonSet 的更新和回滚
DeamonSet 的更新有一点需要注意,更新策略只有 OnDelete 一种,从 Kubernetes 1.6 之后版本,OnDelete 为 DeamonSet 默认的更新策略,即更新时,需要手动删除 Pod。当然了,实际生产中,调接口去删除。
1.5. DeamonSet 原理
那么,DaemonSet 又是如何保证每个 Node 上有且只有一个被管理的 Pod 呢?
显然,这是一个典型的“控制器模型”能够处理的问题。
DaemonSet Controller,首先从 Etcd 里获取所有的 Node 列表,然后遍历所有的 Node。这时,它就可以很容易地去检查,当前这个 Node 上是不是有一个携带了 app=my-first-daemonset
标签的 Pod 在运行。
而检查的结果,可能有这么三种情况:
- 没有这种 Pod,那么就意味着要在这个 Node 上创建这样一个 Pod;
- 有这种 Pod,但是数量大于 1,那就说明要把多余的 Pod 从这个 Node 上删除掉;
- 正好只有一个这种 Pod,那说明这个节点是正常的。
其中,删除节点(Node)上多余的 Pod 非常简单,直接调用 Kubernetes API 就可以了。
<br>
2. Job
2.1. 前言
我们来假设一个场景,有些任务在执行时,就是一个一次性任务,不像 Deployment 服务一直作为服务端运行。那应该如何处理呢?
当然也有,Kubernetes 对应 Job 来处理。
2.2. Job 概念
Kubernetes Job 是 Kubernetes API 中的一种对象,它用于在 Kubernetes 集群上创建一个或多个并行运行的任务。Job 确保任务成功地运行一次(或指定数量)。
当一个 Job 被创建时,它会在 Kubernetes 集群上创建一组 Pod。这些 Pod 在完成任务后将自动被删除。当一个 Pod 失败时,Job 控制器会自动重新创建一个 Pod,以确保指定数量的任务成功地运行。如果一个任务已经成功地运行了指定的次数,Job 控制器将不再创建新的 Pod。
Job 通常用于批处理任务或定时任务,如数据处理、备份、清理任务等。Kubernetes 通过 Job 控制器来管理这些任务,使得任务的执行能够被有效地监控和管理。
Kubernetes 中的 Job 常见有两种类型:
- Non-parallel Job:这种类型的 Job 只会启动一个 Pod,直到该 Pod 成功完成后,Job 就会结束。如果该 Pod 失败了,Job 将会重启该 Pod 直到它成功完成。
- Parallel Job:这种类型的 Job 会并行启动多个 Pod,每个 Pod 执行相同的任务,但它们之间没有顺序关系,这些 Pod 可能会同时运行。该 Job 的完成情况将根据 Pod 的完成情况进行计算,如果有足够的 Pod 成功完成了任务,Job 就会被视为成功完成,由参数 .spec.completions 控制,此参数为正数,当正常结束的 Pod 数量达至此参数设置的值,Job 结束。
2.3. 实验
我们来创建一个简单的 Job 任务:
apiVersion: batch/v1 kind: Job metadata: name: hello-world spec: template: spec: containers: - name: hello-world image: redis:latest command: ['sh', '-c', 'echo "Hello World"'] restartPolicy: Never backoffLimit: 4
该 YAML 文件定义了一个名为 "hello-world" 的 Job 对象,使用了 Kubernetes 中的 batch/v1 API
版本。在 spec 字段中,定义了 Job 的配置信息。在 template 字段中,指定了要运行的 Pod 配置信息,包括容器名为 "hello-world"、使用的镜像为 redis:latest
,以及要在容器中运行的命令为 "echo "Hello World""。restartPolicy 字段设置为 Never,这意味着容器在退出后不会被自动重启。backoffLimit 字段设置为 4,指定了在 Job 运行失败时重试的次数。
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专刊适合于立志转行云计算的小白,有一定的编程、操作系统、计算机网络、数据结构、算法基础。 本专刊同时也适合于面向云计算(Docker + Kubernetes)求职的从业者。 本专刊囊括了云计算、VMWare、Docker、Kubernetes、Containerd等一系列知识点的讲解,并且最后总