pod是一组并置( co-located)的容器, 代表了Kubernetes 中的基本构建块(basic building block)。
pod包含一个或多个容器。一个pod只能工作在一个工作节点上。
image.png

3.1.1 为何需要pod

为何多个容器比单个容器中包含多个进程要好

容器被设计为每个容器只运行一个进程(除非进程本身产生子进程)。 如果在单个容器中运行多个不相关的进程, 那么保持所有进程运行、 管理它们的日志等将会是我们的责任。例如,我们需要包含一种在进程崩溃时能够自动重启的机制。

3.1.2 了解pod

在包含容器的 pod 下,我们可以同时运行一些密切相关的进程,并为它们提供(几乎) 相同的环境, 此时这些进程就好像全部运行于单个容器中一样, 同时又保待着一定的隔离。

同一 pod 中容器之间的部分隔离

Kubernetes 通过配置 Docker 来让一个 pod 内的所有容器共享相同的 Linux 命名空间, 而不是每个容器都有自己的一组命名空间。包括:network UTS IPC,它们也能够共享相同的 PID 命名空间,但是该特征默认是未激活了。(shareProcessNamespace: true)

由于大多数容器的文件系统(mount)来自容器镜像, 因此默认情况下, 每个容器的文件系统与其他容器完全隔离。但我们可以使用名为 Volume 的 Kubernetes 资源来共享文件目录。

容器如何共享相同的 IP 和 port 空间

一个pod中的容器共享相同的 IP 地址和 port 空间。这意味着在同一 pod 中的容器运行的多个进程需要注意不能绑定到相同的端口号, 否则会导致端口冲突, 但这只涉及同一个 pod 中的容器。

此外, 一个 pod 中的所有容器也都具有相同的 loopback 网络接口, 因此容器可以通过 localhost 与同一 pod 中的其他容器进行通信。

介绍平坦的 pod 间(inter-pod)网络

Kubernetes 集群中的所有 pod 都在同一个平坦、共享的网络地址空间中(如图 3.2 所示),这意味着每个 pod 都可以通过其他 pod 的 IP 地址来实现相互访问。换句话说, 这也表示它们之间没有 NAT 网关。

每个 pod 都有自己的 IP 地址, 并且可以通过这个专门的网络实现 pod 之间互相访问。 这个专门的网络通常是由额外的软件基于真实链路实现的。image.png

总结本节涵盖的内容: pod 是逻辑主机,运行在同一个 pod 中的进程与运行在同一物理机或虚拟机上的进程相似, 只是每个进程都封装在一个容器之中。

3.1.3 通过 pod 合理管理容器

由于 pod 比较轻量,我们可以在几乎不导致任何额外开销的前提下拥有尽可能多的 pod。 与将所有内容填充到一个 pod 中不同, 我们应该将应用程序组织到多个 pod 中, 而每个 pod 只包含紧密相关的组件或进程。

对于一个由前端应用服务器和后端数据库组成的多层应用程序, 你认为应该将其配置为单个 pod 还是两个 pod 呢?

基于两点考虑:

  1. 计算资源利用率
  2. 不同的扩缩容需求

将多层应用分散到多个 pod 中

如果前端应用服务器和后端数据库都在同一个 pod 中, 那么两者将始终在同一台计算机上运行,不能充分利用其他节点上的计算资源(CPU和内存)。因此更合理的做法是将 pod 拆分到两个工作节点上,允许Kubernetes 将前端安排到一个节点, 将后端安排到另一个节点, 从而提高基础架构的利用率。

基于扩缩容(scaling)考虑而分割到多个 pod 中

pod 也是扩缩容的基本单位, 对于 Kubernetes 来说, 它不能横向扩缩单个容器, 只能扩缩整个 pod。 这意味着如果你的pod 由一个前端和一个后端容器组成, 那么当你扩大pod的实例数量时, 比如扩大为两个, 最终会得到两个前端容器和两个后端容器。
通常来说, 前端组件与后端组件具有完全不同的扩缩容需求, 所以我们倾向于分别独立地扩缩它们。

理解何时在 pod 中使用多个容器

将多个容器添加到单个pod的主要原因是应用可能由 一个主进程和一个或多个辅助进程组成, 如图 3.3 所示。
image.png

决定何时在 pod 中使用多个容器

当决定是将两个容器放入一个 pod 还是两个单独的 pod 时,我们需要问自己以下题:

  • 它们需要一起运行还是可以在不同的主机上运行?
  • 它们代表的是一个整体还是相互独立的组件?
  • 它们必须一起进行扩缩容还是可以分别进行?

基本上,我们总是应该倾向于在不同的 pod 中运行容器,除非有特定的原因要求它们在同一 pod中运行。
image.png