01. Pod 是什么
Pod 是 K8s 的最小调度单位,一个 Pod 里可以有多个容器,但大多数情况是 1 个 Pod 1 个容器。Pod 里的所有容器共享同一个网络命名空间(同一个 IP)和存储卷,可以通过 localhost 互相通信。
Pod 是临时的——它会被创建、销毁、重建。每次重建 IP 都不一样。Pod 不应该被直接管理(除非临时调试),应该通过 Deployment、StatefulSet 等控制器来管理。
Pod 的生命周期:Pending(等待调度)→ Running(至少一个容器在跑)→ Succeeded/Failed(所有容器终止)。Pod 一旦终止了就不会复活,控制器会创建新的 Pod。
bash
# 快速创建一个临时 Pod 做调试
kubectl run debug-pod --image=nginx --rm -it -- sh
# 查看 Pod 详情
describe pod my-pod
# 查看 Pod 的 YAML(从 K8s 拿到的实际运行配置)
kubectl get pod my-pod -o yaml
# 删除 Pod(如果是 Deployment 管理的,会立刻重建)
kubectl delete pod my-pod02. 多容器 Pod 与 Sidecar 模式
一个 Pod 里多个容器的经典模式叫 Sidecar——主容器干正事,Sidecar 容器干辅助工作:日志收集、代理、配置热更新。
比如你的应用容器把日志写到文件,Sidecar 容器负责把日志发送到日志系统。因为共享存储,Sidecar 能读到主容器的文件。
多容器 Pod 的注意事项:容器启动顺序没有保证(除非用 Init 容器)。如果一个 Pod 里的某个容器一直 CrashLoop,整个 Pod 的状态就是 CrashLoopBackOff。
Init 容器——Pod 里的特殊容器,在普通容器之前启动,完成后就退出。适合做初始化工作:等数据库就绪、下载配置、修改文件权限。
yaml
# Pod 定义(1 主容器 + 1 Sidecar)
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-shipper
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true
volumes:
- name: logs
emptyDir: {}Sidecar 模式最常见的就是日志收集——应用只管写日志,Sidecar 负责发送。两个容器各司其职,解耦。
03. 探针——Liveness、Readiness、Startup
K8s 用探针来检查容器的健康状况:
Liveness Probe——容器还活着吗?如果探针失败,K8s 杀掉容器并重启。适合检测死锁、无限循环等导致进程还活着但已经不能服务的状态。
Readiness Probe——容器准备好接收流量了吗?失败时 K8s 不把流量路由到这个 Pod。适合检测依赖还没就绪的情况(如数据库还没连上)。
Startup Probe——容器启动完了吗?只用在启动慢的容器。启动期间 Startup Probe 如果失败,Liveness 不会执行(否则容器还没启动完就被杀了)。
探针有三种实现方式:HTTP GET(最常用)、TCP Socket、Exec(容器内执行命令)。
yaml
# 探针配置
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10Readiness 和 Liveness 要不同。Readiness 探针失败只是不导流量,Liveness 探针失败是直接杀容器重建。
04. 资源请求与限制
Pod 的每个容器都需要声明资源请求和限制:
requests——调度时保证的最少资源。Scheduler 只会把 Pod 分配到有足够空闲资源的 Node 上。
limits——容器最多能用的资源。超出 CPU limit 会被 throttling(变慢),超出内存 limit 会被 OOMKilled(杀掉)。
requests 用于调度决策,limits 用于运行时限制。如果你设了 limits 没设 requests,K8s 会把 requests 默认设成跟 limits 一样。
资源单位:CPU 用核数(0.5 = 半核,或者写 500m = 500 millicpu)。内存用字节(Mi = 兆字节,Gi = 吉字节)。
yaml
# 资源声明
containers:
- name: app
image: myapp:latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
# 不设 limits 的后果:容器可以用光整个 Node 的资源
# 不设 requests 的后果:调度器不知道给多少资源,可能把 Node 塞爆生产环境每个容器必须设 requests 和 limits。不设的话一个内存泄漏就能把整个 Node 上的 Pod 全拖垮。
05. Pod 排错
Pod 出问题了怎么排查?按这个顺序来:
1. kubectl get pods——先看状态是不是 Running。常见错误状态:Pending(调度不了,查 Node 资源或镜像拉取)、CrashLoopBackOff(起来了又挂,看日志)、ImagePullBackOff(拉不到镜像)、ErrImagePull(镜像名错了)。
2. kubectl describe pod——看 Events 部分,K8s 把 Pod 经历的一切都记在这里。拉镜像、调度、启动探针失败都有对应事件。
3. kubectl logs——看容器输出。如果 Pod 有多个容器,用 -c 指定。如果容器反复重启,加 --previous 看上次容器的日志。
4. kubectl exec——进容器里手动排查。记住容器里可能没装 curl/nc 之类的调试工具,用 alpine 镜像跑临时 Pod。
bash
# 排查流程
kubectl get pods # 状态
kubectl describe pod my-pod # 事件
kubectl logs my-pod # 当前容器日志
kubectl logs my-pod --previous # 上次崩溃的日志
kubectl exec -it my-pod -- sh # 进入容器
# 临时调试 Pod
kubectl run debug --image=alpine --rm -it -- sh
# 进去后可以 ping、nslookup、curl 测试describe pod 的 Events 是最重要的排查入口。每次 Pod 状态变化 K8s 都在 Event 里记原因。
知识测验
第 1/5 题正确 0
Pod 里多个容器怎么互相通信?
下一节
下一节 Service 与网络