Kubernetes网络模型!
k8s对Pods之间如何进行组网通信提出了要求,k8s对集群的网络有以下要求:
- 所有的Pods之间可以在不使用NAT网络地址转换的情况下相互通信
- 所有的Nodes之间可以在不使用NAT网络地址转换的情况下相互通信
- 每个Pod自己看到的自己的ip和其他Pod看到的一致
k8s网络模型设计基础原则:每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中 。
所以不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问。设计这个原则的原因
是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题。由于 Kubemetes 的网络模型假设 Pod 之间访问时使用的是对方 Pod 的实际地址,所以一个 Pod 内部的应用程序看到的自己的
IP 地址和端口与集群内其他 Pod 看到的一样。它们都是 Pod 实际分配的IP地址
(从dockerO上分配的)。将IP地址和端口在Pod内部和外部都保持一致, 我们可以不使用 NAT 来进行转换,地址空间也自然是平的。鉴于上面这些要求,我们需要解决四个不同的网络问题::
- Docker容器和Docker容器之间的网络
- Pod与Pod之间的网络
- Pod与Service之间的网络
- Internet与Service之间的网络
容器和容器之间的网络
- 在k8s中每个Pod中管理着一组Docker容器,这些Docker容器共享同一个网络命名空间。
- Pod中的每个Docker容器拥有与Pod相同的IP和port地址空间,并且由于他们在同- 一个网络命名空间,他们之间可以通过localhost相互访问。
什么机制让同一个Pod内的多个docker容器相互通信那?其实是使用Docker的一种网络模型:–net=container
container模式指定新创建的Docker容器和已经存在的一个容器共享一个网络命名空间,而不是和宿主机共享。新创建的Docker容器不会创建自己的网卡,配置自己的
IP,而是和一个指定的容器共享 IP、端口范围等每个Pod容器有有一个pause容器其有独立的网络命名空间,在Pod内启动Docker容器时候使用
–net=container就可以让当前Docker容器加入到Pod容器拥有的网络命名空间(pause容器)
Pod与Pod之间的网络
- k8s中,每个Pod拥有一个ip地址,不同的Pod之间可以直接使用改ip与彼此进行通讯
- 在同一个Node上,从Pod的视角看,它存在于自己的网络命名空间中,并且需要与该Node上的其他网络命名空间上的Pod进行通信。
不同Node中的Pod之间通信
k8s网络模型需要每个pod必须通过ip地址可以进行访问,每个pod的ip地址总是对网络中的其他pod可见,并且每个pod看待自己的ip与别的pod看待的是一样的
k8s中每个集群中的每个Node都会被分配了一个CIDR块(无类别域间路由选择,把网络前缀都相同的连续地址组成的地址组称为CIDR地址块)用来给该Node上的Pod分配IP地址。(保证pod的ip不会冲突)
另外还需要把pod的ip与所在的nodeip关联起来
Pod与Service之间的网络
k8s中
Service管理了一系列的Pods,每个Service有一个虚拟的ip,要访问service管理的Pod上的服务只需要访问你这个虚拟ip就可以了,这个虚拟ip是固定的,当service下的pod规模改变、故障重启、node重启时候,对使用service的用户来说是无感知的,因为他们使用的service的ip没有变。当数据包到达Service虚拟ip后,数据包会被通过k8s给该servcie自动创建的负载均衡器路由到背后的pod容器