K8S 容器之间通讯方式

概述

首先k8s里面容器是存在于pod里面的,所以容器之间通讯,一般分为三种类型:

1. pod内部容器之间

2. pod 与 pod 容器之间

3. pod 访问service服务

pod内部容器之间

这种情况下容器通讯比较简单,因为k8s pod内部容器是共享网络空间的,所以容器直接可以使用localhost访问其他容器。

k8s在启动容器的时候会先启动一个pause容器,这个容器就是实现这个功能的。

pod 与 pod 容器之间

这种类型又可以分为两种情况:

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

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

针对第一种情况,就比较简单了,就是docker默认的docker网桥互连容器。

第二种情况需要更为复杂的网络模型了,k8s官方推荐的是使用flannel组建一个大二层扁平网络,pod的ip分配由flannel统一分配,通讯过程也是走flannel的网桥。

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会添加一个路由

发送端:

1route -n 2172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0 3172.17.13.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0

接收端:

1route -n 2172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0 3172.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网卡。

flannel的原理是将网络包封装在udp里面,所以发送端和接收端需要装包和解包,对性能有一定的影响。

k8s也支持其他的网络模型,比较有名的还有calico,不过我并没有使用过。

pod 访问service服务

这里涉及到k8s里面一个重要的概念service。它是一个服务的抽象,通过label(k8s会根据service和pod直接的关系创建endpoint,可以通过kubectl get ep查看)关联到后端的pod容器。

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的转发规则:

1KUBE-PORTALS-CONTAINER //从容器中通过service cluster ip和端口访问service的请求 2 3KUBE-PORTALS-HOST //从主机中通过service cluster ip和端口访问service的请求 4 5KUBE-NODEPORT-CONTAINER //从容器中通过service nodeport端口访问service的请求 6 7KUBE-NODEPORT-HOST //从主机中通过service nodeport端口访问service的请求。

见下面测试环境的内容:

1-A KUBE-NODEPORT-CONTAINER -p tcp -m comment --comment "smart/ccdb:port1521" -m tcp --dport 50171 -j REDIRECT --to-ports 52244 2 3-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 4 5-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 6 7-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"” 在节点上面监听的端口。

原文:https://www.jianshu.com/p/b4eabf55533d

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

k8s超详细总结

一个目标:容器操作;两地三中心;四层服务发现;五种Pod共享资源;六个CNI常用插件;七层负载均衡;八种隔离维度;九个网络模型原则;十类IP地址;百级产品线;千级物理机;万级容器;相如无亿,K8s有亿:亿级日服务人次。一个目标:容器操作Kubernetes(k8s)是自动化容器操作的开源平台。这些容

K8S命令集

命令说明kubectln<namespacegetpods获取指定命名空间podkubectldescribepods<pod查看指定pod事件明细kubectlexecit<podbash进入指定pod容器kubectldescribepod查看pod描述信息与Event事件kub

kubernetes资源

在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在K8S中,当Pod重建的时候,数据是会丢失的,K8S也是通过数据卷挂载来提供Pod数据的持久化的。K8S数据卷是对Docker数据卷的扩展,K8S数据卷是Pod级别的,可以用来实现Pod中

Istio Sidecar注入原理

概念简单来说,Sidecar注入会将额外容器的配置添加到Pod模板中。这里特指将Envoy容器注应用所在Pod中。Istio服务网格目前所需的容器有:istioinit用于设置iptables规则,以便将入站/出站流量通过Sidecar代理。初始化容器与应用程序容器在以下方面有所不同:

K8S从入门到放弃系列

摘要:Kubelet组件运行在Node节点上,维持运行中的Pods以及提供kuberntes运行时环境,主要完成以下使命:  1.监视分配给该Node节点的pods  2.挂载pod所需要的volumes  3.下载pod的secret  4.通过docker/rkt来运行pod中的容器  5.周期的执行pod中为容器定义的