文章目录

  • kubernetes02(Kubernetes内容器的网络通信方式)
  • 一.引子
  • 二.K8S中容器的网络通信方式
  • (一)pod内部容器之间
  • (二)pod 与 pod 容器之间网络通信
  • (三).pod 访问service服务
  • (四).通信总图


kubernetes02(Kubernetes内容器的网络通信方式)

一.引子

kubernetes管理pod,pod管理容器,容器我们都知道有很多连接方式。那在kubernetes里面网络通信是怎么发生的呢?让我们一起走进K8S的网络世界。

二.K8S中容器的网络通信方式

在kubernetes中里面容器是存在于pod里面的,所以容器之间通讯,一般分为三种类型:pod内部容器之间,pod 与 pod 容器之间在同一台机器,pod与pod不在一台机器。

(一)pod内部容器之间

pod里有几个容器 pod内部容器通信_pod里有几个容器

这种情况下容器通讯比较简单,因为k8s pod内部容器是共享pause容器的网络栈,所以容器直接可以使用localhost访问其他容器。
k8s在启动容器的时候会先启动一个pause容器,这个容器就是实现pod内部容器之间的网络通信的。pause挂载共享网络和共享存储。

(二)pod 与 pod 容器之间网络通信

1.两个pod在一台主机上面

pod里有几个容器 pod内部容器通信_kubernetes_02

网桥:docker之间的通信我们在之间的docker介绍之中提到过,在看K8S中,不同容器之间的通信依靠的是网桥。在同一网桥之内的容器是开源相互通信的。

2.两个pod分布在不同主机之上

pod里有几个容器 pod内部容器通信_kubernetes_03

fiannel:k8s官方推荐的是使用flannel组建一个大二层扁平网络,pod的ip分配由flannel统一分配,通讯过程也是走flannel的网桥。
flannel的原理是将网络包封装在udp里面(数据包的二次封装),所以发送端和接收端需要装包和解包,对性能有一定的影响。

docker --daemon --bip=172.17.18.1/24

注意其中的“–bip=172.17.18.1/24”这个参数,它限制了所在节点容器获得的IP范围。

每个node上面都会创建一个flannel0虚拟网卡,用于跨node之间通讯。所以容器直接可以直接使用pod id进行通讯。

跨节点通讯时,发送端数据会从docker0路由到flannel0虚拟网卡,接收端数据会从flannel0路由到docker0,这是因为flannel会添加一个路由

发送端:
route -n
172.17.0.0    0.0.0.0    255.255.0.0      U  0  0  0   flannel0
172.17.13.0  0.0.0.0    255.255.255.0  U  0  0  0   docker0

接收端:
172.18.0.0    0.0.0.0    255.255.0.0      U  0  0  0  flannel0
172.17.12.0  0.0.0.0    255.255.255.0  U  0  0  0   docker0

例如现在有一个数据包要从IP为172.17.13.2的容器发到IP为172.17.12.2的容器。根据数据发送节点的路由表,它只与172.17.0.0/16匹配这条记录匹配,因此数据从docker0出来以后就被投递到了flannel0。同理在目标节点,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的172.17.12.0/24这个记录上,自然的被投递到了docker0网卡。

(三).pod 访问service服务

这里涉及到k8s里面一个重要的概念service。它是一个服务的抽象,通过label(k8s会根据service和pod直接的关系创建endpoint,可以通过kubectl get ep查看)关联到后端的pod容器。Pod 至 Service 的网络:目前基于性能考虑,全部为 iptables 维护和转发。

Service分配的ip叫cluster ip是一个虚拟ip(相对固定,除非删除service),这个ip只能在k8s集群内部使用,如果service需要对外提供,只能使用Nodeport方式映射到主机上,使用主机的ip和端口对外提供服务。(另外还可以使用LoadBalance方式,但这种方式是在gce这样的云环境里面使用的 )。

节点上面有个kube-proxy进程,这个进程从master apiserver获取信息,感知service和endpoint的创建,然后做两件事:

  1. 为每个service 在集群中每个节点上面创建一个随机端口,任何该端口上面的连接会代理到相应的pod
  2. 集群中每个节点安装iptables规则,用于clusterip + port路由到上一步定义的随机端口上面,所以集群中每个node上面都有service的转发规则:

KUBE-PORTALS-CONTAINER 从容器中通过service cluster ip和端口访问service的请求

KUBE-PORTALS-HOST 从主机中通过service cluster ip和端口访问service的请求

KUBE-NODEPORT-CONTAINER 从容器中通过service nodeport端口访问service的请求

KUBE-NODEPORT-HOST 从主机中通过service nodeport端口访问service的请求。

见下面测试环境的内容:

-A KUBE-NODEPORT-CONTAINER -p tcp -m comment --comment "smart/ccdb:port1521"  -m tcp --dport 50171 -j REDIRECT --to-ports 52244

-A KUBE-NODEPORT-HOST -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 50171 -j DNAT --to-destination 10.45.25.227:52244

-A KUBE-PORTALS-CONTAINER -d 10.254.120.169/32 -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 1521 -j REDIRECT --to-ports 52244

-A KUBE-PORTALS-HOST -d 10.254.120.169/32 -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 1521 -j DNAT --to-destination 10.45.25.227:52244
52244就是kube-proxy针对service “"smart/ccdb:port1521"” 在节点上面监听的端口。

(四).通信总图

ETCD 之 Flannel 提供说明:

> 存储管理 Flannel 可分配的 IP 地址段资源

> 监控 ETCD 中每个 Pod 的实际地址,并在内存中建立维护 Pod 节点路由表

pod里有几个容器 pod内部容器通信_docker_04


pod里有几个容器 pod内部容器通信_kubernetes_05


kubernetes的理解还是不容易的,大家先对概念有一个简单的了解,后面我们将越来越多地涉及到更深的内容,最后回首一看就没有这么难了。