Pod
- Pod 是一组紧密协同的容器集合,也是 Kubernetes 中的基础调度单元。
- Pod包含Container。
- 当 Pod 包含多个容器时,所有容器都运行在同一工作节点上。
必要性
单容器为何不应运行多进程
- 容器设计初衷是仅运行单个主进程(其派生的子进程除外)。
- 容器运行时仅在根进程终止时重启容器,对其创建的子进程不作监控。若需维持子进程运行,必须由根进程自行管理。
Pod 如何整合多容器
- 作用
- 保留容器的所有特性
- 允许进程间高效协作
- 将关联容器作为统一单元管理
- 共享
- 命名空间共享机制使得分属不同容器的进程产生"共同运行"的错觉。
- 独立
- 每个容器始终拥有独立的 Mount 命名空间(即独立文件系统)。
- 但当容器需要共享部分文件时,可通过 Pod 级存储卷实现——将同一卷挂载至多个容器。
- 它们仍保持独立 Mount 命名空间,但能通过共享卷交换数据。
容器编排与 Pod 组织逻辑
多层应用栈的 Pod 拆分实践
若将前后端服务强制置于同一 Pod,会导致:
- 在双节点集群中,该 Pod 仅能调度至单个节点
- 第二个节点的计算资源(CPU/内存/存储/带宽)完全闲置
- 造成硬件资源利用率低下
通过拆分前后端为独立 Pod,Kubernetes 可将其分别调度至不同节点,从而实现资源优化利用。
基于弹性伸缩的拆分策略
- Pod 不仅是基础部署单元,更是基础伸缩单元。
- 扩展 Deployment 时 Kubernetes 创建的是完整 Pod 副本,而非单个容器副本。
- 前后端组件通常具有不同的伸缩需求。
何时应该采用多容器 Pod
- 仅当应用包含主进程及一个或多个辅助进程时,将多个容器置于同一 Pod 才具有合理性。
- 运行辅助进程的容器被称为 Sidecar 容器。
举例1
- 运行 Node.js 应用的容器仅支持 HTTP 协议。若需启用 HTTPS 支持,传统做法是修改 JavaScript 代码。
- 但更优雅的方案是在 Pod 中新增反向代理容器:
- 该代理容器将 HTTPS 流量转换为 HTTP 协议
- 转换后的流量转发至 Node.js 容器
- 此时 Node.js 容器作为主容器,代理容器则扮演 Sidecar 角色。
举例2
- Pod 中的主容器运行 Web 服务器,从其 webroot 目录提供文件服务;
- 同一 Pod 中的辅助容器则作为代理程序,定期从外部数据源下载内容并存储至 Web 服务器的 webroot 目录。
- 如先前所述,两个容器可通过共享存储卷实现文件交互——webroot 目录正是挂载于此共享卷之上。
容器分组决策指南
在决定采用 Sidecar 模式合并容器还是分设多 Pod 时,请依次思考以下关键问题:
- 共置必要性:这些容器是否必须运行于同一节点?
- 管理维度:是否需要将它们作为统一单元进行管理?
- 架构耦合度:它们是否构成有机整体而非独立组件?
- 伸缩一致性:是否需要始终保持同步扩缩容?
- 资源可行性:单个节点能否满足它们的合并资源需求?
若以上问题的答案均为肯定,则应将它们合并至同一 Pod。
遵循以下黄金准则:除非存在明确需求,否则默认将容器分置不同 Pod。
与应用程序和 pod 进行交互
- 从工作节点连接到 Pod
minikube ssh
curl <pod-ip>:<port>
- 从一次性客户端 pod 连接
- 通过 kubectl 端口转发连接到 pod
kubectl port-forward <pod-name> <port>
curl localhost:<port>
在 Pod 启动时运行额外的容器
- 当一个 Pod 包含多个容器时,所有容器都会并行启动。
- 无法确保一个容器先于另一个容器启动。
- 初始化容器 - 依次运行,并且必须全部成功完成,Pod 的主容器才能启动。
spec.initContainers
初始化容器功能
- 初始化 pod 主容器使用的卷中的文件。
- 初始化 Pod 的网络系统。
- 延迟启动 Pod 的主容器,直到满足某个前提条件。
- 通知外部服务 Pod 即将启动。
总结
- Pod 以一组位于同一位置的容器运行一个或多个容器。它们是部署和横向扩展的基本单元。一个典型的容器只运行一个进程。Sidecar 容器是对 Pod 中主容器的补充。
- 只有当容器必须同时运行时,才应该将它们放在同一个 Pod 中。前端和后端进程应该运行在不同的 Pod 中。这样可以实现对它们的独立扩展。
- 当 Pod 启动时,其初始化容器会依次运行。当最后一个初始化容器完成后,Pod 的主容器才会启动。您可以使用初始化容器在内部配置 Pod,延迟主容器的启动直到满足某个前提条件,或者通知外部服务 Pod 即将启动。
- kubectl 工具用于创建 pod、查看其日志、将文件复制到/从其容器复制文件、在这些容器中执行命令以及在开发期间启用与各个 pod 的通信。
