概念
Pod 就是 K8S 中一个服务资源的闭包。
简单来说,Pod 可以被理解成一群可以共享网络、存储和计算资源的容器化服务的集合。比如一个进程是存储和计算的闭包,一个线程是 CPU 资源(包括寄存器、ALU 等)的闭包。
再打个形象的比喻,一个 Pod 就像一个 KVM。在同一个 Pod 里的几个 Docker 服务/程序,好像被部署在同一台机器上,可以通过 localhost 互相访问,并且可以共用 Pod 里的存储资源(这里是指 Docker 可以挂载 Pod 内的数据卷)。
pod 之间网络通信
同一个 Node 中
基础容器启动前,会为容器创建一个 虚拟 Ethernet 接口对 (veth pair):
- 一端在 node 节点的命名空间中:vethXXXX
- 一端在容器网络命名空间中:eth0
只要连接到 同一 网桥,相互之间就能通信。
不同 Node 间
两个节点之间需要连接网桥,连接网桥的方式有:
- overlay
- underlay 网络
- 常规的三层路由
为什么 Pod 会出现
Pod 是 k8s 中最小的调度单元,一个 Pod 中可以包含多个 Docker,这些 Docker 都会被调度到同一台 Node 上,这些 Docker 共享 NetWork、Namespace,并且可以声明共享同一个 Volume 来共享磁盘空间。
这样的好处是什么呢?其实在真实的世界中,很多应用是有部署在同一台机器的需求的,比如 Redis 日志采集插件要采集日志,肯定需要和 Redis 部署在同一台机器上才能读到 Redis 的日志,我们前面讲述背景的时候说到了 Docker Swarm 存在一些问题,其中之一就是它只是基于 Docker 调度,虽然也可以设置亲和度让两台 Docker 调度在同一个机器上,但是因为不能一起调度,所以会存在一个Docker 提前被调度到了一个资源少的机器上,从而导致第二个 Docker 调度失败。
例如我们一共有 2 台容器,A和B,分别为 Redis 和 日志采集组件,各需要 2g 内存,现在有两台 node,node1 3.5 内存,node2 4g内存,在 Docker Swarm 的调度策略下,先调度 Redis,有可能被调度到了 node1 上,接下来再来调度日志采集组件,发现 node1 只有 1.5g 内存了,调度失败。但是在 k8s 中,调度是按照 pod 来调度的,两个组件在一个 pod 中,调度就不会考虑 node1。
Pod 的控制
虽然 Pod 已经可以运行 Redis 服务了,但是他不具备高可用性,因为一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点,这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去。为了让服务可以一直在,还需要使用 Deployment 这样的控制器。
Deployment 可以定义多副本个 Pod,从而为应用提供迁移能力,如果单纯使用 Pod,实际上当应用被调度到某台机器之后,机器宕机应用也无法自动迁移,但是使用 Deployment,则会调用 ReplicaSet(一种控制器) 来保证当前集群中的应用副本数和指定的一致。