Kubernetes 资源与健康检查
requests 与 limits
yaml
resources:
requests:
cpu: 250m
memory: 256Mi
ephemeral-storage: 512Mi
limits:
cpu: "1"
memory: 512Mi
ephemeral-storage: 2Girequests用于调度、容量预留和 CPU 权重。- CPU limit 通常由 CFS 配额节流;超限不会直接杀进程。
- memory limit 是硬边界,超限可能 OOM Kill。
- 临时存储包括可写层、容器日志和
emptyDir(具体计量受运行时/节点布局影响)。 1 CPU在裸机/虚机上代表一个逻辑 CPU;100m是 0.1 CPU。- 内存用
Mi/Gi;400m内存是 0.4 字节,不是 400Mi。
只设 limits、不设 requests 时,命名空间 LimitRange 及默认规则可能补全请求;不要依赖隐式行为,显式设置并检查最终 PodSpec。
如何确定资源值
- 收集至少一个有代表性的业务周期指标。
- 区分常态、峰值、启动和故障重试。
- requests 反映调度需要的稳定保障,不等于平均值机械取整。
- 内存 limit 留出堆外、Page Cache、线程栈和短时峰值。
- 压测验证延迟、节流、OOM 和扩缩容反馈。
- 上线后用实际指标持续调整,并记录依据。
CPU limit 对延迟敏感服务可能造成节流;是否设置需遵循平台策略和隔离要求。不要简单移除所有 limits,也不要把 request/limit 设成同一个随意的大数。
Pod QoS
| QoS | 条件概览 | 资源压力下特征 |
|---|---|---|
| Guaranteed | 每个容器 CPU/内存 request 等于 limit,且均设置 | 相对最后被驱逐,但不保证永不 OOM |
| Burstable | 至少有请求/限制,但不满足 Guaranteed | 依据使用超出 request 等因素排序 |
| BestEffort | 所有容器都未设置 CPU/内存 request/limit | 资源压力下优先被驱逐 |
bash
kubectl -n demo get pod web-abc -o jsonpath='{.status.qosClass}{"\n"}'QoS 不是业务优先级;它与 PriorityClass、节点压力驱逐和 OOM 决策共同作用。
LimitRange 与 ResourceQuota
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: container-defaults
namespace: demo
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 128Mi
default:
memory: 512Mi
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-budget
namespace: demo
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.memory: 80Gi
pods: "200"Quota 控制总量,LimitRange 控制/默认单对象范围。查看使用量:
bash
kubectl -n demo describe resourcequota
kubectl -n demo describe limitrange三种探针
| 探针 | 失败效果 | 用途 |
|---|---|---|
| startupProbe | 启动未成功前不运行 liveness/readiness;持续失败会重启 | 慢启动应用 |
| livenessProbe | 达阈值后重启容器 | 检测无法自愈的死锁/卡死 |
| readinessProbe | 从 Service 端点移除,不重启 | 判断能否接收流量 |
yaml
startupProbe:
httpGet:
path: /startupz
port: http
periodSeconds: 5
failureThreshold: 60
livenessProbe:
httpGet:
path: /livez
port: http
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
readinessProbe:
httpGet:
path: /readyz
port: http
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2
successThreshold: 1探针可使用 HTTP、TCP、gRPC 或 exec。exec 探针频繁启动进程会有额外开销;命令必须有确定超时和退出码。
探针设计
- Liveness 只检测本进程是否不可恢复,不要依赖数据库、DNS 或所有下游;否则下游故障会触发重启风暴。
- Readiness 可反映必要依赖,但应快速、稳定、有超时,避免一个可选依赖让全服务下线。
- Startup 为初始化留出最大
failureThreshold × periodSeconds窗口,不要靠巨大 liveness 延迟掩盖慢启动。 - 健康端点不返回密钥和详细内部信息。
- 探针由 kubelet直接访问 Pod,行为可能与 Service/Ingress 请求不同。
- 探针成功只是一个信号;发布还应运行端到端冒烟测试。
容器重启与状态
bash
kubectl -n demo get pod web-abc \
-o jsonpath='{range .status.containerStatuses[*]}{.name}{"\t"}{.restartCount}{"\t"}{.state}{"\n"}{end}'
kubectl -n demo logs web-abc -c web --previous
kubectl -n demo describe pod web-abcPod restartPolicy 对普通容器为 Always、OnFailure 或 Never;由 Deployment 管理的 Pod 通常为 Always。CrashLoopBackOff 是指数退避状态,不是根因,必须看退出码、Reason、上一次日志和 Event。
优雅终止
删除 Pod 时通常发生:
- API 对象进入 Terminating。
- EndpointSlice/流量路径逐步撤出端点。
- kubelet 执行
preStop(如配置),向容器 PID 1 发送 TERM。 - 等待
terminationGracePeriodSeconds。 - 超时后强制 KILL。
yaml
spec:
terminationGracePeriodSeconds: 45
containers:
- name: web
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]应用应在收到 TERM 后停止接新请求、完成/取消在途工作、刷新必要状态并在时限内退出。preStop 时间计入 grace period;盲目 sleep 只是给传播留时间,仍需应用正确处理信号。
PID 1 若 shell 包裹而不转发信号,会破坏优雅终止。容器入口用 exec 形式或合适 init 进程。
OOM、CPU 节流与驱逐
bash
kubectl -n demo describe pod web-abc
kubectl -n demo get pod web-abc -o json | jq '.status.containerStatuses[].lastState'
kubectl describe node worker-01
kubectl top pod web-abc -n demo --containersOOMKilled:检查 limit、进程峰值、泄漏和节点 OOM 证据。- CPU throttling:结合容器节流指标和延迟,
top的瞬时 CPU不足以判断。 Evicted:检查 Node Condition(MemoryPressure、DiskPressure、PIDPressure)和 Event。- ephemeral-storage 超限或节点磁盘压力会驱逐 Pod;日志无限增长是常见原因。
健康与资源检查清单
- requests 来自测量并覆盖启动、峰值和滚动发布容量。
- memory limit 经过 OOM/压力测试,CPU 策略符合延迟 SLO。
- startup/liveness/readiness 职责分离,不会放大依赖故障。
- 应用正确处理 TERM,终止时限覆盖最长合法在途请求。
- 监控重启、OOM、节流、工作集、临时存储、探针失败和驱逐。
- 命名空间配额预留发布 Surge、Job 和故障恢复空间。
继续阅读
- 命令
- 故障排查
- 故障排查