网络模型概述

k8s的网络中主要存在四种类型的通信:同一pod内的容器间通信、各pod彼此之间的通信、pod与service间的通信、以及集群外部的流量同service之间的通信。

k8s为pod和service资源对象分别使用了各自的专用网络,pod网络由k8s的网络插件配置实现,而service的网络则由k8s集群予以指定。k8s的网络模型需要借助于外部插件实现,它要求任何实现机制都必须满足以下需求:

1、所有pod间均可不经NAT机制直接通信;

2、所有节点均可不经NAT机制而直接与所有容器通信。

3、容器自己使用的IP也是其他容器或节点直接看到的地址,即,所有pod对象都位于同一平面网络中,而且可以使用pod自身的地址直接通信。

k8s使用的网络插件需要为每个pod配置至少一个特定的地址,即podIP。podIP地址实际存在于某个网卡(可以是虚拟设备)上,而service地址却是一个虚拟IP地址,没有任何网络接口配置此地址,它由kube-proxy借助iptables规则或ipvs规则重新定向到本地端口,再将其调度至后端pod对象。service的IP地址是集群提供服务的接口,也称为clusterIP。

pod网络及其IP由k8s的网络插件负责配置和管理,具体使用的网络地址可在管理配置网络插件时指定,如10.96.0.0/16网络。而cluster网络和IP则是由k8s集群负责配置和管理,如10.96.0.0/12网络。

总结起来,k8s集群至少应该包含三个网络,一个是各主机(master、node、etcd等)自身所属的网络,其地址配置于主机的网络接口,用于各主机之间的通信;第二个是k8s集群上专用于pod资源对象的网络,它是一个虚拟网络,用于为各pod对象设定IP地址等网络参数,其地址配置于pod中容器的网络接口之上。pod网络为各pod对象设定IP地址等网络参数,其地址配置于pod中容器的网络接口之上。pod网络需要借助kubenet插件或CNI插件实现,该插件独立部署于k8s集群之外,也可托关于k8s之上;第三个时专用于service资源对象的网络,它也是一个虚拟网络,用于为k8s集群之中的service配置IP地址,但此地址并不配置于任何主机或容器的网络接口之上,而是通过node之上的kube-proxy配置为iptables或ipvs规则,从而将发往此地址的所有流量调度至其后端的各pod对象之上。service网络再k8s集群创建时予以指定,而各service的地址则在用户创建service时予以动态配置。

集群上的网络通信

k8s集群的客户端大体分为两类:apiserver客户端和应用程序(运行为pod中的容器)客户端。apiserver客户端通常包含人类用户和pod对象两种,它们通过apiserver访问k8s集群完成管理任务,应用程序客户端一般也包含人类用户和pod对象两种,它们的访问目标时pod上运行于容器中的应用程序提供的各种具体的服务,如redis或nginx等。不过,这些访问请求通常要经由service或ingress资源对象进行。另外,应用程序客户端的访问目标对象的操作要经由apiserver客户端创建和配置完成后才能进行。