1. 引言:当容器崩溃时,Kubernetes如何“急救”?
想象一下你正在运营一家7x24小时营业的连锁餐厅,每个服务员(容器)负责处理顾客请求。如果某个服务员突然晕倒(容器崩溃),你是立刻换人顶替(重启容器)、等他自己缓过来再干活(仅在失败时重启),还是干脆让他回家(不重启)?Kubernetes的重启策略(Always
、OnFailure
、Never
)就像这家餐厅的应急预案,本文将用真实场景解析其设计哲学和配置技巧。
2. 三种重启策略的核心逻辑
2.1 Always:无脑重启的“永动机模式”
核心行为:无论容器以什么状态退出(成功或失败),都会无限重启。
适用场景:长期运行的Web服务、API服务器等需要高可用的场景。
示例:使用Deployment部署的Web服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.21
livenessProbe:
httpGet:
path: /
port: 80
restartPolicy: Always # 无论成功或失败,始终保持容器运行
陷阱预警:如果容器因代码逻辑错误频繁崩溃,可能导致无限重启循环。此时需结合资源限制(如livenessProbe
或resource.limits
)防止雪崩。
2.2 OnFailure:理性修复的“智能管家模式”
核心行为:仅当容器以非0状态码退出时(即程序主动报错),才会触发重启。
适用场景:离线批处理任务、数据分析任务等需要容错的场景。
示例:单次数据分析任务
apiVersion: batch/v1
kind: Job
metadata:
name: data-processor
spec:
template:
spec:
containers:
- name: processor
image: python:3.9
command: ["python", "batch_processing.py"]
# 设置重试次数上限(避免无限重试)
restartPolicy: OnFailure # 仅在处理失败时重启
backoffLimit: 4 # 最多尝试4次(含初次运行)
关键细节:
backoffLimit
与restartPolicy: OnFailure
配合使用,控制最大重试次数。- 若脚本以
sys.exit(0)
退出(即使逻辑错误),不会触发重启!需严格规范错误码设计。
2.3 Never:放任自由的“甩手掌柜模式”
核心行为:无论成功或失败,容器退出后都不重启。
适用场景:一次性任务、调试场景或由外部系统管理生命周期的场景。
示例:临时数据备份任务
apiVersion: batch/v1
kind: Job
metadata:
name: nightly-backup
spec:
template:
spec:
containers:
- name: backup-agent
image: alpine/s3-cp
command: ["./backup.sh"]
restartPolicy: Never # 执行一次后无论结果如何都不重启
restartPolicy: Never # Job的Pod模板必须显式声明Never!
特殊限制:
- Deployment/DaemonSet不支持Never策略(因为与控制器职责冲突)。
- 可用于创建“一次性”Pod(直接通过
kubectl run
),例如临时调试:
kubectl run debug-pod --image=busybox --restart=Never -- -- /bin/sh -c "sleep 30"
3. 重启策略的隐形搭档:那些必须了解的关联技术
3.1 健康检查(Liveness/Readiness Probe)
重启策略的“指挥官”——如果容器进程还在运行但实际已瘫痪,只有健康检查能发现并触发重启。
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15 # 容器启动后15秒开始探测
periodSeconds: 5 # 每5秒检查一次
failureThreshold: 3 # 连续失败3次判定为不健康
经典错误:
- 忘记设置
initialDelaySeconds
,导致容器在启动阶段被误杀。 - 探测频率过高(
periodSeconds: 1
)引发性能问题。
3.2 资源配额(Resource Limits)
避免无限重启的核心防线:限制CPU/内存用量,防止单个Pod占用过多资源。
resources:
limits:
memory: "512Mi"
cpu: "1"
requests:
memory: "256Mi"
cpu: "0.5"
经验法则:
- 当容器因OOM(内存溢出)被杀死时,会触发重启(具体行为由策略决定)。
- 资源配置不合理可能导致频繁OOM,叠加
Always
策略形成死循环。
4. 策略选型的三大黄金法则
法则1:区分“瞬时故障”与“永久故障”
- 瞬时故障(如网络抖动):适合
Always
或OnFailure
自动恢复。 - 永久故障(如代码缺陷):需人工介入,否则重启只会掩盖问题。
法则2:Controller类型决定策略选项
- Deployment/DaemonSet:只能选择
Always
(控制器负责维持副本数)。 - Job/CronJob:可选
OnFailure
或Never
。 - 裸Pod:三者皆可,但实际生产环境极少直接使用。
法则3:监控重启次数,防止“无效劳动”
通过kubectl describe pod
查看重启历史:
Containers:
my-container:
Restart Count: 5 # 重要指标!突然飙升可能预示问题
诊断命令合集:
# 查看Pod重启次数
kubectl get pods --field-selector=status.phase=Running --show-labels
# 查看最近5次重启的Pod事件
kubectl get events --sort-by=.metadata.creationTimestamp | grep "BackOff"
5. 高频问题攻防战:避坑指南
问题1:Job任务失败后持续重启,无法终止
根本原因:未设置backoffLimit
或阈值过大(默认6次)。
解决步骤:
- 为Job添加
backoffLimit: 3
等明确上限。 - 在日志中查找
Error: job has failed...
确认退出原因。
问题2:Pod频繁重启但无错误日志
排查路径:
- 检查
livenessProbe
配置是否过于敏感(例如检测路径错误)。 - 通过
kubectl logs --previous
查看崩溃前最后一次日志。 - 检查节点资源是否充足(
kubectl describe node
)。
6. 总结:重启策略的设计哲学
- Always是默认的安全网,但需配合健康检查防止滥用。
- OnFailure在自动化和人工干预间找到平衡点。
- Never将控制权完全交还给开发者,适合高阶场景。
通过合理选择策略,你的Kubernetes集群将像一支训练有素的特种部队——既能在故障面前快速反应,又不会因盲目行动浪费资源。
评论