Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来

Python系列文章目录

PyTorch系列文章目录

机器学习系列文章目录

深度学习系列文章目录

Java系列文章目录

JavaScript系列文章目录

Python系列文章目录

Go语言系列文章目录

Docker系列文章目录

01-【Docker-Day 1】告别部署噩梦:为什么说 Docker 是每个开发者的必备技能?
02-【Docker-Day 2】从零开始:手把手教你在 Windows、macOS 和 Linux 上安装 Docker
03-【Docker-Day 3】深入浅出:彻底搞懂 Docker 的三大核心基石——镜像、容器与仓库
04-【Docker-Day 4】从创建到删除:一文精通 Docker 容器核心操作命令
05-【Docker-Day 5】玩转 Docker 镜像:search, pull, tag, rmi 四大金刚命令详解
06-【Docker-Day 6】从零到一:精通 Dockerfile 核心指令 (FROM, WORKDIR, COPY, RUN)
07-【Docker-Day 7】揭秘 Dockerfile 启动指令:CMD、ENTRYPOINT、ENV、ARG 与 EXPOSE 详解
08-【Docker-Day 8】高手进阶:构建更小、更快、更安全的 Docker 镜像
09-【Docker-Day 9】实战终极指南:手把手教你将 Node.js 应用容器化
10-【Docker-Day 10】容器的“持久化”记忆:深入解析 Docker 数据卷 (Volume)
11-【Docker-Day 11】Docker 绑定挂载 (Bind Mount) 实战:本地代码如何与容器实时同步?
12-【Docker-Day 12】揭秘容器网络:深入理解 Docker Bridge 模式与端口映射
13-【Docker-Day 13】超越默认Bridge:精通Docker Host、None与自定义网络模式
14-【Docker-Day 14】Docker Compose深度解析
15-【Docker-Day 15】一键部署 WordPress!Docker Compose 实战终极指南
16-【Docker-Day 16】告别单机时代:为什么 Docker Compose 不够用,而你需要 Kubernetes?
17-【Docker-Day 17】K8s 架构全解析:深入理解 Kubernetes 的大脑 (Master) 与四肢 (Node)
18-【Docker-Day 18】告别选择困难症:一文掌握 Minikube、kind、k3d,轻松搭建你的第一个 K8s 集群
19-【Docker-Day 19】万物皆 YAML:掌握 Kubernetes 声明式 API 的艺术
20-【Docker-Day 20】揭秘 Kubernetes 的原子单位:深入理解 Pod
21-【Docker-Day 21】Pod的守护神:ReplicaSet与ReplicationController,轻松实现应用高可用
22-【K8s-Day 22】深入解析 Kubernetes Deployment:现代应用部署的基石与滚动更新的艺术
23-【K8s-Day 23】从 Pod 的“失联”到 Service 的“牵线”:深入理解 ClusterIP 核心原理
24-【Docker-Day 24】K8s网络解密:深入NodePort与LoadBalancer,让你的应用走出集群
25-【Docker-Day 25】深入理解 Kubernetes Namespace:实现多租户与环境隔离的利器
26-【Docker-Day 26】K8s实战演练:从零开始部署一个完整的前后端分离Web应用
27-【K8s-Day 27】应用的“体检医生”:深入解析 Kubernetes 健康检查探针 (Probe)
28-【Docker-Day 28】K8s 核心配置管理:解密 ConfigMap,告别硬编码!
29-【Docker-Day 29】K8s 安全第一课:揭秘敏感信息管理器 Secret
30-【Docker-Day 30】解密 K8s 的“硬盘”:深入理解 PersistentVolume (PV) 与 PersistentVolumeClaim (PVC)
31-【Docker-Day 31】告别手动创建 PV!一文搞懂 Kubernetes StorageClass 工作原理与实战
32-【K8s-Day 32】StatefulSet 深度解析:为你的数据库和有状态应用保驾护航
33-【Docker-Day 33】掌握 K8s 任务调度:DaemonSet、Job、CronJob 实战指南



摘要

在 Kubernetes 的世界里,Deployment 是我们最熟悉的朋友,它负责管理无状态应用的部署、扩缩容和滚动更新。然而,并非所有任务都是这种“永远在线”的服务模式。有些任务需要在每个节点上安插一个“哨兵”,有些任务只需要执行一次便功成身退,还有些任务则需要像闹钟一样定时响起。为了应对这些特殊的场景,Kubernetes 提供了三位“特种兵”:DaemonSetJobCronJob。本文将深入剖析这三种控制器的工作原理、核心应用场景,并通过丰富的实战案例,带你彻底掌握它们,让你的 K8s 集群任务调度能力再上一个台阶。

一、超越 Deployment:为什么需要特殊的 Pod 控制器?

在之前的文章中,我们已经熟练掌握了 Deployment,它非常适合部署像 Web 服务器、API 网关这类需要长期运行、并且可以被水平扩展的无状态服务。Deployment 的核心思想是维持期望数量的副本(Replica),并将它们均匀地调度到集群的各个节点上,不关心具体落在哪个节点。

但是,请思考以下几个常见需求:

  1. 节点级监控与日志收集:我希望在集群的每一个工作节点上都运行一个日志收集代理(如 Fluentd)或一个监控代理(如 Prometheus Node Exporter),以便收集该节点的系统日志和性能指标。如果使用 Deployment,我们无法保证每个节点都恰好有一个 Pod 实例。
  2. 一次性批处理任务:我需要对数据库进行一次性数据迁移,或者执行一个复杂的计算任务。这个任务执行完毕后就应该结束,不需要一直占用资源。Deployment 会在 Pod 结束后立即尝试重启它,这显然不符合我们的需求。
  3. 周期性定时任务:我需要每天凌晨 2 点对数据库进行备份,或者每小时清理一次临时文件。这就像 Linux 系统中的 crontab 一样,需要定时触发。Deployment 同样无法满足这种周期性执行的需求。

为了优雅地解决这些问题,Kubernetes 引入了专门的工作负载资源:

  • DaemonSet:节点守护者,确保每个(或部分)节点上都运行一个 Pod 副本。
  • Job:一次性任务执行者,确保一个或多个 Pod 成功运行到结束。
  • CronJob:定时任务调度器,基于 Job 并增加了定时触发的能力。

接下来,我们将逐一揭开它们神秘的面纱。

二、节点“守护神”:DaemonSet 详解

DaemonSet 就像是古代城池中派驻到每个城门(Node)的守护卫兵,确保每个关键位置都有人站岗。

2.1 什么是 DaemonSet?

DaemonSet(守护进程集)是一种 Kubernetes 控制器,它确保全部(或部分)节点上都运行一个 Pod 的副本。当有节点加入集群时,DaemonSet 会为它们新增一个 Pod;当有节点从集群中移除时,这些 Pod 也会被相应地回收。

核心目标:在指定的每个 Node 上都运行一个且仅一个 Pod 实例。

2.2 DaemonSet 的核心工作原理

DaemonSet 控制器会监听集群中的节点。对于每一个满足其调度要求的节点,它会确保该节点上存在一个由它管理的 Pod。它不使用 ReplicaSet,而是直接管理 Pod。

其工作流程可以简化为下图:

graph TD
    subgraph Kubernetes Cluster
        Master[Master Node]
        Node1[Worker Node 1]
        Node2[Worker Node 2]
        Node3[Worker Node 3]
    end

    subgraph Control Plane
        DSC[DaemonSet Controller]
    end

    DS_Def[DaemonSet YAML Definition] -->|kubectl apply| Master

    Master -- informs --> DSC
    DSC -- watches --> Node1
    DSC -- watches --> Node2
    DSC -- watches --> Node3

    subgraph Node1
        Pod_A[Pod A]
    end
    subgraph Node2
        Pod_B[Pod B]
    end
    subgraph Node3
        Pod_C[Pod C]
    end
    
    DSC -- Creates --> Pod_A
    DSC -- Creates --> Pod_B
    DSC -- Creates --> Pod_C

    NewNode[New Node 4 Added] -->|joins| Master
    Master -- informs --> DSC
    DSC -- watches --> NewNode
    subgraph NewNode
       Pod_D[Pod D]
    end
    DSC -- Creates --> Pod_D

    style DS_Def fill:#f9f,stroke:#333,stroke-width:2px
    style DSC fill:#ccf,stroke:#333,stroke-width:2px

2.3 DaemonSet 的典型应用场景

DaemonSet 的应用场景非常广泛,几乎所有需要与节点底层交互的系统级应用都离不开它:

  • 日志收集:在每个节点上运行一个日志收集代理,如 FluentdFilebeatLogstash,用于收集该节点上所有容器的日志。
  • 节点监控:在每个节点上运行一个监控代理,如 Prometheus Node ExporterDatadog AgentZabbix Agent,用于暴露节点的硬件和操作系统指标。
  • 网络插件:许多 CNI(容器网络接口)插件,如 CalicoFlannel 等,会以 DaemonSet 的形式在每个节点上运行一个代理,负责该节点的网络配置和管理。
  • 存储插件:分布式存储系统(如 CephGlusterFS)的客户端或代理也常以 DaemonSet 形式部署,为节点提供存储服务。

2.4 实战:部署一个节点监控 Pod

让我们以部署 Prometheus Node Exporter 为例,它能暴露每个节点的硬件和 OS 指标。

(1) 编写 node-exporter-ds.yaml
# node-exporter-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  labels:
    app: node-exporter
spec:
  # 1. Selector: 用于关联 DaemonSet 和它管理的 Pods
  selector:
    matchLabels:
      app: node-exporter
  # 2. Template: Pod 的定义模板
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.1
        ports:
        - containerPort: 9100
          protocol: TCP
      # 3. Host Network: 允许 Pod 直接使用宿主机的网络,方便外部访问
      hostNetwork: true
      # 4. Host PID: 允许 Pod 访问宿主机的进程信息
      hostPID: true
      # 5. Tolerations: 容忍 master 节点的污点,使其也能被调度上去
      #    这对于监控 master 节点本身也很重要
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      - effect: NoSchedule
        key: node-role.kubernetes.io/control-plane
(2) 部署与验证
  1. 应用 YAML 文件

    kubectl apply -f node-exporter-ds.yaml
    
  2. 查看 DaemonSet 状态

    $ kubectl get ds node-exporter
    NAME            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    node-exporter   3         3         3       3            3           <none>          60s
    

    DESIREDCURRENT 字段显示了期望和当前运行的 Pod 数量,它应该等于你集群中节点的数量。

  3. 查看 Pod 分布情况
    使用 -o wide 参数可以清晰地看到每个 Pod 所在的节点。

    $ kubectl get pods -l app=node-exporter -o wide
    NAME                  READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
    node-exporter-abcde   1/1     Running   0          90s   192.168.1.11   k8s-worker-1   <none>           <none>
    node-exporter-fghij   1/1     Running   0          90s   192.168.1.12   k8s-worker-2   <none>           <none>
    node-exporter-klmno   1/1     Running   0          90s   192.168.1.10   k8s-master-1   <none>           <none>
    

    可以看到,每个节点(包括 master 节点,因为我们加了容忍)上都运行了一个 node-exporter Pod。

三、一次性与周期性任务:Job 与 CronJob

如果说 DaemonSet 关心的是“空间”(部署在哪些节点上),那么 JobCronJob 关心的就是“时间”(何时执行,执行多久)。

3.1 从“一次性”开始:Job 控制器

3.1.1 什么是 Job?

Job 控制器会创建一个或多个 Pod,并确保指定数量的 Pod 成功运行到终止。一旦任务成功完成,Job 就完成了它的使命。如果 Pod 因任何原因(如节点故障、程序 bug)失败,Job 控制器会根据配置的重试策略重新创建一个新的 Pod,直到任务成功或达到重试上限。

核心目标:执行一个会“结束”的任务,并确保其成功完成。

3.1.2 Job 的行为模式

Jobspec 中有几个关键字段来控制其行为:

  • completions: 指定需要成功完成的 Pod 总数。默认为 1。
  • parallelism: 指定并行运行的 Pod 数量。默认为 1。
  • backoffLimit: 指定任务失败前可以重试的次数。默认为 6。
  • activeDeadlineSeconds: 任务运行的最长时限,超时则标记为失败。

3.1.3 Job 应用场景

  • 数据迁移:在应用新版本前,运行一个一次性的数据库 schema 迁移脚本。
  • 批处理计算:对一批数据进行计算、转换或分析。
  • 备份/恢复:执行一次性的数据备份或恢复操作。
  • 测试:运行集成测试或端到端测试。

3.1.4 实战:运行一个计算 π 的 Job

这个经典的例子使用 perl 镜像来计算圆周率到 2000 位。

(1) 编写 pi-job.yaml
# pi-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-calculation
spec:
  # 1. Template: 定义了要运行的 Pod
  template:
    spec:
      containers:
      - name: pi
        image: perl
        # 2. Command: Pod 启动后执行的命令
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      # 3. Restart Policy: Job 的 Pod 必须设置为 OnFailure 或 Never
      #    不能是 Always(这是 Deployment 的默认值)
      restartPolicy: OnFailure
  # 4. Backoff Limit: 如果失败,最多重试 4 次
  backoffLimit: 4
(2) 部署与验证
  1. 应用 YAML 文件

    kubectl apply -f pi-job.yaml
    
  2. 查看 Job 状态

    $ kubectl get jobs pi-calculation
    NAME             COMPLETIONS   DURATION   AGE
    pi-calculation   1/1           15s        30s
    

    COMPLETIONS 显示 1/1,表示任务已成功完成。

  3. 查看 Pod 状态
    Job 完成后,其创建的 Pod 不会被删除,以便你检查日志。

    $ kubectl get pods -l job-name=pi-calculation
    NAME                   READY   STATUS      RESTARTS   AGE
    pi-calculation-xyz12   0/1     Completed   0          45s
    

    STATUSCompleted 表示 Pod 成功执行并退出。

  4. 查看任务输出(日志)

    $ kubectl logs pi-calculation-xyz12
    3.14159265358979323846... (后面跟着一长串数字)
    

3.2 定时任务的“闹钟”:CronJob 控制器

CronJob 是在 Job 之上构建的,它就像为 Job 配备了一个功能强大的定时闹钟。

3.2.1 什么是 CronJob?

CronJob 在给定的时间点(Cron 表达式)上创建一个 Job 对象。它非常适合执行周期性、重复性的任务。

核心目标:按预定的 cron 时间表周期性地创建 Job

3.2.2 Cron 表达式详解

CronJobschedule 字段使用标准的 Cron 表达式,格式如下:

# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 一个月中的第几天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 星期几 (0 - 6) (Sunday to Saturday)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

常用示例:

  • */1 * * * *: 每分钟执行一次。
  • 0 2 * * *: 每天凌晨 2 点执行。
  • 0 17 * * 1-5: 每周一至周五的下午 5 点执行。

3.2.3 CronJob 的关键配置

  • schedule: Cron 表达式,定义任务何时运行。
  • jobTemplate: Job 的模板,定义了每次要创建的 Job 的具体内容。
  • concurrencyPolicy: 并发策略。如果上一个任务还没跑完,新的任务时间点又到了,该如何处理?
    • Allow (默认): 允许并发运行 Job
    • Forbid: 禁止并发,如果前一个 Job 还在运行,则跳过本次执行。
    • Replace: 取消当前正在运行的 Job,并用新的 Job 替换它。
  • successfulJobsHistoryLimit: 保留多少个成功的 Job 历史记录。默认为 3。
  • failedJobsHistoryLimit: 保留多少个失败的 Job 历史记录。默认为 1。

3.2.4 实战:创建一个每分钟打印时间的 CronJob

(1) 编写 hello-cronjob.yaml
# hello-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello-cronjob
spec:
  # 1. Schedule: 每分钟执行一次
  schedule: "*/1 * * * *"
  # 2. Job Template: 定义了每次要创建的 Job
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo "Hello from the Kubernetes CronJob"
          restartPolicy: OnFailure
  # 3. Concurrency Policy: 禁止并发
  concurrencyPolicy: Forbid
  # 4. History Limits: 保留最近 3 个成功和 1 个失败的 Job 记录
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
(2) 部署与验证
  1. 应用 YAML 文件

    kubectl apply -f hello-cronjob.yaml
    
  2. 查看 CronJob 状态

    $ kubectl get cronjob hello-cronjob
    NAME            SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    hello-cronjob   */1 * * * *   False     0        30s             60s
    

    LAST SCHEDULE 显示了上次调度的时间。

  3. 观察被创建的 Job 和 Pod
    等待一两分钟后,你可以看到 CronJob 自动创建的 Job

    $ kubectl get jobs
    NAME                           COMPLETIONS   DURATION   AGE
    hello-cronjob-27757750         1/1           2s         110s
    hello-cronjob-27757751         1/1           2s         50s
    
    $ kubectl get pods
    NAME                                 READY   STATUS      RESTARTS   AGE
    hello-cronjob-27757750-abcde         0/1     Completed   0          112s
    hello-cronjob-27757751-fghij         0/1     Completed   0          52s
    

    你可以看到,CronJob 每次都会创建一个新的 Job,而这个 Job 又会创建一个新的 Pod 来执行任务。

四、三者对比:如何选择合适的控制器?

为了帮助你快速区分和选择,下表总结了 DeploymentDaemonSetJobCronJob 的核心差异。

控制器类型 核心目标 Pod 生命周期 典型应用场景
Deployment 维持指定数量的、长期运行的 Pod 副本 持续运行 (Always Restart) 无状态 Web 服务、API 网关、微服务
DaemonSet 确保每个(或部分)节点上运行一个 Pod 副本 与节点生命周期绑定 日志收集、节点监控、网络/存储插件
Job 确保一个或多个 Pod 成功运行至结束 一次性,运行至完成 (Run-to-Completion) 数据迁移、批处理计算、一次性备份、测试
CronJob 按预定时间表周期性地创建 Job 周期性创建,运行至完成 定时备份、周期性报告生成、定时清理任务

五、总结

通过本文的学习,我们掌握了 Kubernetes 中除了 Deployment 之外的三种重要的工作负载控制器。它们使得 K8s 不仅能管理常规服务,还能灵活处理各种特殊任务,构成了完整而强大的应用调度体系。

核心要点回顾:

  1. Deployment 是通用选择:适用于需要长期运行、可随意扩展的无状态服务。它是最常用的控制器。
  2. DaemonSet 关注“空间”:当你需要在集群的每个节点上部署一个代理或守护进程时,DaemonSet 是不二之选。它保证了 Pod 在节点上的覆盖率。
  3. Job 关注“一次性完成”:对于那些执行完即可丢弃的任务,如数据处理和批处理脚本,Job 提供了可靠的执行和重试机制,确保任务最终成功。
  4. CronJob 关注“周期性执行”:它为 Job 增加了定时调度能力,是 Kubernetes 内置的 crontab,负责自动化执行周期性任务。

理解并熟练运用 DaemonSetJobCronJob,是衡量你是否真正迈入 Kubernetes 进阶大门的重要标志。在实际项目中,根据任务的特性选择最合适的控制器,才能构建出高效、健壮、自动化的云原生应用系统。


Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐