vpc 全局路由模式是 tke 默认网络方案。该模式依托于 vpc 底层路由能力,不需要在节点上配置 vxlan 等 overlay 设备,就可以实现容器网络 和 vpc 网络的互访,并且相比于 calico/flannel 等网络方案,因为没有额外的解封包,性能也会更好。
术语
vpc:私有网络,用户自定义的逻辑网络空间,例如(10.0.0.0/16)。
region:地域,物理概念。例如(北京,上海,广州),vpc 归属于一个地域。
subnet:子网,位于 vpc ip cidr 内的 ip cidr,例如(10.0.0.0/24),云资源中的 ip 都是从子网中分配。
zone:可用区,物理概念。例如(北京一区,北京二区),一个地域下的物理数据中心,subnet 归属于一个可用区。
容器网络:用户自定义用于容器的逻辑网络空间,例如(172.16.0.0/16)。vpc 全局路由模式下,容器网络和 vpc 中的 ip 不能重叠,容器网络关联于一个 vpc。
Global Route:即本文提到的 vpc 全局路由。实现容器网络和 vpc 网络互访的路由策略。
节点:Kubernetes 集群节点,本文指腾讯云主机。
tke-bridge-agent:daemonset,Kuberenetes 概念,运行在各个节点上,负责生成下发 cni 配置到节点。
容器网络和 vpc 网络互访原理
vpc 全局路由模式下 pod 互访数据链路,包括节点在不同母机,同一母机的场景
节点跨母机

vpc cidr 为 10.0.0.0/16,id 为 100
容器网络为 192.168.0.0/16
node1 部署在母机1,pod1 部署在 node1,node2 部署在母机2,pod2 部署在 node2
- pod1 主动访问 pod2,数据包会经由默认路由转发到 node1 cbr0。
- node1 cbr0 收到数据包后会经由节点默认路由转发给 eth0。
- 母机1 br-100 收到数据包后,查询全局路由表项,匹配到表项2,依据 RemoteIP 封装 gre 头,并将节点IP填入 gre option,经由 eth1 发出。
- 母机2 eth1 收到 gre 报文后,转给 gre_100,gre_100 解封gre 头,并从 gre option 获取节点IP,然后将数据包转给节点2 eth0。
- 节点2 收到数据包后转发给 cbr0,cbr0 转发给veth1。
- pod2 eth0 收到数据包后,处理,回包。
- 回包链路和发包链路对称。
节点不跨母机
和节点跨母机 pod 互访数据链路相同,经由母机 eth1 发出后,又由 eth1 收到,解封 gre 报文,转发给 br,最终转发给 pod
容器网络管理
vpc 全局路由模式下容器网络的管理,包含节点网段分配,vpc 全局路由创建和 pod ip 分配
节点网段分配
创建集群时,用户需要指定容器网络(clusterCidr),每个节点能运行的 pod 最大数目以及 service 数目。
为了便于管理,我们会从 clusterCidr 中分配 serviceCidr 用于 service 用途,为每个节点分配一个 podCidr 用于节点上 pod ip 的分配。
serviceCidr 大小取决于 service 数目。
podCidr 大小取决于每个节点上能运行的 pod 最大数目。
由上图可以看出 N 最大为 254,集群最大可以分配 255 个节点。
节点 podCidr 的分配是 kube-controller-manager 做的,当参数 —allocate-node-cidrs 设置为 true 时,nodeIpamController 会尝试为每一个节点分配一个 podCidr,并更新到节点 .spec.podCIDR 字段。
kube-controller-manager 参数 —allocate-node-cidrs 和 configure-cloud-routes 都设置为 true 时,routeController 会 list-watch 节点,根据节点 .spec.podCIDR 字段,调用 cloud-provider 路由接口,cloud-provider 路由接口会调用 tke 云 Api 完成 vpc 全局路由的查询/创建删除。
路由成功创建后,routeController 会更新节点 Condition,依据此 Condition 可以快速判断 vpc 全局路由是否成功创建。
$ kubectl describe no 10.0.0.1
Name: 10.0.0.1
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
—— ——— ————————- ————————— ——— ———-
NetworkUnavailable False Fri, 05 Jul 2019 20:30:18 +0800 Fri, 05 Jul 2019 20:30:18 +0800 RouteCreated RouteController created a route
pod ip 分配
前面已经介绍怎么给节点分配 podCidr 以及怎么让该 podCidr 在 vpc 内是可以路由的,下面具体讲一个节点上 pod 的 ip 是怎么分配的。
首先 tke-bridge-agent 会 List-Watch 本节点,获取分配给本节点的 podCidr,然后生成并下发 cni 配置文件(tke-bridge.conf)到节点指定目录。
$ cat /etc/cni/net.d/multus/tke-bridge.conf
{“cniVersion”:”0.1.0”, “name”:”tke-bridge”, “type”:”bridge”, “bridge”:”cbr0”, “mtu”:1500, “addIf”:”eth0”, “isGateway”: true, “forceAddress”: true, “ipMasq”: false, “hairpinMode”: false, “promiscMode”: true, “ipam”:{“type”:”host-local”, “subnet”:”192.168.0.0/24”, “gateway”:”192.168.0.1”, “routes”:[{“dst”:”0.0.0.0/0”}]}}
参考文献
【vpc 介绍】: https://cloud.tencent.com/document/product/215/20046
【地域和可用区介绍】:https://cloud.tencent.com/document/product/215/20057
