Calico BGP容器网络实践

2023年 11月 28日 60.3k 0

前言

G行全栈云容器大规模运行在信创服务器的虚拟机里,发现如跨NUMA访问CPU可能导致性能不均衡、容器网络和IaaS SDN耦合、虚拟层本身资源消耗等诸多问题。为解决这些问题,G行探索将容器运行在裸金属服务器上,推出裸金属容器平台方案,使用纯三层网络设计,其中东西向网络流量使用开源Calico容器组件,南北向网络流量使用自研ELB。本文主要介绍Calico BGP相关技术原理、实践和思考。

BGP介绍

BGP(Border Gateway Protocol,边界网关协议)为取代外部网关协议(EGP)协议而创建,属于经典网络路由协议。BGP相关的开源项目有bird、goBGP 等,开源软件运行在云平台的宿主主机上,使主机与网络设备交换路由信息,实现云上网络和云下网络的通信。

关键概念:

  • AS(Autonomous System): 一个自治系统是受控于一家组织机构的路由器集合。在企业内部AS号是统一管理的,根据网络设备的AS号异同,可分为IBGP和EBGP。
  • IBGP(Internal BGP):在相同AS路由器之间建立会话,一般认为IBGP运行在安全的网络环境。特点是IBGP的路由信息只能传一跳,不会传递给其他IBGP路由节点。否则,需要开启Router Reflect特性。
  • EBPG(External BGP):在不同AS路由器之间建立会话。特点是EBGP路由器之间会同步彼此的路由。?

图一 网络架构图一 网络架构

在典型Spine-Leaf架构下,Spine与Leaf之间运行EBGP协议,Leaf与裸金属服务器之间运行IBGP协议。

Calico网络

Calico是基于CNI实现的纯三层网络开源项目,首个版本在2015年发布,截止当前版本为Calico 3.26.1。该项目已被业界广泛接受,并拥有许多大规模的实际案例。

图二 Calico架构示意图图二 Calico架构示意图

1. Calico关键组件

  • Felix

Felix负责管理容器网络,配置容器IP地址、路由、iptables、安全策略等功能。在每个Worker节点运行代理程序,负责与容器管理平面通信,获取并配置网络和安全策略。

  • Confd

监控Calico相关数据(BGP配置、IPAM配置等),动态生成Bird配置文件,并使Brid重新加载配置文件。

  • Brid

发布路由:从Felix获取路由,并把路由分发给BGP邻居,外部流量通过该路由找到POD所在Worker节点。

路由反射 (Route Reflector): 收到IBGP邻居发布的BGP路由,并反射路由给其他IBGP邻居。

路由过滤:物理网络设备的所有路由表项会同步到本机,配置路由过滤,可以大量减少本机的路由条目。

  • Typha

Flex通过Tyhpa直接跟Etcd交互,不再经过容器管理平面,在百节点以上的规模,能够有效降低对容器管理平面的访问压力。

2. Calico组网模式

  •  IPIP模式

Calico默认网络架构,IPIP可理解为IPinIP,属于overlay的网络架构。不依赖于外部交换机设备,即可实现网络组网。缺点是报文的封装和解封装对网络效率有影响,节点规模有限制。

  •  BGP模式

Calico最佳实践推荐该模式,计算节点与网络设备建立BGP邻居,并对外宣告POD的路由信息,网络设备学习到路由信息后,外部用户就可通过路由直接访问POD的地址,期间不涉及到报文的封装,网络效率非常高。在合理的网络架构设计下,节点规模灵活扩展且不影响网络效率。缺点是一般硬件网络设备和云平台的计算节点是由不同团队管理,遇到网络故障时需联合处置。

3. IPAM地址管理?

?Calico通过IPPool进行IPAM管理,IPPool定义了地址池名字、地址段、blockSize等字段。IPPool的配置样例如下:

apiVersion:crd.projectcalico.org/v1

kind: IPPool

metadata:

  name: ippool-test-0

spec:

  blockSize: 32

  cidr: 1.1.1.0/24

  ipipMode: Never

  natOutgoing: false

  nodeSelector: “!all()”

  vxlanMode: Never

nodeSelector: 该字段与Kubernetes节点的Label进行映射。默认为all(),表示所有节点均可使用。设置为!all(),表示所有node均不可自动使用,可通过设置命名空间或者POD的注解,实现IPPool的绑定。

block/blockSzie: block主要功能是路由聚合,减少对外宣告路由条目。block在POD所在节点自动创建,如在worker01节点创建1.1.1.1的POD时,blocksize为29,则该节点自动创建1.1.1.0/29的block,对外宣告1.1.1.0/29的BGP路由,并且节点下发1.1.1.0/29的黑洞路由和1.1.1.1/32的明细路由。在IBGP模式下,黑洞路由可避免环路。如果blockSize设置为32,则不下发黑洞路由也不会造成环路,缺点是路由没有聚合,路由表项会比较多,需要考虑交换机路由器的容量。

Calico创建block时,会出现借用IP的情况。如在 worker01节点存在1.1.1.0/29的block,由于worker01节点负载很高,地址为1.1.1.2的POD被调度到worker02节点,这种现象为IP借用。woker02节点会对外宣告1.1.1.2/32的明细路由,在IBGP模式下,交换机需要开启RR模式,将路由反射给worker01上,否则在不同worker节点的同一个block的POD,由于黑洞路由的存在,导致POD之间网络不通。可通过ipamconfigs来管理是否允许借用IP(strictAffinity)、每个节点上最多允许创建block的数量(maxBlocksPerHost)等。

4 BGP模式下路由分析

举例说明,创建1.1.1.0/31的地址池,IPPool配置如下:

root@master1:~# calicoctl get ippool ippool-test-0

NAME            CIDR             SELECTOR

ippool-test-0   1.1.1.0/31       all()

使用该地址池,创建一个名字为nettool的POD,创建完成后,查看workloadendpoint资源信息。可查看得到,POD的IP地址为1.1.1.1/32,其网络接口对应在worker01节点的网卡为cali200f7a51a47。

root@master1:~# calicoctl get workloadendpoint

NAMESPACE   WORKLOAD   NODE        NETWORKS         INTERFACE

default     nettool    worker01    1.1.1.1/32       cali200f7a51a47

进入该容器,查看路由和接口信息。可查看得到,容器默认路由为169.254.1.1,且均指向eth0。通过ethtool查看得到,eth0接口的peer_ifindex为532。

root@master1:~# kubectl exec -it nettool sh

kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

sh-4.4# ip a

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

2: tunl0@NONE:  mtu 1480 qdisc noop state DOWN group default qlen 1000

    link/ipip 0.0.0.0 brd 0.0.0.0

4: eth0@if532:  mtu 1480 qdisc noqueue state UP group default

    link/ether 86:61:23:4e:4e:d0 brd ff:ff:ff:ff:ff:ff link-netnsid 0

    inet 1.1.1.1/32 scope global eth0

       valid_lft forever preferred_lft forever

sh-4.4# ip route

default via 169.254.1.1 dev eth0

169.254.1.1 dev eth0 scope link

sh-4.4# ethtool -S eth0

NIC statistics:

     peer_ifindex: 532

     rx_queue_0_xdp_packets: 0

     rx_queue_0_xdp_bytes: 0

     rx_queue_0_xdp_drops: 0

登录worker01节点,查看index为532的网卡接口,正是该接口cali200f7a51a47。worker01节点已经配置了ARP代理(主机上网卡不管ARP请求的内容,直接将自己的Mac地址作为应答的行为称为ARP Proxy)。Calico把worker01节点当做容器的默认网关使用,所有报文会发送到节点上,节点再根据路由信息进行转发。

root@worker01:~# ip a |grep 532

532: cali200f7a51a47@if4:  mtu 1480 qdisc noqueue state UP group default

root@worker01:~# cat /proc/sys/net/ipv4/conf/cali200f7a51a47/proxy_arp

1

针对回程报文,我们查看节点的1.1.1.1对应路由,也正是该接口cali200f7a51a47。此时worker01节点的收发报文通路已经明了。

root@worker01:~# route -n |grep cali200f7a51a47

1.1.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 cali200f7a51a47

最后,确认下交换机的路由情况。目的地址为1.1.1.1的下一跳为192.168.1.4,该IP地址是worker01主机IP。此时POD就可以跟外部进行通信。

Destination/Mask        Proto   Pre     Cost    Flags   NextHop         Interface

1.1.1.1/32              IBGP    255     0       RD      192.168.1.4     vlanif100

全栈云探索实践

综合考虑微隔离、网路可观测等技术储备已在G行推广使用,Calico默认不开启网络安全策略,依靠微隔离做网络安全管控。主要考虑BGP和IPAM上设计和管理网络。

1.BGP配置

1) 创建BGPconfigurations配置文件,声明节点的默认AS号。

root@master1:~# cat bgpconfigurations.yaml

apiVersion: crd.projectcalico.org/v1

kind: BGPConfiguration

metadata:

  name: default

spec:

  asNumber: 1111111

  logSeverityScreen: Info

  nodeToNodeMeshEnabled: false

2) 创建BGPPeer,明确交换机的AS号、BGP Peer IP,并将含有rr-group=rr1 的节点与交换机建立邻居。

root@master:~# cat bgppper1.yaml

apiVersion: crd.projectcalico.org/v1

kind: BGPPeer

metadata:

  name: bgp-peer-1

spec:

  asNumber: 1111111

  nodeSelector: rr-group == 'rr1'

  peerIP: 192.168.1.1

3) Kubernetes的节点打rr-group=rr1的标签

root@master1:~# kubectl get node --show-labels |grep rr1 |grep worker01

worker01   Ready    worker                 21d    v1.23.15   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker01,kubernetes.io/os=linux,node-role.kubernetes.io/worker=,rr-group=rr1

4) 交换机配置

  • BGP建立邻居
  •  BGP Policy,防止对外发布不可信路由

5) 裸金属Kubernetes节点查看BGP状态,Established意味着BGP邻居已经建立。

root@worker01:~# calicoctl node status

Calico process is running.

IPv4 BGP status

+--------------+---------------+-------+------------+-------------+

| PEER ADDRESS |   PEER TYPE   | STATE |   SINCE    |    INFO     |

+--------------+---------------+-------+------------+-------------+

| 192.168.1.1  | node specific | up    | 2023-08-17 | Established |

| 192.168.1.2  | node specific | up    | 2023-08-17 | Established |

+--------------+---------------+-------+------------+-------------+

IPv6 BGP status

No IPv6 peers found.

2. IPAM配置相关信息

G行云平台底座和业务的IP分开管理,业务自行决定POD的亲和或反亲和,业务部署在自己的命名空间,不会出现多种业务在同一个命名空间部署的情况。

在超过20个节点的容器平台,应用POD会频繁发生IP地址借用情况,block的路由聚合效率大幅度降低。综合考虑交换机性能和容量,地址池的blockSize设置为32,交换机不开启RR特性。

为确保IP不会被其他业务使用,设定所有地址池的nodeSelector为!all()。

root@master1:~# calicoctl get ippool                         

NAME                    CIDR                    SELECTOR

ippool-test-0           1.1.1.0/24              !all()

ippool-test-1           1.1.2.0/24              !all()

ippool-test-2           1.1.3.0/24              !all()

ippool-test-3           1.1.4.0/24              !all()

在namespace中设定对应annotation。

apiVersion: v1

kind: Namespace

metadata:

  annotations:

    cni.projectcalico.org/ipv4pools: '["ippool-test-0"]'

  name: test

3. Calico相关监控

Calico监控体系从三个方面进行覆盖。

  • Calico组件和功能的监控,包含IPPool监控、Felix、Typha等组件监控。
  • Calico网络边界的监控,主要是跟交换机的网络边界监控,网络流量通过可观测平台监控,网络控制面依赖于BGP报文的监控。
  • 容器平台网络固有的监控,跟采用哪种CNI插件无关。如Calico相关POD健康与否、业务POD网络状态、容器节点网络信息等。

图三 Calico监控体系图三 Calico监控体系

Calico BGP模式相关思考

建设方面:Calico BGP建设需要多团队的配合。管理物理网络设备的团队,需全局规划网络设备的BGP信息、AS号和静态路由等,技术上避免单台交换机宕机引起路由的震荡(如一对Leaf交换机拥有不同AS号,会造成路由震荡);管理云平台的团队,需要合理配置iBGP和IPPool,避免发布非法路由,影响其他网络设备。

运维方面:变更管理/故障管理需云和网配合进行,明确双方分工和问题界定,紧密协作。比如管理云平台的团队配置BGP Filter功能,物理网络设备配置BGP Policy,防止对外发布非法路由,形成双保险。在技术探索过程中,引入可观测平台全链路流量和BGP监控等工具,最大程度将问题边界描述清晰,并提高运维效率。

后续细化Calico BGP监控指标,探索Calico eBPF数据面的实现,弱化iptables对网络的影响。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论