前言
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架構示意圖
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: 該字段與Kube.NETes節點的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: <LOOPBACK,UP,LOWER_UP> 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: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if532: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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
<switch>
全棧云探索實踐
綜合考慮微隔離、網路可觀測等技術儲備已在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 BGP模式相關思考
建設方面:Calico BGP建設需要多團隊的配合。管理物理網絡設備的團隊,需全局規劃網絡設備的BGP信息、AS號和靜態路由等,技術上避免單臺交換機宕機引起路由的震蕩(如一對Leaf交換機擁有不同AS號,會造成路由震蕩);管理云平臺的團隊,需要合理配置iBGP和IPPool,避免發布非法路由,影響其他網絡設備。
運維方面:變更管理/故障管理需云和網配合進行,明確雙方分工和問題界定,緊密協作。比如管理云平臺的團隊配置BGP Filter功能,物理網絡設備配置BGP Policy,防止對外發布非法路由,形成雙保險。在技術探索過程中,引入可觀測平臺全鏈路流量和BGP監控等工具,最大程度將問題邊界描述清晰,并提高運維效率。
后續細化Calico BGP監控指標,探索Calico eBPF數據面的實現,弱化iptables對網絡的影響。