作者:余凯

本系列文章由余凯执笔创作,联结作者:阿里云云原生利用平台 谢石 对本文亦有奉献

前言

近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的 IaaS 化到当初的微服务化,客户的颗粒度精细化和可观测性的需要更加强烈。容器网络为了满足客户更高性能和更高的密度,也始终在高速的倒退和演进中,这必然对客户对云原生网络的可观测性带来了极高的门槛和挑战。为了进步云原生网络的可观测性,同时便于客户和前后线同学减少对业务链路的可读性,ACK 产研和 AES 联结共建,合作开发 ack net-exporter 和云原生网络数据面可观测性系列,帮忙客户和前后线同学理解云原生网络架构体系,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学解决疑难问题的体验 ,进步云原生网络的链路的稳定性。

鸟瞰容器网络,整个容器网络能够分为三个局部:Pod 网段,Service 网段和 Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限度又是什么呢?Flannel, Terway 有啥区别?不同模式下网络性能如何?这些,须要客户在下搭建容器之前,就要根据本人的业务场景进行抉择,而搭建结束后,相干的架构又是无奈转变,所以客户须要对每种架构特点要有充沛理解。比方下图是个简图,Pod 网络既要实现同一个ECS的Pod间的网络互通和管制,又要实现不同 ECS Pod 间的拜访, Pod 拜访 SVC 的后端可能在同一个 ECS 也可能是其余 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧体现后果也是不一样的。

本文是[全景分析容器网络数据链路]第一局部,次要介绍 Kubernetes Flannel 模式下,数据面链路的转转发链路,一是通过理解不同场景下的数据面转发链路,从而探知客户在不同的场景下拜访后果体现的起因,帮忙客户进一步优化业务架构;另一方面,通过深刻理解转发链路,从而在遇到容器网络抖动时候,客户运维以及阿里云同学能够晓得在哪些链路点进行部署观测手动,从而进一步定界问题方向和起因。

系列二:

全景分析阿里云容器网络数据链路(二):Terway ENI

系列三:

全景分析阿里云容器网络数据链路(三):Terway ENIIP

系列四:

全景分析阿里云容器网络数据链路(四):Terway IPVLAN+EBPF

系列五:

全景分析阿里云容器网络数据链路(五):Terway ENI-Trunking

系列六:

全景分析阿里云容器网络数据链路(六):ASM Istio

Flannel 模式架构设计

Flannel 模式下,ECS 只有一个主网卡 ENI,无其余从属网卡,ECS 和节点上的 Pod 与内部通信都须要通过主网卡进行。ACK Flannel 会在每个节点创立 cni0 虚构网卡作为 Pod 网络和 ECS 的主网卡 eth0 之间的桥梁。

集群的每个节点会起一个 flannel agent,并且会给每个节点预调配一个 Pod CIDR,这个 Pod CIDR 是ACK集群的 Pod CIDR 的子集。

容器的网络命名空间内会有一个 eth0 的虚构网卡,同时存在下一跳指向该网卡的路由,该网卡会作为容器和宿主内核进行数据交换的出入口。容器和宿主机之间的数据链路是通过 veth pair 进行替换的,当初咱们曾经找到 veth pair 其中一个,如何去找另一个 veth 呢?

如上图所示,咱们能够容器的网络命名空间中通过 p addr 看到一个 eth0@if81 的标记位,其中 ‘81' 这个将会帮助咱们在 ECS 的 OS 内找到找到和容器网络命名空间中的 veth pair 绝对一个。在 ECS OS 内咱们通过 ip addr | grep 81: 能够找到 vethd7e7c6fd 这个虚构网卡,这个就是 veth pair 在 ECS OS 侧绝对的那一个。

到目前为止容器内和 OS 数据链路曾经建设链接了,那么 ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing 咱们能够看到,所有目标是 Pod CIDR 网段的流量都会被转发到 cni0 这张虚构网卡,那么 cni0 是通过 bridge 形式将不同目标的数据链路指向到不同的 vethxxx。到这里为止,ECS OS 和 Pod 的网络命名空间曾经建设好残缺的出入链路配置了。

Flannel 模式容器网络数据链路分析

针对容器网络特点,咱们能够将 Flannel 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分能够拆分到 10 个不同的小的 SOP 场景。

对这 10 个场景的数据链路梳理合并,这些场景能够演绎为上面 5 类典型的场景:

  • Client 和服务端 Pod 部署于同一个 ECS
  • Client 和服务端 Pod 部署于不同 ECS
  • 拜访 SVC External IP, ExternalTrafficPolicy 为 Cluster 时,Client 和服务端 Pod 部署于不同ECS,其中client为集群外
  • 拜访 SVC External IP, ExternalTrafficPolicy 为 Local 时, Client 和服务端 Pod 部署于不同 ECS,其中client为集群内
  • 拜访 SVC External IP, ExternalTrafficPolicy 为 Local 时, Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群外

场景一:Client和服务端Pod部署于同一个ECS

此场景蕴含上面几个子场景,数据链路能够演绎为一种:

  1. 以 Pod IP 对外提供服务,Client 和 Pod 部署于同一个节点;
  2. 以 SVC ClusterIP 对外提供服务,Client 和 SVC 后端 Pod 部署于同一节点;
  3. 以 SVC ExternalIP 对外提供服务,ExternalTrafficPolicy 为 Cluster/Local 状况下,Client 和 SVC 后端 Pod 部署于同一节点

环境

ap-southeast-1.10.0.0.180 节点上存在两个pod:centos-67756b6dc8-rmmxt  IP地址172.23.96.23  和 nginx-7d6877d777-6jkfg 和172.23.96.24

内核路由

centos-67756b6dc8-rmmxt  IP地址172.23.96.23,该容器在宿主机体现的 PID 是503478,该容器网络命名空间有指向容器 eth0 的默认路由

该容器 eth0 在 ECS OS 内对应 veth pair 是 vethd7e7c6fd

通过上述相似的方法,能够找到nginx-7d6877d777-6jkfg  IP地址172.23.96.24,该容器在宿主机体现的 PID 是2981608,该容器 eth0 在 ECS OS 内对应veth pair是vethd3fc7ff4

在 ECS OS 内,有指向 Pod CIDR,下一跳为 cni0 的路由,以及 cni0 中有两个容器的vethxxx 网桥信息

小结:能够拜访到目标端

▲数据链路转发示意图

▲内核协定栈示意图

  • 数据链路:ECS1 Pod1 eth0 ->  vethxxx1 -> cni0 -> vethxxxx2 -> ECS1 Pod2 eth0
  • 数据链路要通过三次内核协定栈,别离是 Pod1 协定栈, ECS OS 协定栈 和 Pod2 协定栈

场景二:Client 和服务端 Pod 部署于不同 ECS

此场景蕴含上面几个子场景,数据链路能够演绎为一种:

  1. 以 Pod IP 对外提供服务,Client 和 Pod 部署于不同节点;
  2. 以 SVC ClusterIP 对外提供服务,Client和SVC 后端Pod部署于不同节点;
  3. 以 SVC ExternalIP 对外提供服务,ExternalTrafficPolicy 为 Cluster 状况下,集群内 Client 和 SVC 后端 Pod 部署于不同节点;

环境

ap-southeast-1.10.0.0.180 节点上存在两个 pod:centos-67756b6dc8-rmmxt  IP地址172.23.96.23  和 nginx1-76c99b49df-7plsr  IP 地址172.23.96.163

Service nginx1 的 ExternalTrafficPlicy 为 Cluster

内核路由

Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中曾经做了详细描述,此处不再果决篇幅形容。

源端 Pod 所在 ECS 的 IPVS 规定

能够看到,源端数据链路拜访 svc 的clusterip 192.168.13.23 时,如果链路达到 ECS 的OS 内,会命中 ipvs 规定,被解析到 svc 的后端 endpoint 之一(本实例中只有一个 pod,所以 endpoint 只有一个)

小结:能够胜利拜访到目标端

▲数据链路转发示意图

VPC 路由表会主动配置目标地址是 pod CIDR, 下一跳为 POD 网段所归属的 ECS 的自定义路由条目,该规定由 ACK 管控测通过 openapi 调用 VPC 去配置,无需手动配置和删除

▲内核协定栈示意图

Conntack 表信息(拜访 SVC 状况)

Node1:

src是源pod IP,dst是svc的ClusterIP,并且冀望是由svc的其中一个endpoint 172.23.96.163 来回音讯给源端 pod

Node2:

目标 pod 所在 ECS 上 conntrack 表记录是由源端 pod 拜访目标 pod,不会记录 svc 的clusterip 地址

  • 数据链路:ECS1 Pod1 eth0 ->  vethxxx1 -> cni0 -> ECS 1 eth0 ->  VPC -> ECS2 eth0 -> cni0 ->  vethxxxx2 -> ECS2 Pod2 eth0
  • 数据链路要通过四次内核协定栈,别离是 Pod1 协定栈, ECS1 OS 协定栈 , ECS2 OS 协定栈和 Pod2 协定栈
  • VPC 路由表会主动配置目标地址是 pod CIDR, 下一跳为 POD 网段所归属的 ECS 的自定义路由条目,该规定由 ACK 管控测通过 openapi 调用 VPC 去配置,无需手动配置和删除
  • 如果拜访的 SVC 的 cluster IP,或者是 Cluster 模式下,拜访 SVC 的 externalIP,数据链路通过veth pair进到 ECS OS 内后,会命中相应的 IPVS 规定,并依据负载规定,抉择IPVS的某一个后端,进而打到其中的一个 SVC 的后端 endpoint,SVC 的 IP 只会再 PoD 的 eth0 , veth pair vethxxx 被捕捉到,其余链路环节不会捕捉到 svc 的 IP

场景三:ExternalTrafficPolicy 为 Local时,Client 和服务端 Pod 部署于集群内不同 ECS

此场景蕴含上面几个子场景,数据链路能够演绎为一种:

1.以SVC ExternalIP对外提供服务,ExternalTrafficPolicy 为 Local状况下,集群内 Client 和 SVC 后端 Pod 部署于不同节点;

环境

ap-southeast-1.10.0.0.180 节点上存在两个pod:centos-67756b6dc8-rmmxt  IP地址172.23.96.23  和 nginx1-76c99b49df-7plsr  IP 地址172.23.96.163

Service nginx1 ExternalTrafficPolicy 为 Local

内核路由

Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中曾经做了详细描述,此处不再果决篇幅形容。

源端 Pod 所在 ECS 的 IPVS 规定

能够看到,源端数据链路拜访 svc 的 externalip  8.219.164.113 时,如果链路达到 ECS 的OS内,会命中ipvs规定,然而咱们能够看到EcternalIP  并没有相干的后端 endpoint,链路达到 OS 后,会命中 IPVS 规定,然而没有后端 pod,所以会呈现 connection refused

小结:不能够拜访到目标端,此时会拜访失败,Connection refused

▲数据链路转发示意图

▲内核协定栈示意图

  • 数据链路:ECS1 Pod1 eth0 ->  vethxxx1 ->
  • 数据链路要通过一次半内核协定栈,别离是 Pod1 协定栈,半个 ECS1 OS 协定栈
  • 如果拜访的 SVC 的 External IP,或者是 Local 模式下,拜访 SVC 的 externalIP,数据链路通过 veth pair 进到 ECS OS内后,会命中相应的 IPVS 规定,然而因为 Local 模式,External IP的 IPVS 为空,所以命中规定然而无转发后端,整个链路会在 ipvs 终止,拜访失败。所以倡议集群内采纳 clusterip 拜访,这也是 k8s 官网举荐的最佳实际。

场景四:ExternalTrafficPolicy 为 Local 时,Client 来自于集群外

此场景蕴含上面几个子场景,数据链路能够演绎为一种:A.拜访SVC External IP, ExternalTrafficPolicy 为 Local时, Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群外

环境

Deployment为nginx1, 别离为三个pod nginx1-76c99b49df-4zsdj和nginx1-76c99b49df-7plsr 部署在 ap-southeast-1.10.0.1.206 ECS上,最初一个pod nginx1-76c99b49df-s6z79 部署在其余节点 ap-southeast-1.10.0.1.216 上

Service nginx1 的ExternalTrafficPlicy 为 Local

内核路由

Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中曾经做了详细描述,此处不再果决篇幅形容。

SLB 相干配置

从 SLB 控制台,能够看到 SLB 后端的虚构服务器组中只有两个 ECS 节点ap-southeast-1.10.0.1.216 和 ap-southeast-1.10.0.1.206。集群内的其余节点 ,比方 ap-southeast-1.10.0.0.180 并未被加到 SLB 的后端虚构服务器组中。虚构服务器组的 IP 为 ECS 的 IP,端口为 service 外面的 nodeport 端口 32580.

故 ExternalTrafficPolicy 为 Local 模式下,只有有 Service 后端 pod 所在的 ECS 节点才会被退出到 SLB 的后端虚构服务器组中,参加 SLB 的流量转发,集群内的其余节点不参加 SLB 的转发

SLB 虚构服务器组 ECS 的 IPVS 规定

从SLB的虚构服务器组中的两个 ECS 能够看到,对于 nodeip+nodeport 的 ipvs转发规定是不同。ExternalTrafficPolicy 为 Local 模式下,只有该节点上的护短 pod 才会被加到该节点的 ipvs 转发规定中,其余节点上的后端 pod 不会加进来,这样保障了被 SLB 转发的链路,只会被转到该节点上的 pod,不会转发到其余节点上。

node1:ap-southeast-1.10.0.1.206

node1:ap-southeast-1.10.0.1.216

小结:能够拜访到目标端

▲数据链路转发示意图

该图示意了只有后端 pod 所在 ECS 才会加到 SLB 后端中,从集群内部拜访 SVC 的externalIP(SLB IP)的状况,可见数据链路只会被转发到虚构服务器组中的 ECS,不会再被转发到集群内其余节点上。

▲内核协定栈示意图

Conntack 表信息

Node:

src 是集群内部客户端IP,dst 是节点 IP,dport 是 SVC 中的 nodeport。并且冀望是由该 ECS 上的 pod 172.23.96.82 来回包给源端

  • 数据链路:client ->  SLB  -> ECS eth0 + ECS nodeport  ->  cni0 ->  vethxxxxx -> ECS1 Pod1 eth0
  • 数据链路要通过两次内核协定栈,别离是 Pod1 协定栈, ECS1 OS 协定栈
  • ExternalTrafficPolicy 为 Local 模式下,只有有 Service 后端 pod 所在的 ECS 节点才会被退出到SLB的后端虚构服务器组中,参加 SLB 的流量转发,集群内的其余节点不参加 SLB 的转发

场景五:ExternalTrafficPolicy 为 Cluster 时,Client 来自于集群外

此场景蕴含上面几个子场景,数据链路能够演绎为一种:

1.拜访 SVCExternal IP, ExternalTrafficPolicy 为 Cluster 时, Client 和服务端 Pod部署于不同 ECS,其中 client 为集群外

环境

Deployment为nginx1, 别离为三个pod nginx1-76c99b49df-4zsdj和nginx1-76c99b49df-7plsr 部署在 ap-southeast-1.10.0.1.206 ECS上,最初一个pod nginx1-76c99b49df-s6z79 部署在其余节点 ap-southeast-1.10.0.1.216 上

Service nginx2 的 ExternalTrafficPlicy 为 Cluster

内核路由

Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中曾经做了详细描述,此处不再果决篇幅形容。

SLB 相干配置

从SLB 控制台,集群内所有节点ap-southeast-1.10.0.0.180、ap-southeast-1.10.0.1.216 和 ap-southeast-1.10.0.1.206 都被加到SLB的虚构服务器组中。其中 虚构服务器组的 IP 为 ECS 的 IP,端口为 service 外面的 nodeport 端口 30875.

故 ExternalTrafficPolicy 为 CLuster 模式下,集群内所有的 ECS 节点都会被退出到 SLB 的后端虚构服务器组中,参加 SLB 的流量转发。

SLB 虚构服务器组 ECS 的 IPVS 规定

从SLB的虚构服务器组中的能够看到,对于 nodeip+nodeport 的 ipvs 转发规定是统一的。ExternalTrafficPolicy为 CLuster 模式下,所有的 service 后端 pod 都会被加到所有节点的 ipvs 的转发规定中,即便是该节点有后端 pod,流量也不肯定会被转发到该节点上 pod,可能会被转发到其余节点上的后端 pod。

node1:ap-southeast-1.10.0.1.206 (该节点有后端pod)

node1:ap-southeast-1.10.0.1.216 (该节点有后端pod)

node3:     ap-southeast-1.10.0.0.180 (该节无后端pod)

小结:能够拜访到目标端

▲数据链路转发示意图

该图示意了集群内所有 ECS 都会被加到 SLB 后端中,从集群内部拜访 SVC 的externalIP(SLB IP)的状况,数据流量可能会被转发到其余节点上

内核协定栈示意图:

内核协定栈示意图曾经在 2.4 场景一中曾经做了详细描述,此处不再果决篇幅形容。

Conntack 表信息

链路1:

ap-southeast-1.10.0.0.180:

此时数据链路对应示意图中的链路1,能够看到数据链路被转到 ap-southeast-1.10.0.0.180 节点,该节点上并没有 service 的后端 pod,通过 conntrack 信息,能够看到

src 是集群内部客户端 IP,dst 是节点 IP,dport 是 SVC 中的 nodeport。并且冀望是172.23.96.163 来回包给 10.0.0.180 。通过前述信息,能够得悉172.23.96.163 是nginx1-76c99b49df-7plsr pod,部署在 ap-southeast-1.10.0.1.206

ap-southeast-1.10.0.1.206:

通过此节点conntrack 表,能够看到src是 node  ap-southeast-1.10.0.0.180,dst 是 172.23.96.163的80 端口,回包也是间接回给 node  ap-southeast-1.10.0.0.180.

综上能够看到 src 变换了屡次,故在 CLuster 模式下,会存在失落实在客户端 IP 的状况

链路2:

src 是集群内部客户端 IP,dst 是节点IP,dport 是 SVC 中的 nodeport。并且冀望是由该 ECS 上的 pod 172.23.96.82 来回包给 172.23.96.65,此地址是 SLB 集群中的一个地址

  • 数据链路:情景一:client ->  SLB  -> ECS eth0 + ECS nodeport  ->  cni0 ->  vethxxxxx -> ECS1 Pod1 eth0情景二:client ->  SLB  -> ECS1 eth0 + ECS1 nodeport  -> VPC Routing ->  ECS2 eth0 + pod port   -> cni0 ->  vethxxxxx -> ECS2 Pod1 eth0
  • 数据链路要通过三次内核协定栈,别离是 ECS1 OS、 ECS2 OS 协定栈 和 Pod 协定栈
  • ExternalTrafficPolicy 为 CLuster 模式下,kubernetes 所有 ECS 节点都会被退出到 SLB 的后端虚构服务器组中,参加 SLB 的流量转发,此时会存在数据路在集群内被多个 ECS 转发的场景,该状况下会失落实在客户端IP的状况

总结

本篇文章次要聚焦 ACK 在 Flannel 模式下,不同 SOP 场景下的数据链路转发门路。随着微服务化和云原生化,网络场景日趋简单,作为 kubernetes 原生的网络模型——Flannel,不同的拜访环境,一共能够分为10个 SOP 场景。通过深刻简出的分析,能够演绎为5个场景,并对这五个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对咱们遇到 Flannel 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向。接下来将进入到阿里自研的 CNI 接口 Terway 模式,也是目前线上集群应用最多的模式,下一系列咱们先带来 Terway  ENI 模式的全景解析——ACK 全景分析阿里云容器网络数据链路(二):Terway ENI。

点击此处理解阿里云容器服务