概述重点(分几个部分学习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 来管
💡 举个真实例子(自愈场景)
- 你创建了一个 Deployment,副本数设置为 3。
- 控制器帮你启动了 3 个 Pod。
- 某个节点故障,挂了一个 Pod。
- 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):
- 你声明了期望运行
replicas: 3
。 - 控制器不断对比实际运行的 Pod 数量。
- 少了就启动,多了就删除,保持一致。
👉 注意: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 history
、kubectl rollout undo
能看到/回滚旧版本 ReplicaSet。
🧠 学习重点总结
模块 |
学什么 |
原理 |
ReplicaSet 是 Pod 副本数量的维持者 |
区别 |
它不支持滚动更新,Deployment 是它的“上层封装” |
实践 |
Deployment 的每次更新都会创建新的 ReplicaSet |
配置 |
必须配置 、 和 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 配置结构 |
、 、 等 |
滚动更新机制 |
默认按比例逐步替换旧 Pod |
命令行控制 |
系列操作 |
与 ReplicaSet 区别 |
一个高层封装,一个底层控制器 |
使用场景 |
用于所有无状态服务、Web 应用等部署场景 |
核心知识点
- YAML 结构
-
- 必填字段:
apiVersion
、kind
、metadata
、spec
(replicas
、selector
、template
)。 - 更新策略(
strategy
):RollingUpdate
(默认)或Recreate
(直接删除旧 Pod)。
- 必填字段:
- 滚动更新参数
-
maxSurge
:允许临时超出副本数的 Pod 数量(如 25% 或固定值)。maxUnavailable
:更新期间允许不可用的 Pod 数量。
- 版本控制与回滚
-
revisionHistoryLimit
:控制保留的历史 ReplicaSet 数量(默认 10)。- 使用
kubectl rollout
命令管理版本。
- 健康检查与就绪探针
-
- 确保新 Pod 就绪后再替换旧 Pod(需配置
readinessProbe
)。
- 确保新 Pod 就绪后再替换旧 Pod(需配置
- 故障排查
-
- 查看 Deployment 事件:
kubectl describe deployment <name>
。 - 常见问题:
- 查看 Deployment 事件:
-
-
- 镜像拉取失败(
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:
下的两个参数
参数 |
含义 |
解释 |
|
最多允许有1个Pod不可用 |
假设原来有3个 Pod,那最多能“临时缺少1个” |
|
最多额外多创建1个新Pod |
比如先启动一个新 Pod 再删旧的,避免服务中断 |
📌 总结一句话:
保证至少有两个 Pod 正常提供服务,一个在升级、一个在等删除。这样实现平滑更新。
🔥 面试可以这样说:
“使用 RollingUpdate
策略可以实现无中断部署(zero downtime),控制升级期间的可用性和资源浪费。”
🧲 selector
和 template.metadata.labels
—— 绑定 Pod 与 Deployment 的“配对钥匙”
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
这是 Kubernetes 的“标签选择机制”,两部分必须完全一致!
区域 |
含义 |
|
Deployment 会“寻找标签为 app=my-app 的 Pod” |
|
新创建 Pod 时,自动打上 标签 |
💡 为什么需要这个绑定?
- 让 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,无需指定节点名 |
兼容性 |
支持 、 来选择部署在哪些节点 |
跟 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 就部署上去了。
- 检查这个 Node 是否满足
💣 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 使用 |
新节点加入自动部署 |
Watch Node,自动 create Pod |
节点删除自动清理 |
Watch Node 状态和生命周期事件 |
不经过 Scheduler |
Pod 的 直接绑定,不用调度器 |
✅ 你需要掌握的关键点:
- DaemonSet 的 Pod 是不通过调度器调度的,而是由控制器直接指定
nodeName
。 - 使用场景明确:每个节点必须部署的系统组件。
- 控制器是核心:监听 Node 的变化自动增删 Pod。
- 可以结合 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 |
触发方式 |
手动或一次性触发 |
自动周期性触发 |
使用场景 |
初始化、数据清洗、备份 |
定时任务:备份、同步、报表 |
配置入口 |
|
|
控制字段 |
、 等 |
同样支持这些字段,也有 |
🧰 四、配置差异对比(关键点)
配置点 |
Job |
CronJob |
顶级 kind |
|
|
定时字段 |
无 |
|
模板结构 |
|
|
控制运行次数 |
, |
自动创建多个 Job 控制 |
清理策略 |
|
同样支持 |
📌 五、怎么用(流程建议)
操作 |
Job |
CronJob |
创建 |
|
同上 |
查看状态 |
|
|
查看 Job 日志 |
|
同样方式 |
强制运行一次 CronJob |
|
手动触发调试 |
删除任务 |
删除 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)
参数 |
类型 |
含义 |
|
int |
期望执行多少次 |
|
int |
同时允许多少个 Pod 并发执行 |
|
int |
失败后最多重试次数(默认 6) |
|
int |
Pod 最长运行时间,超时就失败 |
|
enum |
容器失败是否重启:Always / Never / OnFailure(Job 推荐 OnFailure) |
✅ 示例:
spec:
completions: 1
parallelism: 1
backoffLimit: 3
activeDeadlineSeconds: 600
⏱️ 定时调度专属参数(CronJob)
参数 |
类型 |
含义 |
|
string |
定时格式(cron) |
|
int |
允许延迟启动的最大秒数 |
|
enum |
并发策略:Allow / Forbid / Replace |
|
int |
保留成功历史数量 |
|
int |
保留失败历史数量 |
|
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 |
→ |
增加 字段 |
其他参数基本不变(如 backoffLimit、ttlSecondsAfterFinished) |
✅ 最佳实践建议
目的 |
建议做法 |
定时任务 |
CronJob + concurrencyPolicy |
任务超时限制 |
Job + activeDeadlineSeconds |
自动清理 |
ttlSecondsAfterFinished |
多环境配置 |
ConfigMap + Secret + volumeMounts |
备份类任务 |
Job + PVC 持久化结果 |
调试 CronJob |
|
statefulset
初学先了解 ,认真搞好 deployment
总结:
StatefulSet 是为有状态服务设计的控制器,用的是server 无头服务的网络模式,能够保持每个 Pod 的身份(名字、IP、存储)不变,适用于数据库、消息队列、分布式存储等。
一、什么是 StatefulSet?
StatefulSet
是 Kubernetes 中的一种控制器,用于管理有状态服务的部署和扩缩容,它能够保证:
特性 |
说明 |
稳定的网络标识 |
每个 Pod 有唯一不变的 DNS 名(如: 、 ) |
稳定的存储 |
每个 Pod 拥有自己的 PVC(不会随着 Pod 删除而清除) |
有序部署与删除 |
按照顺序启动或终止( ) |
有序滚动更新 |
一次更新一个,防止全挂 |
二、它是用来干什么的?
用来管理有状态服务,也就是:
每个实例(Pod)都有自己的唯一身份和数据,不能随便丢。
最常见的例子就是:
应用类型 |
说明 |
🐘 数据库集群(MySQL、PostgreSQL、Redis 主从) |
每个节点数据不能共享 |
📦 消息队列(Kafka、RabbitMQ) |
有状态的消息分片 |
🔎 分布式存储(Ceph、Elasticsearch) |
每个节点保存不同分片 |
🧠 Zookeeper、Etcd |
要保持节点 ID 不变 |
三、和 Deployment 有什么区别?
对比项 |
Deployment |
StatefulSet |
Pod 名字 |
随机,例如 |
固定,例如 、 |
网络 DNS |
不保证唯一 |
保证,如 |
存储卷 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 的重点解释:
字段 |
作用 |
|
对应的 Headless Service(作用是提供 DNS) |
|
副本数量,比如你要部署 3 个 MySQL 节点 |
|
自动为每个 Pod 创建专属 PVC(如 ) |
Pod 名 |
将自动生成为: , ... |
🧠 StatefulSet 工作机制:
- 创建 Headless Service(
ClusterIP: None
) → 提供 DNS - StatefulSet 创建 Pod:
mysql-0
→mysql-1
→ ... - 每个 Pod 拥有:
-
- 独立 DNS(如
mysql-0.mysql.default.svc.cluster.local
) - 独立存储卷(
mysql-persistent-storage-mysql-0
)
- 独立 DNS(如
- 删除 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 |
应用配置 |
|
Secret |
账号密码等 |
|
Ingress |
域名访问路由 |
|
PVC |
持久存储 |
|
Prometheus 监控探针 |
监控 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
✅ 总结表格
位置 |
作用 |
是否必须 |
影响对象 |
|
标记 Deployment 本身 |
❌(推荐) |
Deployment |
|
用于匹配 Pod |
✅ |
Deployment 管理哪个 Pod |
|
给 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.maxSurge
和 maxUnavailable
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,满足 ) |
然后 |
杀掉 1 个旧 Pod(剩 3,满足 ) |
重复上面 |
直到所有旧 Pod 替换为新版本 |
这样做的好处是:应用一直可用,用户几乎无感知。
✅ 建议配置(企业生产推荐)
字段 |
推荐值 |
说明 |
|
5~10 |
留有一定历史版本以便回滚 |
|
or |
允许多出来的 Pod 数 |
|
or |
容忍最多几个不可用 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秒钟 才真正终止容器进程。
✅ 整体流程图解(举例):
- 你执行了
kubectl delete pod myapp-pod
- K8s 进入终止流程,触发容器的
preStop
:
-
- 容器此时会先执行:
sleep 10
- 容器此时会先执行:
- 等
sleep 10
执行完后,才会发送SIGTERM
给主容器进程。 - 等待容器正常退出(配合
terminationGracePeriodSeconds
,比如默认 30 秒)。 - 如果容器仍未退出,就会强制发送
SIGKILL
杀掉它。
✅ 应用场景
需求 |
实现方式 |
通知外部:我要下线了 |
执行一个 curl 请求 |
服务从注册中心下线 |
执行一个注销命令 |
给业务一点缓冲时间(比如连接迁移) |
让其等待 N 秒 |