深入理解Kubernetes Pod生命周期与资源管理:从创建到优雅终止
导读:Pod 是 Kubernetes 中最小的调度单元,理解 Pod 的完整生命周期是掌握 K8S 的基石。本文将从 Pod 的创建流程、资源限制机制、生命周期钩子、优雅终止策略四大维度,结合真实的生产级 YAML 配置和命令输出,带你彻底搞懂 Pod 从"出生"到"死亡"的全过程。无论你是准备面试还是日常运维排障,这篇文章都值得收藏。
一、Pod 的创建流程
当你执行 kubectl apply -f deployment.yaml 时,K8S 集群背后到底发生了什么?理解这个流程,是排查 Pod 启动失败、调度异常等问题的前提。
1.1 完整创建流程
用户执行 kubectl apply
│
▼
┌─────────────────────┐
│ ① API Server │ 接收请求,进行认证、鉴权、准入控制
│ (认证→鉴权→准入) │ 将 Pod 信息持久化存储到 etcd
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ ② Scheduler │ 通过 List-Watch 机制监听到新 Pod
│ (调度器) │ 根据调度策略(资源、亲和性、污点等)选择 Node
└─────────┬───────────┘
│ binding(绑定)
▼
┌─────────────────────┐
│ ③ kubelet │ 目标节点的 kubelet 监听到绑定到自己节点的 Pod
│ (节点代理) │ 调用 CRI(容器运行时接口)创建容器
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ ④ Container │ 拉取镜像 → 启动容器 → 执行 postStart 钩子
│ Runtime │ 执行健康检查(startupProbe → livenessProbe/readinessProbe)
└─────────────────────┘
│
▼
Pod Running ✅
1.2 Pod 状态机
Pod 在整个生命周期中会经历多个状态,了解每个状态的含义是排障的第一步:
| 状态 | 含义 | 常见原因 |
|---|---|---|
| Pending | Pod 已被 K8S 接受,但尚未被调度到 Node | 资源不足、节点亲和性不匹配、污点容忍不满足 |
| ContainerCreating | 容器正在创建中(拉取镜像、挂载存储卷) | 镜像过大拉取慢、私有仓库认证失败 |
| Running | Pod 已绑定到 Node,至少一个容器正在运行 | 正常状态 |
| CrashLoopBackOff | 容器反复崩溃退出后自动重启,并增加退避时间 | 应用启动失败、配置错误、端口冲突 |
| ImagePullBackOff | 镜像拉取失败,正在重试 | 镜像名错误、私有仓库未配置认证 |
| Terminating | Pod 正在被终止,执行 preStop 钩子中 | 正常删除或滚动更新时 |
| Completed | 所有容器已正常退出 | 一次性任务(Job)执行完毕 |
排障提示 :当 Pod 处于异常状态时,第一反应应该是
kubectl describe pod <name>查看 Events 部分,这里有最详细的失败原因。
1.3 Pod 的修改流程
当你修改了 Deployment 的镜像版本(如 v1 → v2),触发的是滚动更新流程:
用户修改 Deployment 镜像版本
│
▼
┌─────────────────────┐
│ ① API Server │ 更新 Deployment 对象
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ ② Controller │ Deployment Controller 检测到差异
│ Manager │ 创建新的 ReplicaSet(v2),逐步调整新旧 RS 副本数
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ ③ RS Controller │ 新 RS 创建新 Pod → 旧 Pod 收到终止信号
│ (滚动更新) │ 遵循 maxSurge 和 maxUnavailable 策略
└─────────┬───────────┘
│
▼
新 Pod 就绪 → 旧 Pod 终止 → 完成 ✅
1.4 Pod 的删除流程
Pod 的删除不是"一刀切"的,K8S 设计了一套优雅终止机制:
用户执行 kubectl delete pod
│
▼
┌──────────────────────────────────────┐
│ ① Pod 被标记为 "Terminating" │
│ 此时不接受新的请求 │
└─────────┬────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ ② 执行 preStop 钩子 │
│ (如:通知负载均衡器摘除流量) │
└─────────┬────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ ③ 发送 SIGTERM 信号给主进程 │
│ 应用开始处理完现有请求后优雅退出 │
└─────────┬────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ ④ 等待 terminationGracePeriodSeconds │
│ (默认 30 秒超时) │
└─────────┬────────────────────────────┘
│
┌────┴────┐
│ │
正常退出 超时未退出
│ │
▼ ▼
Pod 删除 发送 SIGKILL 强制杀死
二、资源限制:requests 与 limits
2.1 为什么必须配置资源限制?
如果不为 Pod 配置资源限制,容器可以使用所在 Node 的全部资源(CPU、内存、GPU)。这会带来严重的后果:
- 资源争抢:一个"贪吃"的 Pod 可能吃光节点资源,导致同节点的其他 Pod 被驱逐
- 安全风险:容器被入侵后,攻击者可以消耗节点全部资源,造成 DoS 攻击
- 调度失控:Scheduler 无法准确评估节点负载,导致调度决策失误
2.2 requests 与 limits 的区别
| 配置项 | 作用 | 调度影响 | 超出后行为 |
|---|---|---|---|
| requests | 容器的期望资源量(保障最低资源) | Scheduler 按 requests 进行调度,节点可用资源 ≥ requests 才能调度成功 | 容器可以使用超出 requests 的资源(前提是 limits 未设或更大) |
| limits | 容器的资源使用上限 | 不影响调度决策 | CPU 被限流(throttle),内存超出则 OOMKilled |
关键规则 :
requests ≤ limits。如果只设置了 limits 而未设置 requests,requests 默认等于 limits。
2.3 CPU 单位换算
K8S 中 CPU 资源以核心数为单位,支持以下写法:
yaml
# 以下四种写法等价,都表示 0.5 核 CPU
cpu: 0.5
cpu: 500m
# 以下表示 4 核 CPU
cpu: 4
cpu: 4000m
m 是 millicores(毫核)的缩写,1000m = 1 core。
2.4 内存单位换算
yaml
# 纯数字表示字节数
memory: 209715200 # 200Mi
# 常见单位(注意大小写敏感)
memory: 200Mi # 200 Mebibytes = 200 × 1024 × 1024 bytes(推荐)
memory: 200M # 200 Megabytes = 200 × 1000 × 1000 bytes(不推荐)
memory: 1Gi # 1 Gibibytes = 1024Mi
memory: 500Ki # 500 Kibibytes
注意 :K8S 中推荐使用
Mi/Gi(二进制前缀,1024进位),而非M/G(十进制前缀,1000进位)。
2.5 实战:仅配置 requests
yaml
# deploy-resources-requests.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-resources-requests
spec:
replicas: 3
selector:
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
version: v1
spec:
containers:
- name: c1
image: harbor250.test.com/test-tools/stress:v0.1
command: [tail, -f, /etc/hosts]
resources:
requests:
cpu: 200m # 调度时保证至少 0.2 核
memory: 200Mi # 调度时保证至少 200Mi 内存
bash
kubectl apply -f deploy-resources-requests.yaml
# 验证 Pod 正常运行
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
deploy-resources-requests-855f68686d-lf2sr 1/1 Running 0 2m 10.100.2.192
deploy-resources-requests-855f68686d-prvj5 1/1 Running 0 2m 10.100.2.193
deploy-resources-requests-855f68686d-zd8cp 1/1 Running 0 2m 10.100.1.157
注意 :仅配置 requests 时,容器可以使用超出 requests 的资源,因为没有 limits 上限限制。这意味着在压力测试中,容器可能占用节点大量资源。
2.6 实战:同时配置 requests 和 limits
yaml
# deploy-resources-limits.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-resources-requests-limits
spec:
replicas: 3
selector:
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
version: v1
spec:
containers:
- name: c1
image: harbor250.test.com/test-tools/stress:v0.1
command: [tail, -f, /etc/hosts]
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 200m # 硬上限:最多使用 0.2 核
memory: 500Mi # 硬上限:最多使用 500Mi 内存
bash
kubectl apply -f deploy-resources-limits.yaml
内存超限的实际表现------当我们在容器内执行压力测试,让内存使用超过 500Mi 上限:
bash
# 进入容器执行压力测试
kubectl exec -it deploy-resources-requests-limits-74945b7cbf-dfkxr -- sh
# 启动 stress 压测,尝试占用超过 500Mi 的内存
stress --cpu 8 --io 4 --vm 4 --vm-bytes 128M --timeout 10m --vm-keep
在宿主机上通过 docker stats 观察容器资源使用情况:
# 内存使用接近上限时
CONTAINER ID CPU % MEM USAGE / LIMIT MEM %
da2e1fb8d4ff 20.32% 475.4MiB / 500MiB 95.08%
# 内存超限后,容器被 OOM Kill 重启
CONTAINER ID CPU % MEM USAGE / LIMIT MEM %
da2e1fb8d4ff 12.18% 576KiB / 500MiB 0.11% ← 内存归零,进程被杀
2.7 CPU 和内存超限的行为差异
这是面试高频考点,务必牢记:
| 资源类型 | 超出 limits 的行为 | 是否可恢复 |
|---|---|---|
| CPU | 被限流(throttle),容器变慢但不会被杀 | 是,降低负载后自动恢复 |
| 内存 | 容器进程被 OOM Killed,Pod 重启 | 是,Pod 自动重启(CrashLoopBackOff) |
生产建议 :CPU 的 requests 和 limits 可以不同(QoS 为 Burstable),但内存的 requests 和 limits 建议保持一致,避免内存超限导致的 OOM Kill 频繁重启。
2.8 QoS 服务质量等级
K8S 根据 Pod 的资源配置,将其分为三个 QoS 等级,在节点资源紧张时决定了谁先被驱逐:
| QoS 等级 | 配置特征 | 驱逐优先级 |
|---|---|---|
| Guaranteed(保证) | 每个容器都设置了 requests = limits(CPU 和内存) | 最低,最后被驱逐 |
| Burstable(弹性) | 至少一个容器设置了 requests 或 limits,但不满足 Guaranteed | 中等 |
| BestEffort(尽力而为) | 没有容器设置任何 requests 或 limits | 最高,最先被驱逐 |
yaml
# Guaranteed 示例:requests 和 limits 完全一致
resources:
requests:
cpu: 200m
memory: 500Mi
limits:
cpu: 200m
memory: 500Mi
三、生命周期钩子:postStart 与 preStop
K8S 为容器提供了两个生命周期钩子(Lifecycle Hooks),允许在容器启动和停止时执行自定义操作。
3.1 钩子类型
| 钩子 | 触发时机 | 常见用途 |
|---|---|---|
| postStart | 容器创建后立即执行(与主进程并行) | 初始化配置、注册服务、预热缓存 |
| preStop | 容器被终止前执行 | 优雅关闭连接、通知下游、清理临时文件 |
3.2 钩子实现方式
支持两种方式实现钩子:
- exec:在容器内执行命令
- httpGet:向容器发起 HTTP 请求
3.3 生产级实战:优雅终止配置
以下是一个完整的生产级配置,包含 postStart 和 preStop 钩子,以及优雅终止的超时控制:
yaml
# deploy-termination.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-termination-demo
spec:
revisionHistoryLimit: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
replicas: 1
selector:
matchLabels:
apps: xiuxian
template:
metadata:
labels:
apps: xiuxian
spec:
volumes:
- name: dt
hostPath:
path: /etc/localtime
- name: data
nfs:
server: 10.0.0.250
path: /test/data/nfs-server/casedemo/lifecycle
# 优雅终止宽限期:默认30秒,这里设置为60秒
terminationGracePeriodSeconds: 60
containers:
- name: c1
image: registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.21
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
- name: dt
mountPath: /etc/localtime
env:
# 通过 Downward API 将 Pod 元信息注入环境变量
- name: pod_name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: pod_ip
valueFrom:
fieldRef:
fieldPath: status.podIP
# 定义容器生命周期
lifecycle:
# 容器启动后执行:写入启动日志
postStart:
exec:
command:
- "/bin/sh"
- "-c"
- >
sleep 30;
echo "${pod_name} --- ${pod_ip} postStart at $(date +%F_%T)"
> /usr/share/nginx/html/index.html
# 容器停止前执行:写入终止日志
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- >
sleep 20;
echo "${pod_name} --- ${pod_ip} preStop at $(date +%F_%T)"
>> /usr/share/nginx/html/index.html
3.4 验证生命周期钩子执行
bash
# 部署
kubectl apply -f deploy-termination.yaml
# 观察Pod状态(postStart中sleep 30秒,所以初始会显示0/1)
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE
deploy-termination-grace-period-seconds-d679bd564-g5c6z 0/1 ContainerCreating 0 8s
# 等待postStart完成后变为Running
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE
deploy-termination-grace-period-seconds-d679bd564-g5c6z 1/1 Running 0 37s
# 验证postStart是否写入文件
curl 10.100.2.38
deploy-termination-grace-period-seconds-d679bd564-g5c6z --- 10.100.2.38 postStart at 2025-12-07_15:13:59
3.5 验证优雅终止过程
bash
# 删除Pod,观察终止过程
kubectl delete -f deploy-termination.yaml
# 观察Pod进入Terminating状态
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE
deploy-termination-grace-period-seconds-d679bd564-g5c6z 1/1 Terminating 0 3m4s
此时 Pod 会经历以下过程:
- Pod 被标记为 Terminating
- 执行 preStop 钩子(sleep 20秒 + 写入日志)
- 发送 SIGTERM 信号给容器主进程
- 等待容器优雅退出(最长 60 秒)
- 如果 60 秒内未退出,发送 SIGKILL 强制终止
关键配置 :
terminationGracePeriodSeconds的值必须大于 preStop 钩子的执行时间,否则 preStop 还没执行完就会被 SIGKILL 强杀。
3.6 postStart 的陷阱
postStart 钩子与容器主进程是并行执行的,这是一个常见的认知误区:
容器启动
├── 主进程启动(如 nginx)
└── postStart 钩子并行执行(如 sleep 30)
│
│ 注意:如果 postStart 执行时间很长,
│ 主进程并不会等待它完成!
│
▼
postStart 完成
这意味着:
- postStart 不能用来做"主进程启动前的阻塞等待"
- 如果 postStart 执行失败,容器会被杀死并重启
- ReadinessProbe 可能会在 postStart 完成前就开始探测,导致 Service 将未就绪的 Pod 纳入后端
解决方案 :配合 initialDelaySeconds 让探针延迟检测:
yaml
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 35 # 等待 postStart(30s sleep)完成后再开始探测
periodSeconds: 3
四、Pod 优雅终止的最佳实践
4.1 为什么优雅终止如此重要?
在滚动更新或 Pod 重启时,如果旧 Pod 被强制杀死(SIGKILL),会导致:
- 正在处理的请求丢失------用户看到 502 或 500 错误
- 数据库连接未关闭------产生大量 TIME_WAIT 连接
- 消息队列中的消息重复消费或丢失
- 临时文件未清理------占用磁盘空间
4.2 优雅终止配置清单
一个完善的优雅终止配置需要包含以下要素:
yaml
spec:
terminationGracePeriodSeconds: 60 # 1. 足够的宽限期
containers:
- name: app
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- "sleep 10" # 2. preStop中等待,确保Service已摘除流量
ports:
- name: web
containerPort: 8080
# 3. 配置探针,确保应用真正可用
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
4.3 优雅终止时序图
时间 ──────────────────────────────────────────────────────────────►
│ 0s │ 10s │ 20s │ 40s │ 60s │
│ │ │ │ │ │
│ Pod标记 │ preStop │ SIGTERM │ 应用处理 │ 超时 │
│ Terminating│ 开始执行 │ 发送给 │ 完成请求 │ SIGKILL │
│ │ sleep 10 │ 主进程 │ 优雅退出 │ 强制杀死 │
│ │ │ │ │ │
│ ◄─ 等待 ──►│◄─ 预留 ───►│◄── 应用优雅退出窗口 ──────────────►│
│ │ │ │ │ │
│ Service │ Endpoints │ 容器仍在 │ 容器退出 │ 强制清理 │
│ 移除Pod │ 移除Pod IP │ 处理请求 │ │ │
关键时间关系 :terminationGracePeriodSeconds ≥ preStop执行时间 + 应用优雅退出时间
4.4 各类应用的优雅退出建议
| 应用类型 | 建议宽限期 | preStop 配置 | 应用侧配置 |
|---|---|---|---|
| Web 服务(Nginx/Tomcat) | 30-60s | sleep 5(等待 Endpoints 更新) |
配置 graceful shutdown |
| 数据库(MySQL/PG) | 60-120s | 不需要 | 设置 innodb_fast_shutdown |
| 消息队列消费者 | 60-90s | sleep 5 |
完成当前消息处理后再 ack |
| 长连接服务(WebSocket/gRPC) | 30-60s | sleep 10 |
通知客户端断连 |
五、健康检查探针详解
探针是 K8S 判断容器健康状态的机制,与 Pod 生命周期紧密相关。
5.1 三种探针对比
| 探针 | 用途 | 失败后的行为 |
|---|---|---|
| startupProbe | 判断应用是否启动完成(解决慢启动问题) | 容器被杀死重启 |
| livenessProbe | 判断应用是否存活(是否"挂了") | 容器被杀死重启 |
| readinessProbe | 判断应用是否就绪(能否接收流量) | Pod 从 Service 摘除(不杀死) |
5.2 探针通用参数
yaml
livenessProbe:
httpGet: # 检测方式:HTTP请求
path: /health
port: 8080
httpHeaders:
- name: Custom-Header
value: custom-value
initialDelaySeconds: 30 # 容器启动后延迟多久开始检测
periodSeconds: 10 # 检测间隔(默认10s)
timeoutSeconds: 5 # 单次检测超时时间(默认1s)
successThreshold: 1 # 连续成功N次视为成功(默认1)
failureThreshold: 3 # 连续失败N次视为失败(默认3)
5.3 startupProbe 解决慢启动
对于启动较慢的应用(如 Java Spring Boot),如果 initialDelaySeconds 设置太小,livenessProbe 会在应用启动期间就开始检测,导致频繁重启:
yaml
# 配合 startupProbe 使用:启动阶段只检测 startupProbe
startupProbe:
httpGet:
path: /actuator/health
port: 8080
failureThreshold: 30 # 最多允许失败30次
periodSeconds: 10 # 每10s检测一次
# 即:最多等待 30 × 10 = 300 秒启动时间
# 启动完成后,由 livenessProbe 接管
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
periodSeconds: 10
5.4 探针检测方式
除了 httpGet,还支持其他检测方式:
yaml
# 方式一:HTTP GET(最常用)
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
# 方式二:TCP Socket(适合数据库等非HTTP服务)
livenessProbe:
tcpSocket:
port: 3306
# 方式三:Exec(在容器内执行命令)
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
# 方式四:gRPC(K8S 1.24+)
livenessProbe:
grpc:
port: 9090
service: myservice
六、Secret 敏感数据管理
6.1 Secret 的用途与类型
Secret 用于存储敏感数据(密码、Token、证书等),数据以 Base64 编码存储在 etcd 中。
| 类型 | 用途 |
|---|---|
kubernetes.io/dockerconfigjson |
Docker/Harbor 私有仓库认证 |
kubernetes.io/tls |
TLS 证书 |
Opaque |
通用类型,自定义键值对 |
6.2 Harbor 私有仓库认证实战
当 Harbor 项目设置为私有后,K8S 拉取镜像会报错 ErrImagePull。解决方案是创建 docker-registry 类型的 Secret:
方式一:响应式创建
bash
kubectl create secret docker-registry harbor-admin \
--docker-username=admin \
--docker-password=Harbor12345 \
--docker-email=admin@example.com \
--docker-server=harbor.example.com
方式二:声明式创建(推荐,便于版本管理)
yaml
apiVersion: v1
kind: Secret
metadata:
name: harbor-admin
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: '{"auths":{"harbor.example.com":{"auth":"YWRtaW46SGFyYm9yMTIzNDU="}}}'
提示 :
auth字段的值是username:password的 Base64 编码。可以使用echo -n 'admin:Harbor12345' | base64获取。
6.3 在 Pod 中引用 Secret
方式一:通过 imagePullSecrets 引用(直接在 Pod 级别指定)
yaml
spec:
imagePullSecrets:
- name: harbor-admin
containers:
- name: app
image: harbor.example.com/myproject/app:v1
方式二:通过 ServiceAccount 绑定(推荐,实现认证复用)
yaml
# 1. 创建 ServiceAccount 并绑定 Secret
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-harbor
imagePullSecrets:
- name: harbor-admin
---
# 2. Pod 中指定 ServiceAccount
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-app
spec:
template:
spec:
serviceAccountName: sa-harbor # 使用自定义SA替代default
containers:
- name: app
image: harbor.example.com/myproject/app:v1
优势 :通过 SA 绑定后,所有使用该 SA 的 Pod 都自动获得 Harbor 认证能力,无需在每个 Pod 中重复配置
imagePullSecrets。
七、面试高频知识点总结
7.1 Pod 生命周期关键问题
| 问题 | 答案要点 |
|---|---|
| Pod 的创建流程是什么? | API Server → Scheduler 调度 → kubelet 创建容器 → 执行 postStart → 探针检测 → Running |
| Pod 删除时发生了什么? | 标记 Terminating → 执行 preStop → 发送 SIGTERM → 等待宽限期 → 超时则 SIGKILL |
| terminationGracePeriodSeconds 默认值? | 30 秒 |
| postStart 和 preStop 与主进程的关系? | 并行执行,不是阻塞式的 |
| preStop 中为什么要 sleep? | 等待 Service 的 Endpoints 更新,确保流量已摘除 |
7.2 资源管理关键问题
| 问题 | 答案要点 |
|---|---|
| requests 和 limits 的区别? | requests 影响调度,limits 限制使用上限 |
| CPU 超限会怎样? | 限流(throttle),不会杀死容器 |
| 内存超限会怎样? | OOMKilled,容器被杀重启 |
| QoS 三个等级? | Guaranteed > Burstable > BestEffort |
| 节点资源紧张时谁先被驱逐? | BestEffort 优先驱逐,Guaranteed 最后驱逐 |
7.3 探针关键问题
| 问题 | 答案要点 |
|---|---|
| livenessProbe 失败会怎样? | 容器被杀死重启 |
| readinessProbe 失败会怎样? | Pod 从 Service 摘除,容器不重启 |
| startupProbe 的作用? | 解决慢启动应用被 livenessProbe 误杀的问题 |
| 三种探针的执行顺序? | startupProbe 先执行,成功后 livenessProbe 和 readinessProbe 并行执行 |
八、速查表
资源配置速查
yaml
# Guaranteed(最佳实践)
resources:
requests:
cpu: 200m
memory: 500Mi
limits:
cpu: 200m # = requests
memory: 500Mi # = requests
优雅终止速查
yaml
spec:
terminationGracePeriodSeconds: 60 # 宽限期 ≥ preStop时间 + 应用退出时间
containers:
- lifecycle:
preStop:
exec:
command: ["sleep", "10"] # 等待 Endpoints 摘除
Harbor 私有仓库认证速查
bash
# 创建认证Secret
kubectl create secret docker-registry harbor-auth \
--docker-username=admin --docker-password=xxx \
--docker-server=harbor.example.com
# 绑定到ServiceAccount(推荐)
kubectl patch sa default -p '{"imagePullSecrets":[{"name":"harbor-auth"}]}'
九、总结
本文从四个维度深入剖析了 Pod 的生命周期管理:
-
创建流程 :从
kubectl apply到 Pod Running,经历了 API Server、Scheduler、kubelet 三方协作。理解这个流程是排查 Pending、ContainerCreating 等异常状态的基础。 -
资源限制:requests 决定调度,limits 决定上限。CPU 超限被限流,内存超限被 OOMKill。生产环境务必为所有 Pod 配置资源限制,推荐使用 Guaranteed 级别。
-
生命周期钩子 :postStart 和 preStop 与主进程并行执行,preStop 中应加入 sleep 等待 Endpoints 更新。配合
terminationGracePeriodSeconds实现真正的优雅终止。 -
健康检查:startupProbe 解决慢启动,livenessProbe 保证存活,readinessProbe 控制流量。三种探针各司其职,缺一不可。
实践建议:在部署任何应用到 K8S 之前,都应该为它配置好资源限制、探针和优雅终止策略。这三者是保障服务稳定运行的"三件套",也是面试中最常被考察的知识点。
环境信息:
- Kubernetes: v1.23.17
- 部署方式: kubeadm
- 容器运行时: Docker
- CNI: Flannel