有了容器为什么 kubernetes 还需要 Pod?

简介
容器并不是软件开发的银弹,没有任何一种技术能解决软件开发中的所有问题
当我们采用容器化技术的时候,摒弃了传统的物理机或者虚拟机的部署方式,以一种更加轻快,便捷的方式来部署我们的应用。到容器化的进阶,再加上 kubernetes 对容器的编排技术,使得容器化的利益进一步扩大。但是对于 kubernetes 来说,直接调度编排管理的基本单位并非容器,而是另外一种结构体。
假设容器中同时运行着多个不相关的进程,这些进程的持续运行,管理,以及输入输出日志会是容器的责任。如果这些不相关的进程同时都有标准的输出,而此时我们很难确定每个进程具体输出了什么内容。另一方面,每个容器是一个逻辑的运行单位,有着自己的命名空间,IP 以及端口和其他信息,假如非一个团队开发的不同进程监听了相同的端口号,必将发生资源的争夺冲突。虽然多个进程运行在同一个容器中,无论是通过进程间通信还是通过存储文件进行共享文件都很容易,但是 Docker 和 kubernetes 还是期望每个进程都运行在自己的容器中,除非是和自己相关的子进程。如果你的多个进程有着依赖关系(例如:一个进程的启动依赖于另外一个进程),这样的多个进程推荐运行在相同的容器中。
由于不推荐将无关的进程运行在同一个容器中,但是特殊情况下还存在要求多个相关进程运行于同一个容器的需求,kubernetes 提供了一种更高级的结构来把容器捆绑在一起,并将这种结构作为调度部署的基本单元,这个结构就是 Pod。
Pod 是一组并置的容器,是 kubernetes 中基本的构建模块。但是这并不意味着一个 Pod 总是包含多个容器,在实际应用中每个 Pod 只有一个容器是最常见的部署方式。这里要注意一点,虽然对于 kubernetes 来说,并不关心 Pod 位于哪个节点上,但是一个 Pod 的多个容器位于多个节点是不允许的,换句话说,同一个 Pod 的多个容器总是运行在同一个集群节点上。

kubernetes 部署和操作的基本单位是 Pod
隔离
相同 Pod 下运行的容器之间可以共享一些资源,但是并非全部资源(话句话说,这些容器并非完全隔离的),kubernetes 通过配置可以让同一个 Pod 内的容器共享相同的 linux 命名空间和 network 等资源,所以这些容器共享相同的主机名和网络接口,话句话说,这些容器在 Pod 中可以进行 IPC 通信,就像在局域网中一样。既然共享相同的 IP 和端口号,那么多个容器就不能绑定到相同的端口,否则会出现端口冲突,所以这也是官方推荐一个 Pod 只运行一个容器的原因之一。
每个 Pod 都有自己独立的 Ip 和端口空间,所以不同的 Pod 内的容器永远不会发生端口冲突。同一个 Pod 中的容器具有相同的 loopback,因此可以通过 localhost 与同一 Pod 中的其他容器进行通信

Pod 网络
在同一个 kubernetes 集群中的 Pod 就和局域网内的每台服务器一样,他们共享一个网络地址空间,这个网络是通过软件基于真实链路来实现的。所以只要知道一个 Pod 的 IP 地址就可以进行访问,这个通信过程不通过网关,在通信上性能非常好。由于 kubernetes 把资源进行了抽象,所以 Pod 无论位于哪个服务器节点上,对于同一个集群内的 Pod 来说都一样。
Pod 使用多个容器
在多数情况下,我还是建议每个 Pod 运行一个容器,但是如果你的多个容器有互相依赖关系(比如一个容器的启动依赖于另外一个容器),就需要把多个容器部署到一个 Pod。一个 Pod 中运行一个容器更多的是基于应用分层的考虑,例如:一个应用的容器需要调用一个数据库的容器,这两个容器应该分配到不同的 Pod 中,不仅仅是为了提高集群机器的利用率,更是为了之后不同层次的扩容。对于 kubernetes 来说,操作和部署的基本单位是 Pod,所以 kubernetes 扩容的单位是 Pod 并非容器,如果我们的应用层有性能瓶颈,我们就可以单独的对应用层的 Pod 进行单独扩容,其他层的 Pod 保持不变,这不仅仅是节省资金成本的问题了,而是横向扩展的灵活性问题。

更多精彩文章

版权声明: 本文为 InfoQ 作者【架构师修行之路】的原创文章。
原文链接:【http://xie.infoq.cn/article/256ffc1e6879d611c55bf3f29】。文章转载请联系作者。
评论