一、一句话理解 Pod
Pod = K8s 的最小调度单元,是一个“逻辑主机”。
它里面可以跑一个或多个容器,这些容器共享:
同一个 IP
同一个 hostname
同一个 Network / IPC / UTS 命名空间
同一份 Volume(按需挂载)
所以 Pod 里的容器之间可以用 localhost 直接通信,像在同一台机器上一样。
二、Pod 和容器到底是什么关系?
### 1. 容器是“进程”,Pod 是“进程组 + 共享环境”
2. Pause 容器:Pod 的“二房东”
Pod 启动时,第一个创建的是 Pause 容器(也叫 Infra 容器)。
它不干业务,只做一件事:创建并持有 Network / IPC / UTS 命名空间。
业务容器(nginx、fluentd 等)启动时,是“加入”Pause 容器已经建好的命名空间。
所以:
业务容器崩溃重启 → 重新加入同一个命名空间 → IP 不变、hostname 不变
这就是为什么 Pod 内容器重启,对外表现却很稳定
3. 一个 Pod 里典型有哪些容器?
Pod
├── Pause 容器(Infra,持有命名空间)
├── Init 容器(按顺序执行,全部成功后才启动主容器)
├── 主容器(nginx / 业务应用)
└── Sidecar 容器(日志采集、配置热更新、服务网格代理等)三、为什么最小运行单位是 Pod,而不是容器?
这是 K8s 最核心的设计决策,原因有三个:
理由一:紧密协作的容器需要共享 localhost 和 Volume
比如:
nginx 写日志到
/var/log/nginxfluentd 读同一个日志文件
如果它们是两个独立容器、被调度到不同 Node:
只能走网络存储 → 延迟高、成本高
只能走网络通信 → 不能
localhost
放进同一个 Pod:
共享
emptyDirVolume → 本地磁盘速度共享 Network 命名空间 →
localhost:80直连,零网络延迟
理由二:Pod 是资源调度的原子单位
调度器以 Pod 为单位分配 Node。
如果以容器为单位:
nginx 和 fluentd 可能被分到不同 Node
通信、存储、调度复杂度都会大幅上升
理由三:Pause 容器维持命名空间,保证 IP 稳定
业务容器重启时,Pause 容器还在,命名空间还在,IP 和 hostname 都不变。
四、Pod 内三个关键共享
注意:Mount、Cgroup、User 命名空间是各自独立的,Pod 只共享与网络通信密切相关的部分。
五、三种探针(重点)
K8s 用探针检查容器健康状态,三种探针各司其职。
1. 三种探针的核心区别
2. 为什么需要 startupProbe?
Java 应用启动要 60 秒。
如果只用 liveness(15 秒开始检查,连续失败 3 次):
45 秒就被判定失败 → 重启 → 永远起不来 → CrashLoopBackOff
startupProbe 在 liveness 之前执行,给足启动时间:
startupProbe:
httpGet: { path: /start, port: 8080 }
failureThreshold: 30
periodSeconds: 10
# 最多等 30 × 10 = 300 秒3. 三种探测方式
# HTTP GET(最常用)
livenessProbe:
httpGet:
path: /healthz
port: 80
# TCP Socket(MySQL、Redis 等)
readinessProbe:
tcpSocket:
port: 3306
# Exec 命令(检查文件等)
livenessProbe:
exec:
command: ["cat", "/tmp/healthy"]4. 关键参数速查
调优公式:
liveness 最长容忍窗口 = initialDelaySeconds + (periodSeconds × failureThreshold)
示例:15 + (10 × 3) = 45 秒
startupProbe 保护窗口 = periodSeconds × failureThreshold
示例:10 × 30 = 300 秒(给 Java 5 分钟启动时间)5. 探针端点设计规范(很重要)
错误示范:
// ❌ liveness 检查了 DB
if err := db.Ping(); err != nil {
w.WriteHeader(500) // DB 挂了 → 杀容器 → 重启也没用 → CrashLoopBackOff
}正确做法:
// ✅ liveness 只检查自身
if isDeadlocked() {
w.WriteHeader(503)
return
}
w.WriteHeader(200)六、Pod 生命周期与重启策略
1. 生命周期阶段
2. 重启策略
3. 优雅停机流程
kubectl delete pod
→ 执行 preStop hook
→ 发送 SIGTERM
→ 等待 terminationGracePeriodSeconds(默认 30 秒)
→ 超时发送 SIGKILL 强制终止七、Init Container 的核心用途
Init 容器在主容器之前运行,按顺序执行,全部成功后才启动主容器。
八、QoS 与资源管理
resources:
requests: # 调度保障:决定 Pod 放哪个 Node
cpu: "100m"
memory: "128Mi"
limits: # 运行时上限
cpu: "500m" # CPU 超了限速,不杀进程
memory: "256Mi" # Memory 超了 OOMKill生产建议:至少 Burstable,关键服务 Guaranteed。
九、最容易记混的点(笔记重点)
Pod 不是容器,Pod 是“逻辑主机”,容器是里面的“进程”。
Pause 容器不干活,只持有命名空间,业务容器重启 IP 不变。
最小单位是 Pod,因为紧密协作的容器需要共享 localhost + Volume。
liveness 失败 → 重启容器;readiness 失败 → 摘流量;startup 失败 → 保护慢启动。
liveness 不要检查外部依赖,否则 DB 挂了会引发无意义重启。
readiness 是发布新版本时最重要的探针,能防止错误版本接入流量。
Init 容器按顺序执行,全部成功才启动主容器。
QoS 决定 OOM 时谁先被杀:Guaranteed > Burstable > BestEffort。
十、一张图记住 Pod 与容器关系
Pod(逻辑主机,共享 IP / hostname / Network NS)
├── Pause 容器(Infra,持有命名空间,IP 不变的关键)
├── Init 容器(按顺序执行,全部成功才启动主容器)
├── 主容器(业务应用)
└── Sidecar 容器(日志、配置、代理)
↑
共享 localhost + VolumeK8s三种探针及Pod与容器的关系
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法