Kubernetes 用 Pod 打包容器而非直接运行,这是核心抽象

Kubernetes 不直接运行容器,而是把一个或多个容器打包成 Pod。Pod 是它最小的可部署单元,这个分组机制解决了跨多台机器管理容器化应用的核心问题。即使熟悉 Docker,这个额外抽象也常常让新手困惑,但它正是集群调度和自愈的基础。

Pod 把容器组合成最小调度单元

Kubernetes 不会单独调度一个容器。它把应用容器和可能需要的 sidecar 容器打包成一个 Pod。Pod 共享同一个网络命名空间和存储卷,里面的容器可以通过 localhost 互相通信。

在阿里云 ACK 集群里,创建 Pod 最直接的方式是 kubectl apply 一个 yaml。典型配置里 containers 数组下可以放多个容器,例如一个 Nginx 主容器加一个日志采集的 Fluentd 容器。ACK 控制台的「工作负载」→「Pod」页面会直接显示这个 Pod 的状态、所在节点和重启次数。

Pod 一旦被调度到节点上,kubelet 就负责拉取镜像并启动所有容器。只要其中一个容器崩溃,整个 Pod 就会被重启,这和单容器行为一致。很多新手把 Pod 当成容器来理解,结果发现一个 Pod 里多个容器共享 IP 和端口,就容易踩坑。

实际案例中,阿里云 ACK 的 Pod 事件查看非常方便。在控制台点开具体 Pod,能看到「Events」栏里记录了调度、镜像拉取、启动失败等每一步。如果 Pod 一直处于 Pending 状态,90% 是因为节点资源不够或者没有匹配的 tolerations。

这个分组设计让 Kubernetes 能把一组紧密相关的容器当作一个原子单位来调度、迁移和销毁,避免了单独管理多个容器带来的复杂性。

Service 为动态 Pod 提供固定访问入口

Pod 的 IP 地址是临时的。节点重启、Pod 扩缩容或者被驱逐后 IP 都会变。如果直接用 Pod IP 做前端调用,服务马上就断。

Service 正是解决这个问题的。它给一组 Pod 提供一个稳定的虚拟 IP(ClusterIP)和 DNS 名称。Service 通过标签选择器把符合条件的 Pod 关联起来,后端 Pod 列表会自动更新。

腾讯云 TKE 在这点上集成得比较深。用户在 TKE 控制台创建「服务」时,可以直接选择「负载均衡」类型,系统会自动在 CLB 后面挂载对应 Pod。配置完成后,CLB 的外网 IP 或者内网域名就成了访问入口。

常见踩坑点有两个。一是标签选择器写错,导致 Service 找不到任何 Pod,状态一直是「无后端」。二是用了 NodePort 类型却没有配置安全组,结果外部流量进不来。腾讯云文档里反复强调,NodePort 端口默认在 30000-32767 区间,需要在安全组放行。

另一个容易忽略的问题是 Session Affinity。如果业务需要保持会话,就要把 Service 的 sessionAffinity 设置为 ClientIP,否则请求会在不同 Pod 之间跳来跳去。

Deployment 控制 Pod 副本数与滚动更新

Deployment 是更高一层的控制器。它声明期望的 Pod 副本数、使用的镜像版本和更新策略。控制器会持续对比当前状态和期望状态,自动创建或删除 Pod。

更新时,Deployment 默认采用 RollingUpdate 策略。它先启动新版本 Pod,达到一定比例后才逐步下线旧版本。整个过程不需要停机。

国内用户最常遇到的回滚失败场景是:新版本已经全部上线,旧 ReplicaSet 被删除,kubectl rollout undo 找不到历史版本。这时只能手动把 Deployment 的 spec.template 改回旧镜像,再触发一次更新。

最佳实践是把 revisionHistoryLimit 设置为 5 到 10,保留足够的历史 ReplicaSet。同时在更新前一定要做金丝雀或蓝绿发布,避免直接把 production 的 replicas 从 10 改到 20 再改镜像。

腾讯云 TKE 的「工作负载」页面提供了可视化的滚动更新进度条,能看到新旧 Pod 的比例变化,比纯命令行直观很多。

阿里云与腾讯云对概念的托管封装差异

两家云平台都实现了标准 Kubernetes API,但控制台和附加功能差异明显。

阿里云 ACK 更强调「托管版」,用户几乎不用关心 etcd 和 master 节点。它把 Pod 安全组、镜像加速、日志采集等功能直接做成 CRD 或者控制台开关。创建 Pod 时可以直接勾选「使用镜像加速」和「注入日志 Sidecar」,省去手动写 yaml 的麻烦。

腾讯云 TKE 则在网络和负载均衡上更重。它的 Service 可以一键关联 CLB,并且支持 CLB 的四层和七层配置直接在控制台完成。TKE 的「集群审计」功能默认开启,对 Pod 创建、Service 变更的操作记录得更完整。

这些差异直接影响调试和迁移。如果团队同时使用两家云,同一个 Deployment yaml 在 ACK 上可能因为默认的 NetworkPolicy 不同而无法访问外部服务,而在 TKE 上却正常。迁移时必须把资源限制、亲和性、tolerations 这些字段重新检查一遍。

资源限制缺失是 Pod 被驱逐的主因

Kubernetes 调度器在放置 Pod 时会参考 requests 值,而实际运行时看 limits。如果 Pod 没有设置 requests 和 limits,它会使用节点上可用的全部资源。一旦节点内存或 CPU 紧张,kubelet 就会根据 QoS 等级驱逐 Pod。

Best-Effort 类型的 Pod(没有设置任何 request)最先被杀,然后是 Burstable,最后才是 Guaranteed。很多团队把所有 Pod 都设成 Burstable,结果生产节点一抖动就先杀业务 Pod。

阿里云 ACK 提供资源组和配额管理,能在命名空间层面限制 CPU 和内存总量。建议至少把 requests 设置为实际稳定使用量的 50%-70%,limits 设置为峰值的 1.5 倍。生产环境强烈建议把所有 Pod 都设为 Guaranteed,即 requests 等于 limits。

腾讯云 TKE 的监控大盘会直接显示「Pod 被驱逐次数」,点进去能看到具体原因是 OOMKilled 还是 NodeNotReady。结合这个指标调整资源配置,能快速降低故障率。

标签选择器串联 Deployment、Service 和 Pod

标签是 Kubernetes 组织资源的核心机制。Deployment 的 selector、Service 的 selector、Pod 的 metadata.labels 必须匹配才能形成完整链路。

常见做法是给 Pod 打上 app=nginx、env=prod、version=v1 三个标签。Deployment 用 app 和 env 做 selector,Service 只用 app=nginx。这样版本升级时 Service 不需要改动。

在多集群、多环境场景下,中文开发者常采用的标签策略是再加一个 team 或 owner 标签,便于用 kubectl get all -l team=backend 快速过滤资源。

腾讯云 TKE 的「资源分组」功能直接基于标签实现,能把不同环境的 Deployment 和 Service 自动归类到不同项目下。阿里云 ACK 则在 RAM 权限层面支持标签授权,可以做到只有打了 prod 标签的 Pod 才能被运维账号操作。

标签选择器一旦写错,整个链路就断。Service 找不到 Pod、Deployment 无法管理旧版本,这些问题 80% 都源于标签不匹配。建议在 CI 流水线里增加一个校验步骤,检查 yaml 里的 selector 和 labels 是否一致。

掌握标签用法后,开发者就能在复杂环境中快速定位和操作资源,这是从入门到熟练的真正分水岭。

参考来源