第三部分 k8s 的工作负载资源

发布于:2025-06-27 ⋅ 阅读:(14) ⋅ 点赞:(0)
概述重点(分几个部分学习k8s的笔记)
 第三部分(重要内容)
  • 深刻理解控制器原理
  • 了解ReplicaSet 和 deployment的关系初学重点练习理解deployment(重点)
  • 理解daemonset 工作的原理使用方向
  • 理解job和cronjob 的功能作用和区别
  • 理解statefulset的使用方向先熟练deployment 在进阶练习statefulset

一,控制器原理

总结:控制器是 一个循环控制机制,用来实现 持续维护资源,也就是k8s 的yaml 文件中的期望状态和实际状态的一致性(自愈机制,全靠控制器实现的

原理 :实时监听你的配置 → 对比实际状态 → 如果不一致,就去修复它!

是个资源需要生成yaml 文件,有控制器 只不过是功能不一样

🎯 一句话定义

控制器(Controller)是 Kubernetes 中的一个控制循环,用来持续维护资源的期望状态和实际状态的一致性


🧠 1. 控制器的原理(核心机制)

Kubernetes 是一个“声明式”的系统,你只需要告诉它你想要的状态(desired state),比如:

  • 我要运行 3 个副本的 Web 服务
  • 我要一个暴露端口 80 的服务
  • 我要在 pod 启动前先运行个初始化脚本

控制器的职责就是:

实时监听你的配置 → 对比实际状态 → 如果不一致,就去修复它!

🌀 控制器=一个“无限循环”的自动化流程:

你声明 desired state(yaml)→ 控制器检测差异 → 修复 → 达成期望状态

例如:

  • 你配置了 3 个副本的 Deployment,系统实际只有 2 个,那控制器就会自动再拉起 1 个 Pod。
  • Pod 挂掉,控制器发现异常 → 自动重建。

这就叫 控制循环(Control Loop),是 K8s 自愈能力的核心。


⚙️ 2. 控制器都有哪些?(常见种类)

控制器

干什么的

DeploymentController

管理 Deployment,负责副本数量、滚动更新

ReplicaSetController

实现 Pod 的副本数控制(被 Deployment 使用)

StatefulSetController

管理有状态服务(带编号、稳定存储等)

DaemonSetController

在每个节点部署一个 Pod(如日志/监控 Agent)

JobController

控制一次性任务(运行完就退出)

CronJobController

定时运行的 Job(类比 Linux 的 crontab)

NodeController

管理节点状态,检测是否存活、调度能力

ServiceController

管理 Service 对应的负载均衡器或集群IP


🧰 3. 控制器具体是怎么用的?(怎么做)

Kubernetes 提供的控制器通常以 YAML 资源的形式来使用,例如:

✅ Deployment 示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx

🌟 这里的 kind: Deployment 就代表了你在创建一个控制器对象,控制器会持续保持这个 Pod 的副本数是 3 个。

你使用的每一个如下 YAML 文件,其实背后都是交给控制器去执行的:

  • kind: Deployment → DeploymentController 来管
  • kind: StatefulSet → StatefulSetController 来管
  • kind: CronJob → CronJobController 来管

💡 举个真实例子(自愈场景)

  1. 你创建了一个 Deployment,副本数设置为 3。
  2. 控制器帮你启动了 3 个 Pod。
  3. 某个节点故障,挂了一个 Pod。
  4. DeploymentController 发现只剩 2 个 → 自动再拉起一个 Pod → 恢复为 3 个。

这就是 Kubernetes 的自愈机制,全靠控制器实现的。


✅ 总结一句话

内容

说明

控制器是?

用于保证实际状态 ≈ 期望状态的自动化程序

干什么?

自动修复、调度、副本控制、生命周期管理

怎么用?

通过 YAML 声明资源(Deployment、Job 等)由控制器实现逻辑

原理?

监听资源变化 → 检查 → 修复(控制循环)

ReplicaSet

总结:Kubernetes 中的控制器,确保 pod 的运行状态是正常的以及数量是正确的。

ReplicaSet 是一个用来维持 Pod 副本数量的控制器,是 Deployment 的基础组成部分,是 K8s 自愈机制的关键之一。
了解一下 即可其实 deployment 底层 的副本控制实现用的就是Replicaset

功能

保证副本数

自动重建 Pod

支持 Label 匹配

✅ 什么是 ReplicaSet(RS)

ReplicaSet 是 Kubernetes 中的工作负载资源控制器,负责确保指定数量的 Pod 副本始终处于运行状态

简单说:它会确保你声明了 3 个 Pod,就始终有 3 个 Pod 正在跑,有一个挂了就马上补上。


🎯 它是干什么的?

功能

说明

保证副本数

负责保证 Pod 的数量 = 你设置的副本数

自动重建 Pod

如果某个 Pod 异常退出或节点宕机,会自动重建

支持 Label 匹配

根据标签匹配要管理的 Pod


⚙️ 工作机制(原理)

ReplicaSet 是一个控制循环(Control Loop)

  1. 你声明了期望运行 replicas: 3
  2. 控制器不断对比实际运行的 Pod 数量。
  3. 少了就启动,多了就删除,保持一致。

👉 注意:ReplicaSet 不直接管理 Pod 模板,Deployment 才是完整的高级封装。


🔧 怎么用(配置示例)

虽然现在实际工作很少单独写 ReplicaSet(因为 Deployment 用起来更方便),但它是 Deployment 的核心组件,必须理解。

ReplicaSet YAML 示例

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp         # 匹配 Pod 的标签
  template:
    metadata:
      labels:
        app: myapp       # Pod 的标签,必须与 selector 匹配
    spec:
      containers:
      - name: myapp
        image: nginx

🔍 工作中怎么用(实战应用)

✅ 1. Deployment 的背后就是使用 ReplicaSet 实现副本控制的

kubectl get rs

你会看到每次你更新 Deployment,都会生成一个新的 ReplicaSet。

✅ 2. Pod 自愈能力的底层机制

  • Pod 崩溃或节点宕机时,ReplicaSet 负责拉起新的 Pod。

✅ 3. 滚动更新 / 回滚机制

  • Deployment 管理多个 ReplicaSet,实现版本平滑升级与回退。
  • kubectl rollout historykubectl rollout undo 能看到/回滚旧版本 ReplicaSet。

🧠 学习重点总结

模块

学什么

原理

ReplicaSet 是 Pod 副本数量的维持者

区别

它不支持滚动更新,Deployment 是它的“上层封装”

实践

Deployment 的每次更新都会创建新的 ReplicaSet

配置

必须配置 replicas

selector

和 Pod 模板

标签匹配

selector.matchLabels 要与 template.metadata.labels 匹配


❗️容易踩的坑

常见问题

说明

Pod 标签不匹配

ReplicaSet 管不了 Pod,状态就不正常

手动删除 Pod

会被自动拉起来,因为 RS 控制副本数

没用 Deployment 升级麻烦

RS 没有滚动更新功能,需手动控制


🎯 总结一句话

ReplicaSet 是一个用来维持 Pod 副本数量的控制器,是 Deployment 的基础组成部分,是 K8s 自愈机制的关键之一。

Deployment

总结:Deployment 是Kubernetes 中的工作负载资源高级控制器,负责管理无状态应用。作用是:副本控制,滚动更新,回滚机制

Deployment 是什么?

Deployment 是 Kubernetes 中用于管理 Pod 的高级控制器,用来声明式地管理应用的生命周期,包括创建、更新、回滚和扩缩容,自动重启/调度

换句话说:

Deployment = 自动化 + 管理性更强的 Pod 副本控制器(底层靠 ReplicaSet 实现)


🧠 它是干什么的?

功能

说明

副本控制

控制多个 Pod 的副本数(像 ReplicaSet 一样)

滚动更新

平滑地升级应用,不中断服务

回滚机制

应用异常版本,快速一键回退

自愈能力

Pod 崩溃后自动重建

支持历史记录

保留所有版本的 ReplicaSet 历史

自动重启/调度

Pod 异常时,自动替换运行在健康节点上


🔧 怎么做(YAML 示例)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx:1.25.3
        ports:
        - containerPort: 80

🛠️ 工作中怎么用?

常用命令:

典型操作场景
场景 1:创建与更新
# 创建 Deployment
kubectl apply -f deployment.yaml

# 查看 Deployment 状态
kubectl get deployments
kubectl describe deployment nginx-deployment

# 触发滚动更新(修改镜像版本)
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
场景 2:回滚到历史版本
# 查看更新历史
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
场景 3:扩缩容
# 手动调整副本数
kubectl scale deployment nginx-deployment --replicas=5

# 自动扩缩容(需配置 HPA)
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=2 --max=10

🔄 工作机制:Deployment 背后的控制循环

Deployment 不直接创建 Pod,而是做了这几件事:

你写 Deployment → 创建一个 ReplicaSet → RS 创建多个 Pod
        ↓           ↑          ↑
      滚动更新? → 创建新RS → 启动新Pod、删除旧Pod

🧠 Deployment = 管理多个 ReplicaSet 的控制器
每次你更新 Deployment 的配置,它都会自动:

  • 创建一个新的 ReplicaSet
  • 按策略平滑升级
  • 保留旧的 RS 可用于回滚

🔍 Deployment 与 ReplicaSet 区别(超关键)

对比项

Deployment

ReplicaSet

用途

管理应用发布与升级

管理 Pod 副本

是否直接使用

推荐使用

不建议单独用

是否支持滚动更新

✅ 支持

❌ 不支持

是否支持回滚

✅ 支持

❌ 不支持

自动创建

会创建 RS

被 Deployment 创建

使用方式

实际工作中使用

通常由系统自动生成

🔗 关系总结一句话:
Deployment 是上层控制器,它管理 ReplicaSet → ReplicaSet 再管理 Pod。


🎯 学习重点总结

学习点

说明

YAML 配置结构

replicas

selector

template

滚动更新机制

默认按比例逐步替换旧 Pod

命令行控制

kubectl rollout

系列操作

与 ReplicaSet 区别

一个高层封装,一个底层控制器

使用场景

用于所有无状态服务、Web 应用等部署场景

核心知识点
  1. YAML 结构
    • 必填字段:apiVersionkindmetadataspecreplicasselectortemplate)。
    • 更新策略(strategy):RollingUpdate(默认)或 Recreate(直接删除旧 Pod)。
  1. 滚动更新参数
    • maxSurge:允许临时超出副本数的 Pod 数量(如 25% 或固定值)。
    • maxUnavailable:更新期间允许不可用的 Pod 数量。
  1. 版本控制与回滚
    • revisionHistoryLimit:控制保留的历史 ReplicaSet 数量(默认 10)。
    • 使用 kubectl rollout 命令管理版本。
  1. 健康检查与就绪探针
    • 确保新 Pod 就绪后再替换旧 Pod(需配置 readinessProbe)。
  1. 故障排查
    • 查看 Deployment 事件:kubectl describe deployment <name>
    • 常见问题:
      • 镜像拉取失败(ImagePullBackOff)。
      • 就绪探针配置错误导致 Pod 无法进入 Ready 状态。

全面一点的deployment 的配置内容

注意:你会发现是 Deployment 包裹着 container

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
  labels:
    app: my-app
spec:
  replicas: 3          # 副本数,保持服务高可用告诉 Kubernetes:我要运行 3 个副本 Pod
  strategy:
    type: RollingUpdate                       # 默认就是滚动更新
    rollingUpdate:
      maxUnavailable: 1                       # 最多1个实例不可用(旧 Pod 先删)
      maxSurge: 1                             # 最多新增1个 Pod(新 Pod 先起)
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: my-app-image:1.0.0           # 镜像版本号,改这个就能触发滚动更新
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
          env:                                # 环境变量配置
            - name: ENV
              value: "prod"
            - name: REDIS_HOST
              valueFrom:
                configMapKeyRef:
                  name: my-config
                  key: redis_host
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: my-secret
                  key: db_password
          resources:                          # 资源限制,防止抢占资源
            requests:
              cpu: "200m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          livenessProbe:                      # 存活探针
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:                     # 就绪探针
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          volumeMounts:                       # 配置文件挂载
            - name: config-volume
              mountPath: /app/config
              readOnly: true
      volumes:
        - name: config-volume
          configMap:
            name: my-config
      restartPolicy: Always                   # 一般固定写 Always

🧱 配置详解(重点来了)


🔢 replicas: 3 —— 设置副本数量
replicas: 3

作用:

  • 告诉 Kubernetes:我要运行 3 个副本 Pod
  • Kubernetes 会保证始终有 3 个 Pod 正常运行,如果某个挂了,它会自动拉起。

为什么要多个副本?

  • 保证服务高可用(High Availability)
  • 负载均衡(Load Balance),比如 Service 会把请求分发给多个 Pod
  • 滚动更新时能保证不影响整体服务(一个更新,两个服务中)

🎯 运维建议: 在生产环境一般最少设置 2~3 个副本。


🔄 strategy —— 设置升级策略(重点)
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1
    maxSurge: 1
🔹 type: RollingUpdate
  • 表示使用“滚动更新”方式进行升级。
  • 替代方案是 Recreate(先删再建,很少用,风险大)。
🔹 rollingUpdate: 下的两个参数

参数

含义

解释

maxUnavailable: 1

最多允许有1个Pod不可用

假设原来有3个 Pod,那最多能“临时缺少1个”

maxSurge: 1

最多额外多创建1个新Pod

比如先启动一个新 Pod 再删旧的,避免服务中断

📌 总结一句话:

保证至少有两个 Pod 正常提供服务,一个在升级、一个在等删除。这样实现平滑更新。

🔥 面试可以这样说:
“使用 RollingUpdate 策略可以实现无中断部署(zero downtime),控制升级期间的可用性和资源浪费。”


🧲 selectortemplate.metadata.labels —— 绑定 Pod 与 Deployment 的“配对钥匙”
selector:
  matchLabels:
    app: my-app
template:
  metadata:
    labels:
      app: my-app
这是 Kubernetes 的“标签选择机制”,两部分必须完全一致!

区域

含义

selector.matchLabels

Deployment 会“寻找标签为 app=my-app 的 Pod”

template.metadata.labels

新创建 Pod 时,自动打上 app=my-app

标签

💡 为什么需要这个绑定?

  • 让 Deployment 只管理自己创建的 Pod
  • 防止误操作导致其他服务 Pod 被它“更新”或“删掉”
  • Service 通过 label 找到对应的 Pod,也是依赖这个标签

🎯 运维建议:

  • 标签要统一规范,常见命名:app, env, tier, version,方便组合筛选。
  • 尽量不要让不同 Deployment 使用一样的标签。

container 的内容解释

✅ 一、环境变量注入
🔹 - name: REDIS_HOST
  valueFrom:
    configMapKeyRef:
      name: my-config
      key: redis_host

🔍 一句话作用:
这个环境变量的值来自于一个 ConfigMap(配置文件)里的 redis_host 字段。

🔧 背景原理:
Kubernetes 提倡“配置和代码解耦”,所以把 Redis 的地址不直接写死,而是放进 ConfigMap,应用启动时自动读取。

🧪 举个例子:
你有一个 ConfigMap 叫 my-config,内容如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  redis_host: redis.default.svc.cluster.local

那么容器里就能用:

echo $REDIS_HOST
# 输出 redis.default.svc.cluster.local

🔹 - name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: my-secret
      key: db_password

🔍 一句话作用:
这个环境变量的值来自于一个 Secret(加密配置)里的 db_password 字段,用于存储数据库密码。

🔧 背景原理:
Secret 是加密存储敏感信息(如密码、token、API密钥)的组件,防止写死在代码里。

🧪 举个例子:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  db_password: cGFzc3dvcmQ=   # base64 编码后的密码

容器内你就可以读取 $DB_PASSWORD 获取密码。

🎯 建议:

  • 所有敏感信息都用 Secret,不要写死!
  • ConfigMap 用于公开配置,Secret 用于保密配置。

✅ 二、livenessProbe(存活探针)

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 15

🔍 一句话作用:
定时检查这个容器是否“活着”,不健康就自动重启容器。

🔧 背景原理:

  • /healthz 是应用自定义的健康检查接口,返回 200 表示健康。
  • 如果连续检查失败,K8s 会认为应用“挂了”,触发重启。

🧪 例子: 你的后端代码提供了接口:

GET /healthz
→ 返回 200 OK 正常
→ 返回 500 或不响应 → 重启容器

📌 这能帮助你在 Redis 挂掉、应用卡死的时候自动恢复,无需手动干预!


✅ 三、volumeMounts + volumes(配置挂载)

🔹 volumeMounts 容器内路径挂载点
volumeMounts:
  - name: config-volume
    mountPath: /app/config
    readOnly: true

🔍 一句话作用:
把一个叫 config-volume 的卷(volume)挂载到容器的 /app/config 目录下,并设为只读。


🔹 volumes 容器外部数据源定义
volumes:
  - name: config-volume
    configMap:
      name: my-config

🔍 一句话作用:
这个卷的数据来源是 ConfigMap 叫 my-config,内容自动变成配置文件挂进容器。

🧪 完整例子:
你的 ConfigMap 是:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  redis.conf: |
    bind 0.0.0.0
    protected-mode no

那么容器里会生成一个文件:

/app/config/redis.conf  # 文件内容就是你上面写的

🔐 好处:

  • 不需要重新构建镜像,就能修改配置文件内容!
  • 容器内部代码照常读取 /app/config/redis.conf,就像本地文件一样

🎯 总结一张图帮助你记住:


ConfigMap / Secret
    ↓
  作为变量        ←───────→      挂载成配置文件
    ↓                                 ↓
env: valueFrom             volumeMounts + volumes


面试或复盘建议这样回答:

可以说:

我在配置 Deployment 时,设置了 replicas 作为副本数,保证服务高可用;用 strategy.rollingUpdate 控制升级时的可用性和并发资源创建;同时通过 selector 和 labels 保证 Deployment 精准控制对应 Pod,避免出现意外匹配问题。


DaemonSet

DaemonSet 是一种控制器用于在集群中每个 Node 上都运行一个pod,每个节点跑一个我指定的 Pod,有新节点就自动部署,有节点删除就自动清理
适合:做监控 和 网络插件这样的 每个节点 之运行一个的pod,有新节点就自动部署,有节点删除就自动清理

✅ 什么是 DaemonSet?

DaemonSet 是一种控制器,用于在集群中每个 Node 上都运行一个(或者多个)Pod。

换句话说:

它的使命是:每个节点跑一个我指定的 Pod,有新节点就自动部署,有节点删除就自动清理。


🧠 它是干什么的?

作用

说明

节点级任务部署

保证每个 Node 上都有运行指定的 Pod

常用于系统组件部署

日志采集、监控、网络插件

自动部署

新节点加入后自动部署,节点离开自动清理

不适合跑业务服务

因为不是按副本数,而是按节点分布


📦 常见场景(非常实用!)

场景

举例

日志采集

如部署 Fluentd / Filebeat

监控系统

Node Exporter、Datadog Agent

容器网络插件

CNI 插件如 Calico、Flannel

节点守护程序

自定义运维脚本、健康检测守护进程


🛠️ 怎么做(配置 YAML 示例)

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-logger
spec:
  selector:
    matchLabels:
      app: node-logger
  template:
    metadata:
      labels:
        app: node-logger
    spec:
      containers:
      - name: logger
        image: fluentd:latest

🔍 解释说明:

  • 每个 Node 会运行一个 fluentd 容器
  • 不需要写 replicas(DaemonSet 是自动按节点数来分配)

🛠️ 工作中怎么用?

常用命令:

kubectl apply -f fluentd-daemonset.yaml    # 创建 DaemonSet
kubectl get ds                              # 查看所有 DaemonSet
kubectl describe ds node-logger             # 查看详情
kubectl delete ds node-logger               # 删除

实际工作场景:

  • 在阿里云、腾讯云部署监控 agent(如 Argo agent)
  • 在裸机部署日志采集器
  • 大厂都会用它来部署节点探测服务、CNI 组件

🔍 DaemonSet 的控制机制

控制器逻辑如下:

你定义了一个 DaemonSet →
  控制器监听 Node →
    在每个节点上自动拉起 Pod →
      新节点加入时自动部署 →
        节点删掉时自动清理对应 Pod

 学习重点总结

学习项

说明

使用场景

主要跑守护类、节点级别服务,不跑业务

YAML 配置

类似 Deployment,但没有 replicas 字段

自动调度

每个 Node 自动部署 Pod,无需指定节点名

兼容性

支持 nodeSelector

tolerations

来选择部署在哪些节点

跟 Deployment 区别

Deployment 是“控制副本数”,DaemonSet 是“控制每个节点”


 DaemonSet vs Deployment

对比项

Deployment

DaemonSet

副本数控制

手动设置 replicas

每个 Node 自动部署一个

应用类型

应用服务(Web)

系统级任务(日志、监控)

新节点支持

不自动部署

自动部署

用于负载均衡

❌ 通常不使用

常见用法

Nginx、Java 服务等

Filebeat、Node Exporter


✅ 总结一句话:

DaemonSet 是用来在每个 Node 上部署一个 Pod 的控制器,常用于日志、监控、网络插件等系统组件的运行。

问题: daemonset 的实现原理是什么(随着node 创建自动创建,node 移除自动移除)。

总结:daemonset通过Controller 其控制循环逻辑 监听系统中着node(节点)的增加或删除,遍历集群中的每个符合调度条件的节点, 符合了pod 会被打上 spec.nodeName = 某个节点名 的标签 通过标签找到节点进行创建, 不需要经过schedule 调度器

🧠 DaemonSet 是怎么实现的?

Kubernetes 中的 DaemonSet 是通过 控制器(Controller)机制 实现的,其控制循环逻辑大概如下:

🌱 1. 每个节点上运行一个 Pod

  • 当你创建一个 DaemonSet 资源时,kube-controller-manager 中的 DaemonSet Controller 就会开始工作。
  • 它会遍历集群中的每个 符合调度条件的节点,为这些节点 创建对应的 Pod
  • 这些 Pod 会被打上 spec.nodeName = 某个节点名 的标签,强制调度到目标 Node 上(不经过调度器)。

🪄 2. 新节点加入,自动创建 Pod

  • DaemonSet Controller 会监听集群中所有的 Node。
  • 如果有新的 Node 加入,Controller 就会:
    • 检查这个 Node 是否满足 DaemonSet 的调度条件(如 nodeSelector、Tolerations 等)
    • 满足条件就立即创建一个 Pod,spec.nodeName 指定为该新 Node,Pod 就部署上去了。

💣 3. 节点删除,自动删除对应的 Pod

  • 节点下线或被删除时,Kubelet 会向 apiserver 报告 Node NotReady 或删除 Node 资源。
  • DaemonSet Controller 会监听到这个事件,自动将该 Node 上的 Pod 标记为 Terminating。
  • 同时 Kubernetes 会清理对应的 Pod。

⚙️ 示例 YAML:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-agent
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: my-agent
  template:
    metadata:
      labels:
        app: my-agent
    spec:
      containers:
      - name: my-agent
        image: busybox
        command: ["sh", "-c", "while true; do echo hello; sleep 10; done"]
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

🧩 技术核心点总结:

特性

实现机制

每个 Node 1 个 Pod

DaemonSet Controller 使用 nodeName

新节点加入自动部署

Watch Node,自动 create Pod

节点删除自动清理

Watch Node 状态和生命周期事件

不经过 Scheduler

Pod 的 nodeName

直接绑定,不用调度器


✅ 你需要掌握的关键点:

  1. DaemonSet 的 Pod 是不通过调度器调度的,而是由控制器直接指定 nodeName
  2. 使用场景明确:每个节点必须部署的系统组件
  3. 控制器是核心:监听 Node 的变化自动增删 Pod
  4. 可以结合 Tolerations、NodeSelector、Affinity 精确控制哪些节点要部署。

job 和 cronjob

一、Job 是什么?干什么的?

Job 是一种一次性任务控制器,用来在 K8s 中执行并确保某个任务成功运行完成

✅ Job 适合什么?

执行完就结束的任务,比如:

  • 备份数据库
  • 执行一次数据导入脚本
  • 清理历史日志
  • 初始化数据(如表结构、种子数据)
  • 运行测试脚本等

📄 Job 示例:

apiVersion: batch/v1
kind: Job
metadata:
  name: backup-job
spec:
  template:
    spec:
      containers:
      - name: backup
        image: mysql:8
        command: ["sh", "-c", "mysqldump -h ... > /backup/db.sql"]
      restartPolicy: OnFailure

执行一次后任务就完成 ✅


🕒 二、CronJob 是什么?干什么的?

CronJob 是 Job 的定时调度版本,可以按计划周期性地执行 Job

就像 Linux 里的 crontab

✅ CronJob 适合什么?

定时跑任务,比如:

  • 每天 2 点做数据库备份
  • 每小时刷新缓存
  • 每月归档日志
  • 每 5 分钟清理临时文件

📄 CronJob 示例:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: log-clean-cron
spec:
  schedule: "0 2 * * *"  # 每天凌晨2点
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: clean
            image: busybox
            command: ["sh", "-c", "rm -rf /tmp/logs/*"]
          restartPolicy: OnFailure

会根据 schedule 周期性生成 Job。


🔍 三、Job vs CronJob 对比总结

对比项

Job

CronJob

作用

执行一次任务

定期重复执行任务

是否定时

❌ 不是定时

✅ 有 schedule

触发方式

手动或一次性触发

自动周期性触发

使用场景

初始化、数据清洗、备份

定时任务:备份、同步、报表

配置入口

spec.template.spec

spec.jobTemplate.spec.template.spec

控制字段

backoffLimit

ttlSecondsAfterFinished

同样支持这些字段,也有 schedule


🧰 四、配置差异对比(关键点)

配置点

Job

CronJob

顶级 kind

Job

CronJob

定时字段

schedule: "* * * * *"

模板结构

spec.template.spec

spec.jobTemplate.spec.template.spec

控制运行次数

completions

, parallelism

自动创建多个 Job 控制

清理策略

ttlSecondsAfterFinished

同样支持


📌 五、怎么用(流程建议)

操作

Job

CronJob

创建

kubectl apply -f job.yaml

同上

查看状态

kubectl get jobs

kubectl get cronjobs

查看 Job 日志

kubectl logs <pod-name>

同样方式

强制运行一次 CronJob

kubectl create job --from=cronjob/<name> <job-name>

手动触发调试

删除任务

删除 Job 或 CronJob 资源即可


🧠 一句话总结

Job 是一次性的执行任务,CronJob定期执行 Job 的计划任务,二者用途不同,配置结构相似但有调度差异。

练习: Job & CronJob 参数使用模板大全(超实用)

我们按 3 个层次整理:

层级

内容

🔹 基础字段

每次都需要用的

🔸 控制字段

控制任务行为(并发、重试、超时)

🔺 高级字段

控制清理、历史任务、挂载、安全等


🔹 一、通用基础结构(Job vs CronJob)

✅ Job 基本结构

apiVersion: batch/v1
kind: Job
metadata:
  name: demo-job
spec:
  template:
    spec:
      containers:
      - name: task
        image: busybox
        command: ["sh", "-c", "echo Hello Job"]
      restartPolicy: OnFailure

✅ CronJob 基本结构

apiVersion: batch/v1
kind: CronJob
metadata:
  name: demo-cronjob
spec:
  schedule: "0 3 * * *"  # 每天凌晨3点
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: task
            image: busybox
            command: ["sh", "-c", "echo Hello CronJob"]
          restartPolicy: OnFailure

🔸 二、控制行为的参数

🔁 任务并发与重试(Job + CronJob)

参数

类型

含义

completions

int

期望执行多少次

parallelism

int

同时允许多少个 Pod 并发执行

backoffLimit

int

失败后最多重试次数(默认 6)

activeDeadlineSeconds

int

Pod 最长运行时间,超时就失败

restartPolicy

enum

容器失败是否重启:Always / Never / OnFailure(Job 推荐 OnFailure)

✅ 示例:

spec:
  completions: 1
  parallelism: 1
  backoffLimit: 3
  activeDeadlineSeconds: 600

⏱️ 定时调度专属参数(CronJob)

参数

类型

含义

schedule

string

定时格式(cron)

startingDeadlineSeconds

int

允许延迟启动的最大秒数

concurrencyPolicy

enum

并发策略:Allow / Forbid / Replace

successfulJobsHistoryLimit

int

保留成功历史数量

failedJobsHistoryLimit

int

保留失败历史数量

suspend

bool

暂停 CronJob(调试时很有用)

✅ 示例:

spec:
  schedule: "*/5 * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 2
  suspend: false

🔺 三、高级实战字段推荐

🧹 自动清理 Job 和 Pod(Job / CronJob 通用)

spec:
  ttlSecondsAfterFinished: 3600  # 成功或失败后 1 小时自动删除

💾 挂载配置文件和密码(ConfigMap + Secret)

containers:
- name: task
  env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mysql-secret
        key: password
  volumeMounts:
  - name: config-volume
    mountPath: /app/config

volumes:
- name: config-volume
  configMap:
    name: app-config

📦 资源限制(建议设置)

resources:
  requests:
    cpu: "100m"
    memory: "256Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

💡 小技巧:Job 与 CronJob 模板切换速记(重点)

Job → CronJob

spec.template

spec.jobTemplate.spec.template

增加 schedule

字段

其他参数基本不变(如 backoffLimit、ttlSecondsAfterFinished)


✅ 最佳实践建议

目的

建议做法

定时任务

CronJob + concurrencyPolicy

任务超时限制

Job + activeDeadlineSeconds

自动清理

ttlSecondsAfterFinished

多环境配置

ConfigMap + Secret + volumeMounts

备份类任务

Job + PVC 持久化结果

调试 CronJob

kubectl create job --from=cronjob/...

statefulset

初学先了解 ,认真搞好 deployment

总结:

StatefulSet 是为有状态服务设计的控制器,用的是server 无头服务的网络模式,能够保持每个 Pod 的身份(名字、IP、存储)不变,适用于数据库、消息队列、分布式存储等。

一、什么是 StatefulSet?

StatefulSet 是 Kubernetes 中的一种控制器,用于管理有状态服务的部署和扩缩容,它能够保证:

特性

说明

稳定的网络标识

每个 Pod 有唯一不变的 DNS 名(如:mysql-0

mysql-1

稳定的存储

每个 Pod 拥有自己的 PVC(不会随着 Pod 删除而清除)

有序部署与删除

按照顺序启动或终止(0 → n

有序滚动更新

一次更新一个,防止全挂


二、它是用来干什么的?

用来管理有状态服务,也就是:

每个实例(Pod)都有自己的唯一身份和数据,不能随便丢。

最常见的例子就是:

应用类型

说明

🐘 数据库集群(MySQL、PostgreSQL、Redis 主从)

每个节点数据不能共享

📦 消息队列(Kafka、RabbitMQ)

有状态的消息分片

🔎 分布式存储(Ceph、Elasticsearch)

每个节点保存不同分片

🧠 Zookeeper、Etcd

要保持节点 ID 不变


三、和 Deployment 有什么区别?

对比项

Deployment

StatefulSet

Pod 名字

随机,例如 web-6f98df5bfb-xxx

固定,例如 mysql-0

mysql-1

网络 DNS

不保证唯一

保证,如 mysql-0.mysql.default.svc.cluster.local

存储卷 PVC

可共享 / 不保留

每个 Pod 单独一个,且不会删除

部署顺序

可并发

严格有序(0 → 1 → 2)

适合场景

无状态应用,如 Web 服务

有状态服务,如数据库

📌 一句话区分:

✅ 无状态用 Deployment,
✅ 有状态用 StatefulSet!


四、StatefulSet 的使用示例(最简单版本)

我们来举一个 MySQL 主节点的单实例 StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"         # 必须先创建一个 Headless Service
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-persistent-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

💡 对上面 YAML 的重点解释:

字段

作用

serviceName

对应的 Headless Service(作用是提供 DNS)

replicas

副本数量,比如你要部署 3 个 MySQL 节点

volumeClaimTemplates

自动为每个 Pod 创建专属 PVC(如 mysql-persistent-storage-mysql-0

Pod 名

将自动生成为:mysql-0

, mysql-1

...


🧠 StatefulSet 工作机制:

  1. 创建 Headless Service(ClusterIP: None) → 提供 DNS
  2. StatefulSet 创建 Pod:mysql-0mysql-1 → ...
  3. 每个 Pod 拥有:
    • 独立 DNS(如 mysql-0.mysql.default.svc.cluster.local
    • 独立存储卷(mysql-persistent-storage-mysql-0
  1. 删除 Pod 不会删 PVC,数据保留!

总结一句话

StatefulSet 是为有状态服务设计的控制器,能够保持每个 Pod 的身份(名字、IP、存储)不变,适用于数据库、消息队列、分布式存储等。

最完整的 Deployment 案例 一

总结: 没太多的配置主要是 1. selector (筛选) 和 template(创建) 的组合

2,strategy 滚动更新 3,replicas 副本数

1. 准备一个简单的容器镜像

我们用官方的 nginx:1.25 作为示例,简单、稳定。


2. 完整 Deployment 配置

以下内容直接保存成一个文件,比如叫 nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx    
spec:
  replicas: 3   # 副本数量 3 个pod 用于负载均衡
  selector:   #筛选 pod 
    matchLabels:
      app: nginx  # 筛选所有包含标签 `app: nginx` 的 Pod   先由 template 给 replicas 的3个pod 打上标签 , 再由 selector 去筛选出来 控制维护
  template:
    metadata: 
      labels:
        app: nginx  # 为 Pod 打上标签 `app: nginx`
    spec:
      containers:
      - name: nginx    #这名字 是 为了 Deployment 提供筛选的
        image: nginx:1.25
        ports:
        - containerPort: 80
        readinessProbe:    # 就绪探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:     # 存活探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 20
        resources:         # 资源请求和限制(合理,不超规格)
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service  #就是 你创建的service 的名字
  namespace: default
spec:
  type: ClusterIP   # Service 的网络工作模式
  selector:         # 这个筛选是 和 deployment的 那个 selector....template 绑定的 让service直接路由到上面
    app: nginx
  ports:    
  - port: 80      #  这个是 Service 暴露的端口  Service 是一个虚拟IP(ClusterIP)+端口,别人访问的是 Service 的地址和它暴露出来的 port 
    targetPort: 80  # 这个是 pod 暴露的端口   targetPort 是为了告诉 Service,应该把流量转发到 Pod 的哪个端口! 因为pod才是最后工作的

为什么要有 targetPort: 80

简单一句话总结:
👉 targetPort 是为了告诉 Service,应该把流量转发到 Pod 的哪个端口

因为

  • Service 是一个虚拟IP(ClusterIP)+端口,别人访问的是 Service 的地址和它暴露出来的 port
  • 但真正提供服务的是后端的 Pod,它们内部监听的端口不一定和 Service 暴露的 port 一样。
  • 所以,需要一个字段明确告诉 Service:"你把流量转发到 Pod 的哪个端口去" —— 这就是 targetPort 的作用!1

3. 执行部署步骤

1)保存上述内容 保存为 nginx-deployment.yaml 文件。

2)执行 kubectl apply

kubectl apply -f nginx-deployment.yaml

3)验证部署

# 查看 Deployment
kubectl get deployment nginx-deployment

# 查看 Pod
kubectl get pods -l app=nginx

# 查看 Service
kubectl get svc nginx-service

4)如果想要访问测试一下 因为 Service 是 ClusterIP,只能在集群内部访问。 可以用 kubectl port-forward 绑定到本地测试:

kubectl port-forward svc/nginx-service 8080:80

然后浏览器访问:http://localhost:8080,就能看到 nginx 的欢迎页面。


4. 特别说明

  • 这个 Deployment 带了:
    • 副本(replicas)
    • 选择器(selector)
    • 镜像(image)
    • 端口映射(containerPort)
    • 资源管理(resources)
    • 存活探针(livenessProbe)
    • 就绪探针(readinessProbe)
  • Service 是 ClusterIP 类型,生产一般配合 Ingress 或外部负载均衡器。

案例二  标准企业级 Deployment 模板(带所有核心字段)

保存为 enterprise-deployment.yaml,适合 Java/Node/Nginx 类服务都可根据情况套用。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
  labels:
    app: myapp
spec:
  replicas: 3  # 多副本部署
  revisionHistoryLimit: 5  # 回滚历史版本保留数
  strategy:
    type: RollingUpdate  # 或者 也可以设置为 Recreate(会先杀掉所有旧 Pod,再启动新 Pod,不推荐用于生产)
    rollingUpdate:
      maxSurge: 1  # 更新时最多多出一个 Pod
      maxUnavailable: 1  # 更新时最多停一个 Pod
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      terminationGracePeriodSeconds: 30  # 优雅终止等待时间
      securityContext:
        runAsNonRoot: true  # 非 root 用户运行(推荐)
        fsGroup: 2000
      nodeSelector:
        dedicated: myapp-node  # 只调度到带有该标签的节点(可选)
      affinity:  # 反亲和性,避免多个副本集中在一个节点
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - myapp
              topologyKey: "kubernetes.io/hostname"
      tolerations:
        - key: "dedicated"
          operator: "Equal"
          value: "myapp-node"
          effect: "NoSchedule"
      containers:
        - name: myapp
          image: myorg/myapp:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
              name: http
          envFrom:
            - configMapRef:
                name: myapp-config  # 配置来源
            - secretRef:
                name: myapp-secret  # 敏感信息来源
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "1000m"
              memory: "512Mi"
          readinessProbe:  # 就绪检查,控制流量转发
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
            timeoutSeconds: 3
            failureThreshold: 3
          livenessProbe:  # 存活检查,控制重启
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
            timeoutSeconds: 5
            failureThreshold: 3
          lifecycle:  #这是 Pod 生命周期钩子(Lifecycle Hooks) 的一部分,专门用于在容器被终止前执行一些操作。
            preStop:  #
              exec:
                command: ["/bin/sh", "-c", "sleep 10"]  # 下线前缓冲
          volumeMounts:
            - name: logs
              mountPath: /var/log/myapp
      volumes:
        - name: logs
          emptyDir: {}  # 示例日志目录,如需持久化可换成 PVC

✅ 配套 Service(暴露服务)

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: default
  labels:
    app: myapp
spec:
  selector:
    app: myapp
  type: ClusterIP  # 也可改为 NodePort / LoadBalancer / 外部 Ingress
  ports:
    - name: http
      port: 80
      targetPort: 8080

✅ 可选:配套 HPA(自动扩缩容)

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  namespace: default
spec:
  scaleTargetRef:   #要匹配的资源 
    apiVersion: apps/v1
    kind: Deployment  # 也可是 StatefulSet
    name: myapp-deployment
  minReplicas: 3  # 最少是三个副本
  maxReplicas: 10 # 最多是10个副本
  metrics:  # 指标是 cpu
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

✅ 建议你配的额外资源(可选但推荐)

资源

用途

示例名字

ConfigMap

应用配置

myapp-config

Secret

账号密码等

myapp-secret

Ingress

域名访问路由

myapp-ingress

PVC

持久存储

myapp-pvc

Prometheus 监控探针

监控 metrics

/metrics

路由暴露


✅ 总结

分类

是否包含

多副本

滚动更新

资源限制

健康检查

生命周期钩子

配置分离

✅(ConfigMap、Secret)

节点调度控制

✅(nodeSelector / affinity / toleration)

安全最佳实践

✅(非 root)

自动扩缩容

✅(HPA)

日志挂载

✅(volumeMounts)


这个模板可作为你以后所有服务的基础模板去复制改写,适配任何语言栈、服务形态。
要不要我再给你配一个基于这个模板的 Java SpringBoot 示例版本?那种一般端口是 8080,health 路径是 /actuator/health

部署的问题

问题一:

namespace: default

labels: app: myapp

selector:

matchLabels:

app: myapp

template:

metadata:

labels:

app: myapp 这 三个 app:myapp 的作用相同吗

总结:不相同 第一个是 作用:是 Deployment 自身的标签 用于筛选查询。

第二个 作用:定义 Deployment 如何识别它自己创建的 Pod Kubernetes 会根据这个 selector 来判断:“这个 Pod 是我管理的吗?”
第三个 作用是
Deployment 创建的 Pod 所带的标签

  • 它必须和上面的 spec.selector.matchLabels 完全一致。
  • 同时,Service 也通常根据这个标签来进行流量转发


提到的这三个 app: myapp,虽然看起来一样,但它们各自作用不同、意义不同,我们逐一分析:


✅ 对比这三处 app: myapp 的具体作用

metadata.labels(Deployment 级别)

metadata:
  name: myapp-deployment
  labels:
    app: myapp

🟡 作用:是 Deployment 自身的标签,比如你执行:

kubectl get deployment -l app=myapp

这个标签就能让你快速筛选出该 Deployment。

📌 仅标记 Deployment 本身,不影响 Pod 创建或服务匹配。


spec.selector.matchLabels

selector:
  matchLabels:
    app: myapp

🟠 作用:定义 Deployment 如何识别它自己创建的 Pod

这个 selector 要与 Pod Template 的标签精确一致,否则会报错!

📌 Kubernetes 会根据这个 selector 来判断:“这个 Pod 是我管理的吗?”
否则 Deployment 就无法管理、滚动更新这个 Pod。


template.metadata.labels

template:
  metadata:
    labels:
      app: myapp

🔵 作用:是 Deployment 创建的 Pod 所带的标签

  • 它必须和上面的 spec.selector.matchLabels 完全一致。
  • 同时,Service 也通常根据这个标签来进行流量转发:
spec:
  selector:
    app: myapp  # Service 会根据这个标签找到 Pod

✅ 总结表格

位置

作用

是否必须

影响对象

metadata.labels

标记 Deployment 本身

❌(推荐)

Deployment

selector.matchLabels

用于匹配 Pod

Deployment 管理哪个 Pod

template.metadata.labels

给 Pod 打标签

Pod;供 Service/selector 匹配


🚨 注意:这三者虽然可以一样,但职责不同,不能随便漏掉!

✅ 最关键的是 ② selector 和 ③ pod label 必须一致,否则 Deployment 会报错说 selector 和 template 不匹配。

问题二:

revisionHistoryLimit: 5 # 回滚历史版本保留数

strategy:

type: RollingUpdate

rollingUpdate:

maxSurge: 1 # 更新时最多多出一个 Pod

maxUnavailable: 1 # 更新时最多停一个 Pod
详细解释一下

🔁 revisionHistoryLimit: 5

revisionHistoryLimit: 5
✅ 作用
  • 控制 Deployment 最多保留多少个历史版本(replicaSet),以便可以进行回滚。
  • 比如你从 v1 → v2 → v3 → v4,这时旧版本(replicaSet)最多保留 5 个。
⚠️ 如果不设置或设置为 0:
  • 回滚会失效(无法 kubectl rollout undo
  • 生产环境推荐设置为 至少 2~10,视变更频率而定。

🧠 strategy.type: RollingUpdate

strategy:
  type: RollingUpdate
✅ 作用
  • 指定更新策略类型,默认就是 RollingUpdate
  • 也可以设置为 Recreate(会先杀掉所有旧 Pod,再启动新 Pod,不推荐用于生产)。

🔄 rollingUpdate.maxSurgemaxUnavailable

rollingUpdate:
  maxSurge: 1
  maxUnavailable: 1

这是滚动更新的关键控制参数,决定了更新时新增 Pod 数量和可同时中断的 Pod 数量


🔹 maxSurge: 1 → 最多可以“多出来”多少个 Pod
  • 表示更新时,临时允许新 Pod 超过原有副本数的最大数量
  • 可以是绝对值(如 1)或百分比(如 30%)。
  • 作用是加快新版本上线速度。

▶ 示例:
如果原来有 3 个副本 replicas: 3,更新时:

  • 最多可以变成 4 个 Pod 同时存在(旧 3 + 新 1)

🔸 maxUnavailable: 1 → 更新时最多“不可用”的旧 Pod 数
  • 表示滚动更新过程中,最多允许有多少个 Pod 是“不可用”的(被删或未 ready)。
  • 也是绝对值或百分比。

▶ 示例:

  • 如果是 maxUnavailable: 1,那在更新过程中,最多允许有 1 个 Pod 不可用。

🧩 总结一下更新流程(假设 replicas: 3)

更新阶段

Pod 状态变化

开始

原来 3 个旧 Pod 运行

第一步

创建 1 个新 Pod(总数 4,满足 maxSurge: 1

然后

杀掉 1 个旧 Pod(剩 3,满足 maxUnavailable: 1

重复上面

直到所有旧 Pod 替换为新版本

这样做的好处是:应用一直可用,用户几乎无感知


✅ 建议配置(企业生产推荐)

字段

推荐值

说明

revisionHistoryLimit

5~10

留有一定历史版本以便回滚

maxSurge

25%

or 1

允许多出来的 Pod 数

maxUnavailable

25%

or 1

容忍最多几个不可用 Pod

问题三:

lifecycle:

preStop:

exec: command: ["/bin/sh", "-c", "sleep 10"] # 下线前缓冲 解释一下这个内容

详细解释提供的这段 Kubernetes 容器生命周期钩子配置:


✅ 配置内容:

lifecycle:
  preStop:

      command: ["/bin/sh", "-c", "sleep 10"]  # 下线前缓冲

✅ 这个配置属于什么?

这是 Pod 生命周期钩子(Lifecycle Hooks) 的一部分,专门用于在容器被终止前执行一些操作。


preStop 是什么?

  • preStop 是容器在 终止前(删除 Pod、滚动更新、缩容等) 会调用的钩子。
  • 它的目的是:
    • 优雅下线处理,例如通知外部系统、退出注册中心、关闭连接等。
    • 给应用一些时间完成“收尾”工作。

command: ["/bin/sh", "-c", "sleep 10"] 是什么?

这表示:

  • 当容器即将被终止时,先执行:
/bin/sh -c "sleep 10"
  • 也就是说: 👉 Kubernetes 会等 10秒钟 才真正终止容器进程。

✅ 整体流程图解(举例):

  1. 你执行了 kubectl delete pod myapp-pod
  2. K8s 进入终止流程,触发容器的 preStop
    • 容器此时会先执行:sleep 10
  1. sleep 10 执行完后,才会发送 SIGTERM 给主容器进程。
  2. 等待容器正常退出(配合 terminationGracePeriodSeconds,比如默认 30 秒)。
  3. 如果容器仍未退出,就会强制发送 SIGKILL 杀掉它。

✅ 应用场景

需求

实现方式

通知外部:我要下线了

执行一个 curl 请求

服务从注册中心下线

执行一个注销命令

给业务一点缓冲时间(比如连接迁移)

sleep N

让其等待 N 秒


网站公告

今日签到

点亮在社区的每一天
去签到