引言:为何需要 Pod?
在 Kubernetes(k8s)中,把「容器」比作运行应用的小屋,而「Pod」则是把关联小屋围在同一个院子里,共享网络和存储资源。想象一个微服务场景,主应用需要日志收集和监控探针,如果把它们拆成独立 Pod,不仅网络调用增加,还得为每个 Pod 单独配置存储与安全策略;而将它们放进同一个 Pod,就能高效协作、简化管理。
注意:Pod 是 k8s 最小部署单元,容器始终运行在 Pod 里,无法单独存在。
什么是 Pod?
-
定义:Pod(同伴容器集合)是 k8s 中最小的调度与生命周期单位,一个 Pod 可包含 1~n 个容器。
-
特性:
- 共享网络 :同 Pod 容器通过
localhost
通信,拥有同一个 IP 地址。 - 共享存储 :挂载同一卷(
emptyDir
、PVC 等),容器间可直接读写。 - 统一调度:调度器以 Pod 为粒度分配到节点,容器一起启动与销毁。
- 共享网络 :同 Pod 容器通过
容器在 Pod 中的关系
为了让大家更直观,这里用一个「家庭」比喻来说明:
- Pod 就像一个「家庭」(House),负责提供房屋结构(网络、存储、沙箱容器);
- 容器 就像「家庭成员」(Room),每个成员承担不同角色(主应用、Sidecar、Init)。
关系维度 | 描述 |
---|---|
一对多 | 一个 Pod(家庭)可以有多个容器(成员)。主容器负责核心业务,Sidecar 容器负责日志/监控,Init 容器完成初始化任务。 |
网络共享 | 所有容器共用同一个 IP 地址和网络命名空间。容器内应用互通只需使用 localhost:端口 ;但同 Pod 内端口不能重复,需合理规划。 |
存储共享 | 通过挂载同一个卷(如 emptyDir 或 PVC),容器可共享数据。Init 容器可在启动时准备数据,主容器和 Sidecar 容器则读取或追加操作。 |
生命周期绑定 | kubelet 启动时,先启动一个 Pause(沙箱)容器来初始化网络与卷,再拉起各个容器;删除 Pod 时,会同时停掉所有容器,保证资源统一回收。 |
- Init 容器:在主容器前运行,用于拉取配置、初始化数据库 schema 等;
- Sidecar 容器:与主容器并行运行,如日志代理、配置热更新、流量录制等;
- 主容器:承担核心业务逻辑,通常资源需求最大。
示意图:
cssPod(家庭) ├─ Pause 容器(院子大门,挂载网络与存储) ├─ Init 容器(管家,预先打扫并布置家具) ├─ 主容器(家庭成员 A,核心业务) └─ Sidecar 容器(家庭成员 B,收集日志/监控)
样例演示:单容器 vs 多容器 Pod
单容器 Pod
yaml
apiVersion: v1
kind: Pod
metadata:
name: single-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
bash
kubectl apply -f single-pod.yaml
kubectl exec single-pod -- curl localhost
多容器(Sidecar)Pod
yaml
apiVersion: v1
kind: Pod
metadata:
name: sidecar-pod
spec:
volumes:
- name: logs
emptyDir: {}
containers:
- name: app
image: busybox
command: ["sh", "-c", "while true; do echo hello >> /var/log/app.log; sleep 5; done"]
volumeMounts:
- name: logs
mountPath: /var/log
- name: log-agent
image: busybox
command: ["sh", "-c", "tail -n+1 -f /var/log/app.log"]
volumeMounts:
- name: logs
mountPath: /var/log
bash
kubectl apply -f sidecar-pod.yaml
kubectl logs sidecar-pod -c log-agent
常见易错点
场景 | 问题描述 | 解决思路 |
---|---|---|
端口冲突 | 同 Pod 容器使用相同 containerPort |
为每个容器分配不同端口,或内部通过域套接字通信 |
探针配置过严 | Liveness 探测未通过导致持续重启 | 适当放宽 initialDelaySeconds 、timeoutSeconds |
卷权限问题 | 容器无法写入共享卷 | 在 Init 容器中使用 chmod 设置目录权限 |
最佳实践
- 职责分离:Init、主容器、Sidecar 分工明确,不要在主容器承担太多辅助任务。
- 统一日志 :主容器输出到
stdout
/stderr
,Sidecar 负责采集并发送到集中式系统。 - 资源隔离 :合理设置
requests
与limits
,避免容器间资源争抢。 - 健康探针:根据应用启动与加载时间调优,避免误判重启。