容器与kubernetes的网络(三)

158 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

pod——kubernetes的最小计算单元介绍

Pod (豌豆荚)是一组容器的集合,是Kubernetes 创建和管理的、最小的可部署的计算单元。pod中总是包含一个Infra 容器,Infra 容器永远是第一个被创建的,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起。Pod 里的所有容器,共享同一个 Network Namespace,并且可以声明共享同一个 Volume。因此:

  • 同一个pod中的容器之间可以直接使用 localhost 进行通信;
  • 它们看到的网络设备跟 Infra 容器看到的完全一样;
  • 一个 Pod 只有一个 IP 地址,也就是这个 Pod 的 Network Namespace 对应的 IP 地址;
  • 当然,其他的所有网络资源,都是一个 Pod 一份,并且被该 Pod 中的所有容器共享;
  • Pod 的生命周期只跟 Infra 容器一致,而与其他容器 无关。

image.png

image.png

pod之间的网络通信

单机容器的bridge网络模式,容器之间无法实现跨主机ip互访,在k8s集群中,pod部署在多台主机,在集群内部,显然需要实现pod间跨主机网络。最简单的方式就是将pod与宿主机共用网络命名空间(hostNetwork: true),好处是简单高效,缺点是网络资源没有隔离,并且容易产生端口冲突。另一个方式是利用CNI(container network interface)插件,为pod的infra容器创建网络命名空间、配置网络参数,并实现跨主通信的网络方案。我们使用的cni插件是calico。

图:通过看pod的ip确定pod使用的是主机网络还是容器网络

image.png calico网络解析:

1、calico插件以daemonset方式部署在每一台主机,主机加入集群时,根据配置信息,分配一个ip地址block,创建IP隧道(IP tunnel)设备tunl0等,添加和同步集群路由信息并配置到本地

2、一个pod被调度到某台主机上,该主机的kubelet调用calico插件,为pod的infra容器创建网络命名空间、配置网络参数,其中eth0为veth设备在容器命名空间的一端

image.png pod调度所在主机上配置veth另一端,新增一条路由信息,发往69的包,进入cali6588c215a7d设备

image.png 3、其他主机访问该ip的实现,我们使用 overlay (ipip)模式,并开启cross subnet 特性,集群路由信息由BGP维护同步。

3.1、访问主机与宿主机在同一子网,类似flannel host-gw模式,即以主机为网关,根据主机加入时配置的路由信息,网络包经主机网卡,下一跳地址设置为容器所在主机ip,直接二层转发到pod所在主机,pod所在主机根据前文所述路由信息转发到对应的veth设备

image.png

image.png 3.2、访问主机与宿主机不在同一子网,跨子网的主机间不能直接设置下一跳到目标宿主机,所以采用IPIP模式

IP 包进入 IP 隧道设备之后,就会被 Linux 内核的 IPIP 驱动接管。IPIP 驱动会根据路由信息将这个 IP 包直接封装在一个宿主机网络的 IP 包中,走三层路由到对应主机,再解包。相对host-gw模式,效率会更低一些。

image.png

image.png