k8s中的整体架构 ,pod含义,服务类型,网络通讯等
- k8s整体架构
- pod内部和pod之间的通讯
- k8s的组件
k8s整体架构
上图中,较大的红框是k8s中的master节点,负责接受请求,调度任务,管理节点等,较小的红框中的是node节点,是负责具体干活的节点;
在master节点中,
scheduler是调度器,任务过来之后,要通过scheduler把任务分散到不同的node中。它先将请求发送给api server,api server再将请求发送给etcd;
replication controller(RC)是控制器,负责控制副本数量满足期望值,一旦超出或者不足,RC会删除pod或者新建pod;
api server: 所有服务访问统一入口;scheduler和RC可以在本地生成一些缓存,这样不需要每次都和api server进行交互,环节api server的压力。
etcd是一个可信赖的分布式键值存储数据库,负责和api server进行交互,存储类似拓扑结构,服务发现等一些关键信息。它天生支持集群方式搭建,raft协议,方便扩展,
在node节点中,
kubelet会与CRI(container容器,runtime运行环境,interface接口)交互,实现容器的生命周期管理
kube proxy 实现pod与pod之间的访问,负载均衡等的功能;以上是k8s的核心功能组件,还有一些其他插件,例如coreDNS,dashboard,ingress controller,federation,prometheus,ekl等,见下方图片的说明:
pod内部和pod之间的通讯
k8s网络模型假定了所有pod都在一个可以直接连通的扁平的网络空间中。这个看似简单的操作实际上需要底层网络进行复杂的布局。
同一个pod内多个容器之间的通讯是通过lo(localhost+端口号,回环网卡)
各个pod之间的通讯:overlay network
pod和service之间的通讯:各个节点的iptables规则(lvs)
flannel是CoreOS团队针对k8s设计的一个网络规划服务。它的功能是让集群中不同节点主机创建的docker容器都具有全集群唯一的虚拟ip地址,并且这些ip地址之间建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包在各个目标容器之间进行传输。
在k8s各个服务器上会启动一个flanneld守护进程,它会创建一个flannel0的网桥,网桥flannel0会收集网关docker0转发的数据包。docker0会把自己的ip分配到不同的pod上(web app2 ,web app1等),那么同一个服务器上的不同pod就可以通过docker0来进行网络通讯;那么不同主机的pod之间是如何通过pod的ip进行通讯的呢?
例如web app2要向backend进行转发,首先docker0会判断sourceIP 10.1.15.2/24和destIP 10.1.20.3/24不是同一个网段的,那么就会把数据包发送到自己的网关docker0上,docker0上会有钩子函数把数据包发送到flannel0,flannel0上面会有很多的路由表记录(从etcd获取),找到这个数据包应该发送到哪一个主机。之后会把数据包发送到flanneld守护进程中,flanneld对数据包进行封装(见上图右上角),采用udp的方式进行转发。
数据包会被相应主机截获,被flanneld进行解析,之后通过flannel0和docker0转发,最终达到目标pod backend中。
flannel将可分配的ip地址资源端存储在etcd中,防止为pod分配ip的时候发生重复;
维护pod节点路由表,这样才能知道podIP和真实主机IP的对应关系,实现pod之间扁平化的通讯方式。
下面再来说说PodIP,PodIP是k8s分配给pod的IP,每个pod各不相同,到都在一个大的网断内,各个pod可以互通互联,并且集群的节点也可以通过PodIP访问到各个pod的服务。为了理解它的原理,我们先看下面这张图:
上图中,cni0和flannel.1网络设备都是flannel网络插件生成的虚拟网络设备,使用cni0是一个bridge设备,flannel.1是一个vxlan设备,cni0连接着该节点上的各个pod以及flannel.1。而flannel.1的另一头连着flanneld进程,所有进入flannel.1的流量都会交给flanneld进程进行处理,而flanneld会把数据包3层(IP层)及以上的包封装到一个udp包中,然后查找系统配置,找到数据包需要发送到的节点的IP,然后发送给对端节点的指定udp端口(5678),这个技术就是vxlan,可以将非同一网段的设备通过公网组成同一网段(内网)。
k8s的组件