Pod 是 Kubernetes 中最小、最基础的调度单元,它封装了一个或多个容器,共享网络和存储资源,kubelet 直接管理 Pod 而非单个容器。无论你是刚接触云原生还是准备排查线上问题,理解 Pod 的工作方式,就等于握住了 Kubernetes 的钥匙,下面从概念、调度到实践排查,一次讲透。
Pod 到底是什么
很多人第一次接触 Pod 时,容易把它和容器混为一谈,简单说,Pod 是容器的”外壳”,Kubernetes 不会直接运行一个 Docker 容器,而是先创建一个 Pod,再让容器在这个 Pod 里启动,Pod 里的容器共享同一个网络命名空间、IP 地址和存储卷,它们可以通过 localhost 互相访问,这就像合租一套房子几个室友共享客厅和厨房,但各自有独立的卧室。
Pod 的核心特征
- 最小调度单位:kubelet 只认 Pod,不认容器,扩容、缩容、滚动更新,操作对象都是 Pod。
- 共享网络:同一个 Pod 内的容器共享 IP 和端口空间,所以要注意端口冲突。
- 共享存储:Pod 里的 volume 可以挂载到多个容器,数据交换无需经过网络。
- 生命周期短暂:Pod 随时可能被销毁重建,IP 不固定,所以不要直接依赖 Pod IP。
Pod 与容器的区别
这是百度上很常见的搜索词”pod和容器的区别”,用一张表说清楚:
| 对比项 | Pod | 容器 |
|---|---|---|
| 层级 | Kubernetes 资源对象 | 运行时实例 |
| 生命周期 | 由 Deployment 等控制器管理 | 跟随 Pod 创建和销毁 |
| 网络 | 有独立 Pod IP | 共享 Pod IP,无独立 IP |
| 存储 | 可挂载多个卷 | 卷挂在 Pod 上,容器复用 |
| 健康检查 | Pod 级 readiness/liveness | 容器内进程状态 |
行业共识认为,Pod 的设计是为了解决”哪些进程需要紧密协作且共享资源”的问题,比如日志 sidecar 容器和主业务容器放在同一个 Pod 里,就是为了让日志采集器直接读本地文件,不走网络。
为什么说 Pod 是调度的基础单元
调度器 kube-scheduler 的工作对象是 Pod,不是容器,当你要部署一个 Nginx,写一个 Deployment,控制器会创建 ReplicaSet,ReplicaSet 再创建 Pod,调度器看到一个新 Pod 出现,就会为它选一个最合适的节点(Node),然后该节点上的 kubelet 负责拉起 Pod 里的所有容器。
调度决策看什么
调度器做决定时,主要看三类信息:
- 资源请求:Pod 里所有容器的 requests 之和,比如请求 2 核 4G,节点必须有这么多空闲资源。
- 标签选择器:nodeSelector 或亲和性规则,比如把 Pod 调度到 SSD 节点。
- 约束条件:污点容忍、端口冲突、卷区域限制等。
你可以用 kubectl describe pod <pod-name> 查看调度结果,末尾的 Events 会显示 “Successfully assigned pod to node-1” 这样的信息,如果一直 Pending,大概率是资源不够或约束不满足。
一个实际调度场景
假设你要上线一个在线教育应用,需要两个实例,一个跑在主节点,一个跑在 GPU 节点,你可以这样写:
spec:
affinities:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
但注意,调度只决定 Pod 放在哪台机器,不保证容器一定能启动,启动失败的锅要由 kubelet 和镜像仓库来背。
Pod 的资源限制怎么配
搜索引擎里”pod资源限制配置”是一个高频长尾词,配置不当,会导致节点资源耗尽或 Pod 被驱逐,配置核心是 requests 和 limits 两个字段:
- requests:调度器需要满足的最低资源,相当于”预约座位”。
- limits:容器最多能用的资源,超过会触发 OOM 或 CPU 限制。
推荐配置方式
resources:
requests:
cpu: 250m # 0.25 核
memory: 512Mi
limits:
cpu: "1" # 1 核
memory: 1Gi
为什么 requests 和 limits 要留出差距?因为limits 是硬上限,requests 是软保障,如果两者一样,容器就失去了突发能力,对延迟敏感型应用,比如支付接口,建议 limits 不超过 requests 的 1.5 倍;对批处理任务,可以放宽到 2 倍。
容易踩的坑
- 只设 limits 不设 requests:调度器按 requests 算资源,不设 requests 会导致 Pod 被塞到资源不足的节点,运行后直接 OOM。
- CPU 限制过小:CPU limits 用的是 CFS 配额,限制过小会让进程频繁被节流,表现为响应变慢,但不会崩溃。
- 内存限制大于节点内存
:Pod 可能被调度到内存不足的节点,然后被系统 OOM Killer 杀掉。
遇到 Pod 启动失败,先看 kubectl describe pod 的 Events,常见错误有 Insufficient memory、OutOfcpu、Back-off pulling image,对应解决方案各不相同。
Pod 常见问题排查路径
很多人在百度搜”pod无法启动排查”,这类问题占运维工作量的相当一部分,下面给出一套从易到难的排查顺序。
第一步:看 Pod 状态
kubectl get pods -n <namespace> 看状态列:
- Pending:调度未完成,查 Events,看是不是资源不足。
- ContainerCreating:容器创建中,查镜像是否存在、证书是否过期。
- CrashLoopBackOff:容器启动后立刻退出。
kubectl logs看报错。 - Running 但异常:进程活着但业务不通,查 readiness 探针。
第二步:看事件和日志
kubectl describe pod <pod-name> -n <namespace>
kubectl logs <pod-name> -c <container-name> -n <namespace>
日志默认只显示当前容器,如果容器重启过,加 --previous 看上一次的日志。
第三步:检查网络和存储
- 用
kubectl exec -it <pod> -- curl <service>测网络连通性。 - 存储挂载失败通常会出现
MountVolume.MountDevice failed事件,检查 PV 状态。
这里要强调一个原则:排查 Pod 问题,永远先看事件,后看日志,事件告诉你发生了什么,日志告诉你为什么发生。
Pod 生命周期与控制器
Pod 本身没有自愈能力,删除就没了,真正干活的是各种控制器,Deployment 管理无状态应用,StatefulSet 管有状态应用(比如数据库),DaemonSet 保证每个节点跑一个 Pod(比如日志采集)。
更新策略
比如你用 Deployment 滚动更新,新 Pod 起来后先等 readiness 探针通过,再杀掉旧 Pod,如果新 Pod 一直不 ready,更新会暂停,这时候用 kubectl rollout status deployment/<name> 查看进度,回滚用 kubectl rollout undo。
静态 Pod
还有一种特殊 Pod,由 kubelet 直接管理,不经过 API Server,在 /etc/kubernetes/manifests/ 下放 YAML 文件,kubelet 会自动拉起,静态 Pod 的命名通常带有节点名后缀,etcd-master1,这类 Pod 用于部署控制平面组件,普通用户很少接触。
多容器 Pod 的协作模式
你可能会问,什么时候需要多个容器放在一个 Pod 里?业界总结出三种常见模式:
- Sidecar 模式:主容器负责业务,sidecar 负责辅助功能,Envoy 代理、日志采集器、文件同步器。
- Adapter 模式:将业务输出标准化,比如把应用日志转成统一格式。
- Ambassador 模式:代表主容器访问外部服务,比如数据库访问代理。
强烈建议不要在 Pod 里放两个有状态业务容器,Nginx 和 MySQL 放一起,这会让扩容、故障恢复变得极其复杂,而且违背了 Pod 的设计初衷。
Pod 安全与隔离
在生产环境,Pod 的权限控制必须重视,默认情况下,Pod 里的容器以 root 运行,这很危险。
常用安全配置
securityContext:
allowPrivilegeEscalation: false
runAsUser: 1000
runAsGroup: 1000
capabilities:
drop: ["ALL"]
- runAsUser:指定非 root 用户运行。
- capabilities:去掉 Linux 特殊权限。
- seccompProfile:限制系统调用。
如果你使用的是托管 Kubernetes 服务,比如简米云 ACK 或酷番云 TKE,控制台里通常有”Pod 安全策略”选项,但要注意,安全策略只对新建 Pod 生效,已有 Pod 不会自动修改。
Pod 的常见问答
Q1:Pod 重启后 IP 变了,业务怎么保持访问?
不要让业务直接访问 Pod IP,而是通过 Service 提供稳定的虚拟 IP 和 DNS 名称,Service 会对后端 Pod 做负载均衡,Pod 重建后自动更新 Endpoints 列表。
Q2:Pod 一直 Terminating 删不掉,怎么办?
先看节点上的 kubelet 是否健康,然后强制删除:kubectl delete pod <name> --force --grace-period=0,如果依然卡住,可能是节点失联或挂载点被占用,需要登录节点处理。
Q3:两个容器在同一个 Pod 里如何通信?
直接访问 localhost + 端口即可,因为共享网络命名空间,注意端口不能冲突,否则后启动的容器会绑定失败。
最后几句实在话
Pod 不复杂,但很多线上事故都出在对 Pod 机制的误读上,把本文的调度、资源限制、排查路径记牢,再配合熟练使用 kubectl describe 和 kubectl logs,基本能解决日常 80% 的 Kubernetes 问题。Pod 是 Kubernetes 的最小租户,你对它负责,它才对业务负责。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/641266.html




