作者:若禾

CNStack 是阿里云推出的一款开放的一站式企业级云原生技能中台。在异构的混合云根底设施上,对资源进行一致纳管和优化调度,以开放的、云原生的方法为渠道及事务系统供给出产可用的产品及组件,协助用户打造满意大规划、高功用、合规性和事务连续性等要求的分布式应用系统,提高企业数字化转型的整体效能。hybridnet 是 CNStack 运用的容器网络完结,一起也是阿里云推出的唯二开源通用 K8s 网络插件完结之一。

开源库房地址:github.com/alibaba/hyb…

解说下“通用”俩字,阿里云现在存在两种开源 K8s 网络插件完结:terway、hybridnet。与 hybridnet 网络插件不同,terway 网络插件是与阿里云根底设施紧密结合的,并不考虑在非阿里云公有云根底设施环境布置的状况,而 hybridnet 更像是相似 flannel、calico 的社区处理计划,支撑在任意环境拉起和布置。本文会具体描绘 hybridnet 网络插件的规划与完结。

布景

从诞生到现在,在阿里内部 hybridnet 一向承载的是“私有化交给基石”的人物,即为以 K8s 为交给前言的 PaaS/SaaS 产品供给在客户线下机房的网络布置、运维才能,其性质看起来也就和 “为一切人供给 K8s 网络” 愈加相似,咱们对 hybridnet 的希望有几点:

  1. 架构简略、功用安稳。关于要交给到客户线下机房的产品,一旦呈现问题,排查成本是十分高的,安稳性是重中之重。

  2. “On Anywhere” 布置。这的确是一开始的希望,听起来不可思议,但某种程度上的确完结了。

  3. 灵活。能够满意不同客户功用需求以及就广泛通用场景进行功用扩展。

  4. 运维简略。负责交给施行的同学能够快速上手。

当然,社区也存在众多优异的网络插件完结,咱们也对其进行了了解和调研,总结下最终没有采用的原因:

  1. 社区网络插件的网络形式是相对简略的,不是 overlay 便是 underlay,看下来无法既完结 “On Anywhere” 布置,又满意客户关于 underlay 网络场景的需求(功用或许网络打通)。

  2. 关于 underlay 网络场景需求,社区供给的干流处理方法一向是 “只供给经过 bgp 宣告路由” 的方法,这种方法对没有进行 bgp 组网的公司并不是很友好,咱们仍需求没有 bgp 条件环境下的容器网络完结(也便是 vlan 方法),这方面社区并没有十分老练的计划。

  3. 大部分社区网络插件的 ip 分配是 “为节点分配网段” 的模型,好像并没有考虑处于 “传统运维” 过渡到 “云原生运维” 阶段用户或许存在的“需求容器固定 ip 被拜访”的场景,也难以扩展完结。

  4. 部分社区网络插件的技能体系(ovs、ebpf)在运维、二次开发方面的门槛和成本比较高。

规划与完结

怎么 “On Anywhere”

在规划之初,需求想理解的一个问题是:怎么既完结 “On Anywhere” 布置又满意客户关于 underlay 网络场景的需求?首先咱们要理解 overlay、underlay 在交给场景下的不同含义。

“overlay” 的网络计划作为在根底网络之上构建的抽象网络,自身其实便是屏蔽了底层根底设施依靠的,以 vxlan 容器网络为例,容器网络的 ip 流量被封装成宿主机的 udp 数据包,依靠的仅仅比较简略的 “底层网络环境放行 udp 流量” 才能,其完结已具备了 “On Anywhere” 布置的条件。

而在 “underlay” 容器网络计划中,容器网络的报文被 “原封不动” 地经过宿主机网卡转发到根底网络环境里,凭借底层网络完结后续的通讯,底层网络环境需求具备打通以及放行一切容器网络流量的才能,这就在不同场景下带来了交给上的重重挑战,交给一个 underlay K8s 集群时,在 K8s 集群能正常作业之前,咱们需求客户协助进行的作业包含可是不限于 “恳求/规划网段”、“装备交换机端口”、“装备交换机路由”、“修改防火墙” 等等,整个进程由于门槛要素往往需求网络专家直接参与,极大增加了交给成本。

随着交给经验的堆集,咱们发现,大部分需求私有化交给的产品是不依靠 underlay 网络才能的,即便是产品需求依靠 underlay 才能,这部分 pod 的数量在整个集群中的占比也一般比较小,大部分产品的办理组件 pod 并没有特别的网络要求。也便是说,关于大部分产品,假如能够确保办理组件在任何环境中能正常拉起,那产品的运用是不成问题的,其他装备甚至能够在交给后的阶段增量进行,提高交给功率

进而咱们得出了定论:“咱们需求一个 overlay 和 underlay 网络能够一起存在的集群,其间 underlay 网络能否正常不影响 overlay 网络,underlay 网络能够增量装备,而且集群内 overlay 网络能和 underlay 网络不依靠根底设施互通”,这好像便是现在私有化场景 “On Anywhere” 布置的正确答案。

经过 CRD 装备办理集群网络

为了便于办理,咱们需求一个方法一致描绘 overlay、underlay 容器网络资源,考虑到 underlay 容器网络依靠是对底层根底设施敏感的,而且往往呈现出 “节点分组” 的现象(比方同一交换机下的节点能够运用相同网段),咱们提出了 “网络域” 的概念。

网络域中包含了一组具有相同网络性质(比方,处于相同 VLAN 环境、归于同一网关、归于相同二层网络)的节点,作为创立 ip 的底层资源。一个网络域具有这样的性质:“一个带有特定地址的 Pod 假如能被布置到网络域内的某一节点,那么带有相同地址的 Pod 应该能被调度到同一网络域内的其他任意节点”。对应了 Network CR 方针。在集群中能够经过 kubectl get network 命令检查,比方:

[root@iZf8z4x1svumpy31kcrltaZ ~]# kubectl get network init -oyaml
apiVersion: networking.alibaba.com/v1
kind: Network
metadata:
  annotations:
    meta.helm.sh/release-name: hybridnet
    meta.helm.sh/release-namespace: kube-system
  creationTimestamp: "2023-02-10T05:52:11Z"
  generation: 1
  labels:
    app.kubernetes.io/managed-by: Helm
    webhook.hybridnet.io/ignore: "true"
  name: init
  resourceVersion: "40647"
  uid: cc889b11-9ede-4711-93b3-910f0e59335e
spec:
  netID: 4
  type: Overlay
status:
  dualStackStatistics:
    available: 65526
    total: 0
    used: 0
  ipv6Statistics:
    available: 65534
    total: 65535
    used: 1
  lastAllocatedIPv6Subnet: init-2
  lastAllocatedSubnet: init
  nodeList:
  - izf8z4x1svumpy31kcrltaz
  - izf8zatm3b8zaaks5gqk0tz
  statistics:
    available: 65526
    total: 65534
    used: 8
  subnetList:
  - init
  - init-2

Network 方针经过 nodeSelector 挑选带有特定 label 的节点作为网络域中的节点,凭借网络域的概念,咱们完结了依靠特定网络资源 pod 的主动调度。

前面咱们提到,overlay 网络是不依靠底层网络资源的,所以创立 overlay 的 Network 方针时,nodeSelector 一定只能为空,而且每个集群只能创立一个 overlay 的网络域,这网络域对应了集群内的一切节点

经过 “网络域” 概念处理了 “根据网络资源的可用节点规划对 pod 进行主动化调度” 问题之后,咱们还需求引进一个 Subnet 方针描绘 ip 地址分配信息。

Subnet 方针是依附于 Network 方针的,每个 Subnet 有必要且只能归于一个 Network,同一个 Network 中能够有多个 Subnet。每个 Subnet 方针描绘了该网络域内一个可用的容器网段的地址信息,比方:

[root@iZf8z4x1svumpy31kcrltaZ ~]# kubectl get subnet init -oyaml
apiVersion: networking.alibaba.com/v1
kind: Subnet
metadata:
  annotations:
    meta.helm.sh/release-name: hybridnet
    meta.helm.sh/release-namespace: kube-system
  creationTimestamp: "2023-02-10T05:52:11Z"
  generation: 1
  labels:
    app.kubernetes.io/managed-by: Helm
    webhook.hybridnet.io/ignore: "true"
  name: init
  resourceVersion: "40646"
  uid: ca73b837-b28f-4727-949d-d06f152202ed
spec:
  config:
    autoNatOutgoing: true
  network: init
  range:
    cidr: 172.24.0.0/16
    version: "4"
status:
  available: 65526
  lastAllocatedIP: 172.24.0.23
  total: 65534
  used: 8

每个 hybridnet 集群要正常作业,至少需求存在一个 Network 和 Subnet。能够说 Network 和 Subnet 方针便是 hybridnet 对用户供给的装备进口。关于每个 pod 的 ip,hybridnet 会主动创立一个 IPInstance 方针,该 CRD 是namespace scope 的,与 pod 处于相同 namespace。IPInstance 方针首要的功用是用来持久化 hybridnet 地址分配信息,当然也能够用来供给给用户查询和审计,关于用户来讲,一般是只读的。

根据战略路由的 overlay/underlay 混合数据链路

战略路由

Linux 内核的路由才能其实十分强壮,绝大部分场景下咱们只用到了其间的一小部分,比方在一台 Linux 机器上运行 ip route 命令,咱们会得到下面的输出:

[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route
default via 172.16.255.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.0.0/16 dev eth0 proto kernel scope link src 172.16.69.139

这便是咱们所经常看见的 “路由表”,但这其实仅仅内核的其间一张名字叫做 “main” 的路由表,也是一般状况下,咱们 “增加路由”、“删除路由” 的操作方针。

Linux 内核从 2.2 版别开始就支撑了战略路由(Policy Route)才能,经过履行 ip rule 命令咱们能够看到战略路由规矩,默许状况下 Linux 操作系统中默许会存在 “local”、“main”、“default” 三张路由表,其间最前面的数字代表了优先级,数字越小,优先级越高,优先级从高到低第一张能够匹配流量的路由表会生效:

[root@iZf8z4x1svumpy31kcrltaZ ~]# ip rule
0:  from all lookup local
32766:  from all lookup main
32767:  from all lookup default

其间 “default” 一般为空,“local” 表中比较要害的是存在了带有 local 要害字的路由条目,对应了每个节点的本地 ip 地址,表示发送到本机的哪些流量应该不进行转发直接进入上层协议栈处理:

[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table default
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 172.16.0.0 dev eth0 proto kernel scope link src 172.16.69.139
local 172.16.69.139 dev eth0 proto kernel scope host src 172.16.69.139
broadcast 172.16.255.255 dev eth0 proto kernel scope link src 172.16.69.139

数据链路概述

在一个 hybridnet 集群内,流量的行为整体描绘如下:

  1. 同一节点上的 pod 之间通讯的流量只在节点内部转发

  2. overlay pod 与其他 pod (包含 underlay pod)相互拜访的流量都是地道流量

  3. underlay pod 拜访非 overlay pod 的流量(包含节点、集群外 ip 地址)为非地道流量

  4. 集群内节点拜访 overlay pod 的流量为地道流量(不经过 NAT)

  5. overlay pod 拜访集群内节点以及集群外部 ip 的流量为 NAT 流量(SNAT 成对应节点 ip)

数据链路彻底根据战略路由完结,这让 hybridnet 跟 kube-proxy、felix 的 iptables/ipvs 规矩以及其他相似的 service/networkpolicy 完结能够良好地适配,其流量路径如图:

CNStack 网络插件:hybridnet 的设计与实现

在一个只要 overlay 网段的环境(这儿有两个网段,咱们以为环境中只要 ipv4 的 172.24.0.0/16,ipv6 的战略路由要运用 ip -6 rule 检查,逻辑相同),能够看到节点战略路由规矩如下:

[root@iZf8z4x1svumpy31kcrltaZ ~]# kubectl get subnet
NAME     VERSION   CIDR                                          START   END   GATEWAY   TOTAL   USED   AVAILABLE   NETID   NETWORK
init     4         172.24.0.0/16                                                         65534   8      65526               init
init-2   6         5408:4003:10bb:6a01:83b9:6360:c66d:0000/112                           65535   1      65534               init
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip rule
0:  from all lookup local
1:  from all lookup 39999
2:  from all lookup 40000
3:  from all fwmark 0x20/0x20 lookup 40001
4:  from 172.24.0.0/16 fwmark 0x0/0x4040 lookup 10000
32766:  from all lookup main
32767:  from all lookup default
[root@iZf8z4x1svumpy31kcrltaZ ~]#

咱们能够看到 hybridnet 在战略路由中增加了四条规矩,分别对应了 39999、40000、40001、10000 的路由表,表中的路由条目分别如下:

[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 39999
172.24.0.1 dev hybr6b3adcd7e1e
172.24.0.4 dev hybr1b7a9ed1883
172.24.0.7 dev hybr6809d4b1e0e
172.24.0.9 dev hybr56df5339e20
172.24.0.11 dev hybr3c237dc2041
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 40000
172.24.0.0/16 dev eth0.vxlan4
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 40001
default dev eth0.vxlan4
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 10000
[root@iZf8z4x1svumpy31kcrltaZ ~]#

用最少的战略路由规矩数量,咱们完结了 hybridnet 的数据链路:

  • 关于 39999 路由表中的每个条目,其方针网段为本节点上 pod 的 ip 地址、出口设备为 pod 对应的 veth 设备。这个路由表的会处理一切方针地址为本机上 Pod 的流量,将其直接发送给本机 pod 的 netns 处理。咱们能够看到 39999 表的优先级是最高的

  • 关于 40000 路由表中的每个条目,其方针网段为集群内的 overlay 网段、出口设备为 vxlan 设备。这个路由表处理了一切方针地址为 overlay 容器网段的流量,确保一切发往 overlay pod 的流量会经过 vxlan 设备进行地道封装(这儿没有装备nexthop,表示下一跳 ip 就为数据包的方针 ip)

  • 40001 路由表中现在只要一条 default 路由,它的作用是让 “其他节点拜访本节点上 overlay pod” 的反向流量经过 overlay 设备,到达 “集群内节点拜访 overlay pod 的流量为地道流量(不经过 NAT)” 的作用

  • 10000 路由表其实比较特别,咱们能够看到它对应的战略路由规矩是 from 172.24.0.0/16 fwmark 0x0/0x4040 lookup 10000,以这条规矩为例,它表示 “只要源 ip 在 172.24.0.0/16 网段中而且没有相关 mark 的流量才会进入 10000 表处理”。关于集群内每个容器网段都会有这样一条战略路由规矩,对应路由表中的条目描绘了 “从本节点上对应该容器网段 pod 中宣布的流量” 应该怎么处理,不同网络形式的网段会有不同的规矩:

    • 关于 overlay 的网段(overlay 只要 vxlan [ 1] 形式),路由表内每个路由条目代表发送到某个 underlay 网段的流量。比方咱们在集群内经过**增量进行 underlay 网络装备 [ 2] **,增加了两个192.168.56.0/24和192.168.57.0/24的 Subnet(以及对应的 Network),一个为 vlan [ 3] 形式,一个为 bgp [4 ] 形式,10000 路由表会变成这样(由于192.168.56.1是 vlan 网段的网关,用 throw 类型的条目忽略):
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 10000
192.168.56.0/24 dev eth0.vxlan4
throw 192.168.56.1
192.168.57.0/24 dev eth0.vxlan4
    • 关于 vlan 形式的网段,路由表的内容是固定的,一条方针地址为本网段 CIDR 的直接路由,一条下一跳为网段网关 ip (对应 Subnet 方针的spec.range.gateway 字段)的默许路由,方针是让同网段的流量直接走物理网卡发送出去,跨网段的流量走外部网关路由进行转发,在对应 vlan 网络域中的节点上检查路由规矩:
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip rule
0:  from all lookup local
1:  from all lookup 39999
2:  from all lookup 40000
3:  from all fwmark 0x20/0x20 lookup 40001
4:  from 172.24.0.0/16 fwmark 0x0/0x4040 lookup 10000
5:  from 192.168.56.0/24 fwmark 0x0/0x4040 lookup 10001
32766:  from all lookup main
32767:  from all lookup default
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]#
[root@iZf8z4x1svumpy31kcrltaZ ~]# ip route show table 10001
default via 192.168.56.1 dev eth0
192.168.56.0/24 dev eth0 scope link
[root@iZf8z4x1svumpy31kcrltaZ ~]#
    • 关于 bgp 形式的网段,路由表的内容是固定的,一条下一跳为 BGP 网关 ip (对应 Network 方针的spec.config.bgpPeers[0].address字段,这个地址需求是当时节点路由可达的)的默许路由,方针是让一切流量走外部网关路由进行转发,在对应 bgp 网络域中的节点上检查路由规矩:
[root@iZf8zatm3b8zaaks5gqk0tZ ~]# ip rule
0:  from all lookup local
1:  from all lookup 39999
2:  from all lookup 40000
3:  from all fwmark 0x20/0x20 lookup 40001
4:  from 172.24.0.0/16 fwmark 0x0/0x4040 lookup 10000
5:  from 192.168.57.0/24 fwmark 0x0/0x4040 lookup 10001
32766:  from all lookup main
32767:  from all lookup default
[root@iZf8zatm3b8zaaks5gqk0tZ ~]# ip route show table 10001
default via 172.16.255.253 dev eth0
[root@iZf8zatm3b8zaaks5gqk0tZ ~]#

链路完结细节

怎么让宿主机成为路由器

要运用战略路由构建容器网络,咱们需求宿主机来 “路由” 节点上一切 pod 的流量,也便是成为本节点一切 pod 的路由器。这一点其实和 calico 是相同的,咱们沿用了相同的规划。

进入 pod 能够看到,pod netns 内部(main 表)只存在一条 default 路由条目,而且该路由条目的下一条 ip 为一个固定的不存在的 ip 地址(hybridnet 运用的是和 calico 相同的 169.254.1.1、fe80::ecee:eeff:feee:eeee);在 pod netns 外部,host 侧会在 pod 对应的 veth 设备上装备 proxy_arp/proxy_ndp,确保一切从 pod 中宣布的、“下一跳地址为上述不存在地址”的流量都能被 host netns 处理。

虚拟大二层的 vxlan 网络

关于 calico、flannel 而言,“节点绑定网段” 是容器网络 ip 分配的根本模型。在 hybridnet 中,由于存在 “固定ip” 的诉求,假如节点固定某一个或许某几个容器网段的话,固定了 ip 的 pod 也会被迫与节点生命周期绑定,极大地影响了 pod 的可用性。咱们希望每个 overlay 网段都是整个集群节点规划内可用的,固定了 ip 的 pod 能够漂移到集群的其他节点上,一起也具备愈加简略灵活的 ip 扩容才能(不需求考虑节点上容器网段巨细)。

在 overlay 的计划上(只要 vxlan 形式),咱们参阅了 flannel 的完结。迥然不同,关于怎么运用 linux 内核的 vxlan 虚拟设备进行组网,需求考虑两个问题:

  1. 咱们需求 vxlan 设备能够像 “外接了交换机的物理网卡” 相同作业,也便是说,数据包在由 vxlan 设备宣布时,vxlan 设备需求能够处理该数据包的方针 mac 地址,这部分装备是需求咱们去组织 vxlan 设备 fdb 表的,它决议了 “哪个 mac 要发往哪个 VTEP ip”

  2. 当 vxlan 设备变成一张可用网卡后,咱们需求装备这张网卡相关的路由表,而且在跟 vxlan 设备相关的条目中需求给出一个可用的(能够被街坊解析的)下一跳 ip,让流量能够被正确从 vxlan 设备宣布

在 flannel 前史上,存在三个版别的数据链路完结(能够在 flannel 代码**注释 [ 5] **里看到):

  1. 第一个版别,flannel 会在用户态监听 vxlan 设备的 L2/L3 miss 事情,这首要指两个阶段:

    1. 当容器数据包在完结路由查询后要从 vxlan 设备宣布之前,需求根据路由表的下一跳 ip 进行街坊解析,以填充容器数据包的方针 mac 地址。由于此刻没有对应的街坊缓存,这会宣布一个 L2 miss 事情,flannel 用户态进程在监听到 L2 miss 事情之后会经过预先在 etcd 中记载的信息返回成果,供给对应该下一跳 ip 的正确 mac 地址
    2. 当容器数据包被填充完毕后,会进入 vxlan 设备内部的发送逻辑。此刻 vxlan 设备需求知道对应容器数据包 mac 地址的 VTEP 网关 ip 是什么,以构造对应的 udp 数据包,这个时分会发生一个 L3 miss 事情,flannel 用户态进程在监听到之后会经过预先在 etcd 中记载的信息返回成果,供给对应容器网段 ip 地点节点上的宿主机 ip 地址
  2. 第二个版别,flannel 移除了 L3 miss 事情的用户态处理。由于宿主机被加入集群之后 ip 根本不会再发生变化,所以 flannel 会在发现节点的时分,直接更新每个节点上的 vxlan fdb 表项,将宿主机的 ip 地址写入。

  3. 第三个版别也便是现在的版别,为了提高 flannel 的可靠性(假如数据链路依靠用户态进程,在 flannel 更新或许暂时 Crash 的时分,节点上的容器网络通讯会断开,也便是数据链路连通性和办理组件生命周期是紧耦合的),flannel 移除了 L2 miss 事情的用户态处理,采用“发现节点之后直接为节点分配网段”的方法,为每个节点增加一条静态街坊缓存,而且为每个其他节点上的网段增加一条固定的路由规矩

经过学习 flannel 的前史,不难发现,关于 “vxlan 设备上街坊解析进程”(L2 miss 事情)的处理,是能否去掉 “节点绑定网段” 限制的要害。根据这一点,hybridnet 做出了和 flannel 不同的挑选,咱们在坚持数据链路连通性与组件生命周期松耦合的一起,完结了 “容器网段跨节点” 的 ip 分配模型。

在 hybridnet 中,vxlan 网络的装备具有以下特色:

  1. 出口设备为 vxlan 设备的路由都是没有指定 “下一跳” 的,也便是当数据包从 vxlan 设备上宣布时,街坊解析的方针 ip 与数据包的方针 ip 一致

  2. 每个节点上,hybridnet 会为本节点上的一切 pod ip 装备 vxlan 设备上的proxy类型街坊缓存条目,这意味着宿主时机主动处理从 vxlan 设备上收到的街坊恳求,而且将 vxlan 设备的 mac 地址作为成果响应,这样,一切的 pod 之间经过 vxlan 网络通讯实际上运用的是 pod 地点节点的 vxlan 设备 mac 地址

  3. hybridnet 会在 vxlan 设备中为每个节点的 VTEP ip 装备 00:00:00:00:00:00 dev dst self permanent的 fdb 条目,这种方针 mac 全零的条目的 VTEP ip 形成了一个组,当数据包的方针 mac 地址没有匹配到任何 fdb 条目时,内核会将数据包封装成 udp 地道包而且分别拷贝一份发向该组中一切 VTEP ip

  4. hybridnet 会在 vxlan 设备中为每个节点的 VTEP ip 和 VTEP mac(节点 vxlan 设备的 mac 地址)装备 dev dst self permanent的 fdb 条目,当数据包的方针 mac 地址匹配到 VTEP mac 时,内核会将数据包封装成 udp 地道包发向对应 VTEP ip

  5. hybridnet 会有用户态进程监听 vxlan 设备的 L2 miss 事情,当呈现这种事情时,hybridnet 会查询 IPInstance 方针以及节点信息(经过 k8s informer 的本地缓存,一般比较快),假如查询到了,会直接返回对应街坊解析的成果,跳过内核态街坊解析的广播报文发送进程

整体来讲,由于 pod 经过 vxlan 网络通讯的 mac 地址都是其地点节点的 vxlan 设备 mac 地址,所以 vxlan 设备的 fdb 表规划是可控的,经过 “每个节点的 VTEP ip 和 VTEP mac(节点 vxlan 设备的 mac 地址)fdb 表装备”,一切单播的报文都能够被正常处理。关于或许发送广播报文的街坊解析恳求,咱们运用 “手动维护广播组” 和 “用户态监听 L2 miss 代理街坊解析” 的方法,前者会确保组件反常时不影响网络通讯,后者会在组件正常作业时降低甚至消除由于广播发生的流量开销。

更多关于怎么装备 vxlan 网络能够检查 wiki 中 “vxlan 网络” 部分。

路由完结的 vlan 网络

关于 vlan 形式的网络,hybridnet 首要逻辑为:

  1. 为netID不为 0 的网段,创立 vlan 虚拟设备;假如netID为 0,直接运用宿主机网卡自身进行通讯

  2. 在容器网络流量出口设备(如上面所说,或许是 vlan 虚拟设备也或许不是)上为节点上一切 vlan 形式的 pod ip 创立proxy类型街坊缓存

结合 “数据链路概述” 中描绘的 vlan 网段路由规矩,大致整理规矩之后咱们会发现,此刻理论上网络现已能通了,外部流量看起来会和二层桥接的流量一致,容器会运用宿主机网卡的 mac 地址进行通讯。可是其实仍然存在问题,问题首要在于内核发送 arp 恳求的 sender ip 挑选进程。

在咱们的规划中,当 vlan 的 pod 要对外进行通讯时,pod 关于同网段或许网关地址的 arp 恳求永远是由宿主机宣布的,又由于 underlay 网络的 ip 地址比较名贵,咱们不希望浪费地址在节点上,所以并没有为节点分配任何容器网段的地址(overlay 网络也是相同);这就造成了,宿主机在替 pod 发送 arp 恳求时只能将自己的 ip 填充到恳求的 sender ip 字段。关于某些交换机,这类流量是不合法的,由于看起来是 “跨网段的街坊解析恳求”。

经过查询相关内核逻辑咱们发现,在这种状况,内核决议 arp 恳求 sender ip 时的逻辑首要为 “优先挑选网卡上第一个跟 target ip 在同一网段,而且 scope 为link或许global的地址”,一起又由于需求避免 scope 为global的地址或许被内核子系统 “源地址挑选” 进程选中,所以咱们需求的是一个同网段中,scope 为link的 ip 地址。

为了处理这个问题,咱们引进了 “enhanced address” 装备。大致思路是,关于节点地点 vlan 网络域中的一切网段,当出口设备没有容器网段对应的 ip 地址时,随机挑选本节点上一个 pod ip 地址装备到出口设备上,这个地址的装备有以下特色:

  1. 开启了noprefixroute的 flag
  2. 地址的 scope 是link的
  3. 删除了 local 路由表中对应该地址主动生成的 local 路由条目

经过这样的装备,咱们成功地让宿主机上的一切 “enhanced address” 只为 arp 解析进程服务,不影响其他进程。

更多关于怎么装备 vlan 网络能够检查 wiki 中 “vlan 网络” 部分。

支撑固定 ip 的 bgp 网络

经过前面的规矩描绘咱们能够发现,在 hybridnet 中关于 bgp 形式的数据链路规划十分简略:“一直经过外部网关交换机”。比较复杂的部分在于 bgp 协议的办理。具体规划能够参阅 wiki 中 “bgp 网络” 部分。

CNStack 怎么运用 hybridnet

CNStack 经过 hybridnet 完结了 “On Anywhere” 布置。

在创立集群时,CNStack 集群会初始化 overlay 网络资源的创立,而且一直运用 overlay 作为默许网络类型,绝大部分集群内的 pod 会经过 overlay 网络拉起,包含 CNStack 渠道的办理 pod,这样就确保了 CNStack 的白屏渠道办理逻辑能够在任意网络环境的正确作业。

一起,CNStack 中集成了对 hybridnet 网络装备的白屏办理才能,用户能够在 CNStack 渠道完结交给后,在白屏控制台上自助增加 underlay 网络装备,而且经过在发布 pod 时带上固定 annotation 的方法运用 underlay 网络资源(由于集群默许网络类型是 overlay 的,运用 underlay 网络需求特别指定)。

经过这样的方法,传统含义上在交给 underlay K8s 集群之前需求完结的网络规划、装备作业变成了与交给进程解藕的、用户可选自助装备的逻辑,而且 underlay 的装备并不影响产品的可用性和安稳性,极大地提高了交给功率。

相关链接:

[1]vxlan

github.com/alibaba/hyb…

[2]增量进行 underlay 网络装备

github.com/alibaba/hyb…

[3]vlan

github.com/alibaba/hyb…

[4]bgp

github.com/alibaba/hyb…

[5]注释

github.com/flannel-io/…

参阅链接:

hybridnet github 库房

github.com/alibaba/hyb…

hybridnet 开源 wiki

github.com/alibaba/hyb…

与容器服务 ACK 发行版的深度对话第二弹:怎么凭借 hybridnet 构建混合云一致网络平面

mp.weixin.qq.com/s/O095yS5xP…

阿里云 CNStack 产品

www.aliyun.com/product/ali…

CNStack 社区版

github.com/alibaba/CNS…

阿里云 ACK 发型版

github.com/AliyunConta…