Cilium Overview
Cilium 是一個基于 eBPF 和 XDP 的高性能容器網(wǎng)絡(luò)方案的開源項目救恨,目標(biāo)是為微服務(wù)環(huán)境提供網(wǎng)絡(luò)纵朋、負(fù)載均衡雷客、安全功能裙秋,主要定位是容器平臺容燕。
Why Cilium ?
現(xiàn)在應(yīng)用程序服務(wù)的發(fā)展已從單體結(jié)構(gòu)轉(zhuǎn)變?yōu)槲⒎?wù)架構(gòu)梁呈,微服務(wù)間的的通信通常使用輕量級的 http 協(xié)議。微服務(wù)應(yīng)用往往是經(jīng)常性更新變化的蘸秘,在持續(xù)交付體系中為了應(yīng)對負(fù)載的變化通常會橫向擴縮容官卡,應(yīng)用容器實例也會隨著應(yīng)用的更新而被創(chuàng)建或銷毀蝗茁。
這種高頻率的更新對微服務(wù)間的網(wǎng)絡(luò)可靠連接帶來了挑戰(zhàn):
傳統(tǒng)的 Linux 網(wǎng)絡(luò)安全連接方式是通過過濾器(例如 iptables )在 IP 地址及端口上進(jìn)行的,但是在微服務(wù)高頻更新的環(huán)境下寻咒,應(yīng)用容器實例的 IP 端口是會經(jīng)常變動评甜。在微服務(wù)應(yīng)用較多的場景下,由于這種頻繁的變動仔涩,成千上萬的 iptables 規(guī)則將會被頻繁的更新忍坷。
出于安全目的,協(xié)議端口(例如 HTTP 流量的 TCP 端口 80)不再用于區(qū)分應(yīng)用流量熔脂,因為該端口用于跨服務(wù)的各種消息佩研。
傳統(tǒng)系統(tǒng)主要使用 IP 地址作為標(biāo)識手段,在微服務(wù)頻繁更新的架構(gòu)中霞揉,某個 IP 地址可能只會存在短短的幾秒鐘旬薯,這將難以提供準(zhǔn)確的可視化追蹤痕跡。
Cilium 通過利用 BPF 具有能夠透明的注入網(wǎng)絡(luò)安全策略并實施的功能适秩,區(qū)別于傳統(tǒng)的 IP 地址標(biāo)識的方式绊序,Cilium 是基于 service / pod /container 標(biāo)識來實現(xiàn)的,并且可以在應(yīng)用層實現(xiàn) L7 Policy 網(wǎng)絡(luò)過濾秽荞≈韫總之,Cilium 通過解藕 IP 地址扬跋,不僅可以在高頻變化的微服務(wù)環(huán)境中應(yīng)用簡單的網(wǎng)絡(luò)安全策略阶捆,還能在支持 L3/L4 基礎(chǔ)上通過對 http 層進(jìn)行操作來提供更強大的網(wǎng)絡(luò)安全隔離。BPF 的使用使 Cilium 甚至可以在大規(guī)模環(huán)境中以高度可擴展的方式解決這些挑戰(zhàn)問題钦听。
Cilium 的主要功能特性:
支持 L3/L4/L7 安全策略洒试,這些策略按照使用方法又可以分為
基于身份的安全策略(Security identity)
基于 CIDR 的安全策略
基于標(biāo)簽的安全策略-
支持三層扁平網(wǎng)絡(luò)
Cilium 的一個簡單的扁平 3 層網(wǎng)絡(luò)具有跨多個群集的能力,可以連接所有應(yīng)用程序容器朴上。通過使用主機作用域分配器垒棋,可以簡化 IP 分配,這意味著每臺主機不需要相互協(xié)調(diào)就可以分配到 IP subnet痪宰。
Cilium 支持以下多節(jié)點的網(wǎng)絡(luò)模型:
Overlay 網(wǎng)絡(luò)叼架,當(dāng)前支持 Vxlan 和 Geneve ,但是也可以啟用 Linux 支持的所有封裝格式酵镜。
Native Routing, 使用 Linux 主機的常規(guī)路由表或云服務(wù)商的高級網(wǎng)絡(luò)路由等碉碉。此網(wǎng)絡(luò)要求能夠路由應(yīng)用容器的 IP 地址柴钻。
提供基于 BPF 的負(fù)載均衡
Cilium 能對應(yīng)用容器間的流量及外部服務(wù)支持分布式負(fù)載均衡淮韭。-
提供便利的監(jiān)控手段和排錯能力
可見性和快速的問題定位能力是一個分布式系統(tǒng)最基礎(chǔ)的部分。除了傳統(tǒng)的 tcpdump 和 ping 命令工具贴届,Cilium 提供了:
具有元數(shù)據(jù)的事件監(jiān)控:當(dāng)一個 Packet 包被丟棄靠粪,這個工具不會只報告這個包的源 IP 和目的 IP蜡吧,此工具還會提供關(guān)于發(fā)送方和接送方所有相關(guān)的標(biāo)簽信息。
決策追蹤:為何一個 packet 包被丟棄占键,為何一個請求被拒絕昔善?策略追蹤框架允許追蹤正在運行的工作負(fù)載和基于任意標(biāo)簽定義的策略決策過程。
通過 Prometheus 暴露 Metrics 指標(biāo):關(guān)鍵的 Metrics 指標(biāo)可以通過 Prometheus 暴露出來到監(jiān)控看板上進(jìn)行集成展示畔乙。
Hubble:一個專門為 Cilium 開發(fā)的可視化平臺君仆。它可以通過 flow log 來提供微服務(wù)間的依賴關(guān)系,監(jiān)控告警操作及應(yīng)用服務(wù)安全策略可視化牲距。
Cilium 的部署
此處使用外部的 etcd 的部署方式返咱,外部 etcd 安裝 cilium 在較大的運行環(huán)境中能夠提供更好的性能。
Requirements
1. Kubernetes >= 1.9
2. Linux kernel >= 4.9
3. ETCD >= 3.1.0
4. kubernetes 環(huán)境中安裝了 Helm 3
5. Kubernetes in CNI mode
6. 在所有 worker node 上掛載 BPF 文件系統(tǒng)
7. 推薦:在 kube-controller-manager 上使能 PodCIDR allocation (--allocate-node-cidrs)
安裝 helm 3
# 下載解壓 helm 安裝包
[root@k8s-master-01 ~]# wget https://get.helm.sh/helm-v3.1.2-linux-amd64.tar.gz
[root@k8s-master-01 ~]# tar -zxvf helm-v3.1.2-linux-amd64.tar.gz
[root@k8s-master-01 ~]# mv linux-amd64/helm /usr/local/bin/
# verify
[root@k8s-master-01 ~]# helm help
The Kubernetes package manager
Common actions for Helm:
- helm search: search for charts
- helm pull: download a chart to your local directory to view
- helm install: upload the chart to Kubernetes
- helm list: list releases of charts
Environment variables:
+------------------+-----------------------------------------------------------------------------+
| Name | Description |
+------------------+-----------------------------------------------------------------------------+
| $XDG_CACHE_HOME | set an alternative location for storing cached files. |
| $XDG_CONFIG_HOME | set an alternative location for storing Helm configuration. |
| $XDG_DATA_HOME | set an alternative location for storing Helm data. |
| $HELM_DRIVER | set the backend storage driver. Values are: configmap, secret, memory |
| $HELM_NO_PLUGINS | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. |
| $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") |
+------------------+-----------------------------------------------------------------------------+
Helm stores configuration based on the XDG base directory specification, so
- cached files are stored in $XDG_CACHE_HOME/helm
- configuration is stored in $XDG_CONFIG_HOME/helm
- data is stored in $XDG_DATA_HOME/helm
Use "helm [command] --help" for more information about a command.
掛載 BPF 文件系統(tǒng)
在 kubernetes 集群所有 node 上掛載 bpf 文件系統(tǒng)
[root@k8s-master-01 ~]# mount bpffs /sys/fs/bpf -t bpf
# verify
[root@k8s-master-01 ~]# mount |grep bpf
bpffs on /sys/fs/bpf type bpf (rw,relatime)
# persistence configuration, don’t worry that ‘bpffs’ displaying as red, seems bpf was new commer, fastab desen’t update that feature.
[root@k8s-master-01 ~]# echo "bpffs /sys/fs/bpf bpf defaults 0 0" >> /etc/fstab
kubernetes 配置
# 在所有的 kubernetes node 中的 kubelet 配置使用 CNI 模式, kubelet.config 中添加
--network-plugin=cni
# 在 kube-controller-manager 中使能 PodCIDR, kube-controller-manager.config 中添加
--allocate-node-cidrs=true
cilium 安裝
當(dāng)使用外部 etcd 作為 cilium 的 k-v 存儲牍鞠,etcd 的 IP 地址需要在 cilium 的 configmap 中配置咖摹。
使用 helm 安裝 cilium
# 添加 helm cilium repo
[root@k8s-master-01 ~]# helm repo add cilium https://helm.cilium.io/
# 創(chuàng)建 etcd ssl 證書
[root@k8s-master-01 ~]# kubectl create secret generic -n kube-system cilium-etcd-secrets \
--from-file=etcd-client-ca.crt=/etc/etcd/ssl/ca.crt \
--from-file=etcd-client.key=/etc/etcd/ssl/etcd.key \
--from-file=etcd-client.crt=/etc/etcd/ssl/etcd.crt
# 安裝 cilium,指定 cilium 版本為 v1.7.1, 開啟 SSL 驗證难述,開啟 prometheus 監(jiān)控萤晴,添加 etcd cluster 的 menber endpoints
[root@k8s-master-01 ~]# helm install cilium cilium/cilium\
--version 1.7.1\
--set global.etcd.enabled=true\
--set global.etcd.ssl=true\
--set global.prometheus.enabled=true\
--set global.etcd.endpoints[0]=https://172.19.50.7:2379\
--set global.etcd.endpoints[1]=https://172.19.60.32:2379\
--set global.etcd.endpoints[2]=https://172.19.100.16:2379\
--namespace kube-system
NAME: cilium
LAST DEPLOYED: Mon Mar 16 16:44:33 2020
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
# 驗證 cilium pod 都安裝成功
[root@k8s-master-01 ~]# kubectl --namespace kube-system get ds cilium
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
cilium 4 4 4 4 4 <none> 13h
[root@k8s-master-01 ~]# kubectl -n kube-system get deployments cilium-operator
NAME READY UP-TO-DATE AVAILABLE AGE
cilium-operator 1/1 1 1 13h
安裝 cilium 連接測試用例
此用例將會部署一系列的 deployment,它們會使用多種路徑來相互訪問胁后,連接路徑包括帶或者不帶服務(wù)負(fù)載均衡和各種網(wǎng)絡(luò)策略的組合店读。
部署的 podName 表示連接方式,readiness/liveness 探針則可指示連接是否成功攀芯。
[root@k8s-master-01 ~]# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/kubernetes/connectivity-check/connectivity-check.yaml -n app-service
[root@k8s-master-01 ~]# kubectl get pods -o wide -n app-service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
echo-a-58dd59998d-n9g9p 1/1 Running 0 9m13s 10.244.1.50 k8s-master-02 <none> <none>
echo-b-669ccc7765-lzqn7 1/1 Running 0 9m13s 10.244.2.50 k8s-master-03 <none> <none>
host-to-b-multi-node-clusterip-6fb94d9df6-rbjwz 1/1 Running 3 9m13s 192.168.66.226 k8s-master-02 <none> <none>
host-to-b-multi-node-headless-7c4ff79cd-hm6sr 1/1 Running 3 9m13s 192.168.66.226 k8s-master-02 <none> <none>
pod-to-a-5c8dcf69f7-gldq9 1/1 Running 3 9m13s 10.244.2.30 k8s-master-03 <none> <none>
pod-to-a-allowed-cnp-75684d58cc-tf9nn 1/1 Running 1 9m13s 10.244.2.239 k8s-master-03 <none> <none>
pod-to-a-external-1111-669ccfb85f-7r4j8 1/1 Running 0 9m13s 10.244.2.251 k8s-master-03 <none> <none>
pod-to-a-l3-denied-cnp-7b8bfcb66c-wd4nj 1/1 Running 0 9m13s 10.244.2.134 k8s-master-03 <none> <none>
pod-to-b-intra-node-74997967f8-ml5ps 1/1 Running 3 9m13s 10.244.2.95 k8s-master-03 <none> <none>
pod-to-b-multi-node-clusterip-587678cbc4-4qcb2 1/1 Running 3 9m13s 10.244.1.28 k8s-master-02 <none> <none>
pod-to-b-multi-node-headless-574d9f5894-tmfwn 1/1 Running 3 9m13s 10.244.1.138 k8s-master-02 <none> <none>
pod-to-external-fqdn-allow-google-cnp-6dd57bc859-l49z2 1/1 Running 0 9m12s 10.244.2.62 k8s-master-03 <none> <none>
安裝 hubble https://github.com/cilium/hubble
hubble 是一個用于云原生工作負(fù)載的完全分布式網(wǎng)絡(luò)和安全可視化平臺两入。它建立在 Cilium 和 eBPF 的基礎(chǔ)上,以完全透明的方式深入了解服務(wù)以及網(wǎng)絡(luò)基礎(chǔ)結(jié)構(gòu)的通信和行為敲才。
[root@k8s-master-01 ~]# git clone https://github.com/cilium/hubble.git
[root@k8s-master-01 ~]# cd hubble/install/kubernetes
[root@k8s-master-01 ~]# helm install hubble ./hubble \
--namespace kube-system \
--set metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,http}" \
--set ui.enabled=true
hubble 對前面安裝的測試用例監(jiān)控信息
Cilium 的網(wǎng)絡(luò)通信解析
cilium 在 kubernetes 集群中安裝好后裹纳,此處我們來探究一下在不同 node 上 pod 間的 vxlan 通信方式。
cilium 安裝完后紧武,cilium agent 會在 node 上創(chuàng)建 cilium_net
與 cilium_host
一對 veth pair 及用于跨宿主機通信的 cilium_vxlan
剃氧,然后在 cilium_host
上配置其管理的 CIDR IP 作為網(wǎng)關(guān)。
如上圖示中阻星,通過抓包分析 Container A 與 Container B 之前的通信路徑朋鞍。
Container A ping Container B (以下稱 Container A -> CA , Container B -> CB)
進(jìn)入 Node01 上 CA 內(nèi) (10.244.1.154),ping CB ip 地址 10.224.6.11
[root@Node01 ~]# docker exec -it 5eb8b6605c64 bash
root@voyager-client-8769496c4-ttzsj:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.244.1.154 netmask 255.255.255.255 broadcast 0.0.0.0
ether 02:16:7a:1d:0c:7e txqueuelen 0 (Ethernet)
RX packets 1518748 bytes 139582792 (133.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1377417 bytes 286246722 (272.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@voyager-client-8769496c4-ttzsj:/# ping 10.244.6.11
PING 10.244.6.11 (10.244.6.11) 56(84) bytes of data.
64 bytes from 10.244.6.11: icmp_seq=1 ttl=63 time=0.664 ms
64 bytes from 10.244.6.11: icmp_seq=2 ttl=63 time=1.58 ms
64 bytes from 10.244.6.11: icmp_seq=3 ttl=63 time=0.574 ms
64 bytes from 10.244.6.11: icmp_seq=4 ttl=63 time=0.493 ms
64 bytes from 10.244.6.11: icmp_seq=5 ttl=63 time=0.587 ms
64 bytes from 10.244.6.11: icmp_seq=6 ttl=63 time=0.460 ms
64 bytes from 10.244.6.11: icmp_seq=7 ttl=63 time=0.551 ms
進(jìn)入 Node01 上 cilium agent 容器內(nèi)妥箕,查看 CA 容器作為 cilium endpoint 的信息
[root@Node01 ~]# docker exec -it 7c0ce8909d21 bash
# 通過 cilium bpf endpoint 可看到在宿主機 Node01 上 CA 容器 attach 的網(wǎng)卡 mac 地址 F2:19:FC:0E:0A:8c
root@cilium-agent:~# cilium bpf endpoint list
IP ADDRESS LOCAL ENDPOINT INFO
10.96.0.10:0 (localhost)
192.168.66.226:0 (localhost)
10.102.101.239:0 (localhost)
10.101.126.212:0 (localhost)
10.99.24.234:0 (localhost)
10.244.1.4:0 id=1928 flags=0x0000 ifindex=10 mac=26:84:C5:50:4D:F9 nodemac=C6:AB:F1:63:C1:FE
10.99.146.112:0 (localhost)
10.96.0.1:0 (localhost)
10.110.33.8:0 (localhost)
10.244.1.208:0 (localhost)
10.111.30.67:0 (localhost)
10.108.89.187:0 (localhost)
10.107.23.171:0 (localhost)
10.244.1.183:0 id=3023 flags=0x0000 ifindex=48 mac=7E:DB:15:12:77:78 nodemac=CA:DE:51:6C:3B:6E
10.244.1.18:0 id=3047 flags=0x0000 ifindex=322 mac=92:BB:35:0B:64:DD nodemac=96:2D:AE:BD:78:6D
10.244.1.154:0 id=3432 flags=0x0000 ifindex=336 mac=02:16:7A:1D:0C:7E nodemac=F2:19:FC:0E:0A:8C
10.244.1.106:0 id=2222 flags=0x0000 ifindex=310 mac=02:EF:1A:74:99:36 nodemac=CE:12:20:E1:99:98
# 在宿主機上可看到對應(yīng)的網(wǎng)卡為 lxc8b528e748ff4(lxcxxA)
[root@Node01 ~]# ifconfig
cilium_host: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.244.1.208 netmask 255.255.255.255 broadcast 0.0.0.0
inet6 fe80::b814:51ff:fe6e:3ec0 prefixlen 64 scopeid 0x20<link>
ether ba:14:51:6e:3e:c0 txqueuelen 1000 (Ethernet)
RX packets 28524536 bytes 4348528855 (4.0 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1583 bytes 107646 (105.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
cilium_net: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1500
inet6 fe80::cd4:62ff:fe16:2c7c prefixlen 64 scopeid 0x20<link>
ether 0e:d4:62:16:2c:7c txqueuelen 1000 (Ethernet)
RX packets 1583 bytes 107646 (105.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 28524536 bytes 4348528855 (4.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
cilium_vxlan: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::f4ee:12ff:fe6e:c46f prefixlen 64 scopeid 0x20<link>
ether f6:ee:12:6e:c4:6f txqueuelen 1000 (Ethernet)
RX packets 24633319 bytes 3811772734 (3.5 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 24389802 bytes 6318433970 (5.8 GiB)
TX errors 0 dropped 46 overruns 0 carrier 0 collisions 0
.......
lxc8b528e748ff4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::f019:fcff:fe0e:a8c prefixlen 64 scopeid 0x20<link>
ether f2:19:fc:0e:0a:8c txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
.......
CA 容器 ping 出的 icmp 包將會經(jīng)過網(wǎng)卡 lxc8b528e748ff4 (lxcxxA) 路由到 cilium_host
網(wǎng)關(guān)滥酥,路由方式與傳統(tǒng)的通過 Linux bridge 這樣的二層設(shè)備轉(zhuǎn)發(fā)不一樣,cilium 在每個容器相關(guān)聯(lián)的虛擬網(wǎng)卡上都附加了 bpf 程序畦幢,通過連接到 TC ( traffic control ) 入口鉤子的 bpf 程序?qū)⑺芯W(wǎng)絡(luò)流量路由到主機端虛擬設(shè)備上坎吻,由此 cilium 便可以監(jiān)視和執(zhí)行有關(guān)進(jìn)出節(jié)點的所有流量的策略,例如 pod 內(nèi)的 networkPolicy 宇葱、L7 policy瘦真、加密等規(guī)則刊头。
# CA 容器內(nèi)的默認(rèn)路由指向 cilium_host 網(wǎng)關(guān)地址 10.244.1.208
root@voyager-client-8769496c4-ttzsj:/# ip route
default via 10.244.1.208 dev eth0 mtu 1450
10.244.1.208 dev eth0 scope link
CA 容器內(nèi)的流量要跨宿主機節(jié)點路由到 CB 容器,則需要 cilium_vxlan
VTEP 設(shè)備對流量包進(jìn)行封裝轉(zhuǎn)發(fā)到 Node02 上诸尽。bpf 程序會查詢 tunnel 規(guī)則并將流量發(fā)送給 cilium_vxlan
原杂,在 cilium agent 容器內(nèi)可查看到 bpf 的 tunnel 規(guī)則
[root@Node01 ~]# docker exec -it 7c0ce8909d21 bash
root@cilium-agent:~# cilium bpf tunnel list
TUNNEL VALUE
10.244.3.0:0 192.168.66.196:0
10.244.2.0:0 192.168.66.194:0
10.244.6.0:0 192.168.66.221:0 # CB 容器 ip 為 10.244.6.11, tunnel 對端地址為 192.168.66.221,即為 Node02 主機節(jié)點地址
在 Node01 上對 cilium_vxlan
抓包您机,可看到 CA 容器對 icmp 包經(jīng)過了 cilium_vxlan
[root@Node01 ~]# tcpdump -i cilium_vxlan icmp -n -vv
tcpdump: listening on cilium_vxlan, link-type EN10MB (Ethernet), capture size 262144 bytes
15:54:23.550645 IP (tos 0x0, ttl 64, id 18157, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 497, seq 509, length 64
15:54:23.551123 IP (tos 0x0, ttl 64, id 12892, offset 0, flags [none], proto ICMP (1), length 84)
10.244.6.11 > 10.244.1.154: ICMP echo reply, id 497, seq 509, length 64
15:54:24.574575 IP (tos 0x0, ttl 64, id 18805, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 497, seq 510, length 64
15:54:24.574999 IP (tos 0x0, ttl 64, id 13181, offset 0, flags [none], proto ICMP (1), length 84)
10.244.6.11 > 10.244.1.154: ICMP echo reply, id 497, seq 510, length 64
15:54:25.598625 IP (tos 0x0, ttl 64, id 19388, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 497, seq 511, length 64
15:54:25.599107 IP (tos 0x0, ttl 64, id 13587, offset 0, flags [none], proto ICMP (1), length 84)
再對 Node01 上的 eth0 抓包穿肄,可看到 cilium_vxlan
已將 CA 的流量進(jìn)行 vxlan 封包,src ip 改為本機 node ip 192.168.66.226, dst ip 改為 192.168.66.221
[root@Node01 ~]# tcpdump -i eth0 -n dst 192.168.66.221 and udp -vv
17:48:38.398691 IP (tos 0x0, ttl 64, id 58330, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 35369, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 1878, length 64
17:48:39.422639 IP (tos 0x0, ttl 64, id 58509, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 36202, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 1879, length 64
17:48:40.446630 IP (tos 0x0, ttl 64, id 59226, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 37119, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 1880, length 64
17:48:41.470617 IP (tos 0x0, ttl 64, id 60174, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 37830, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 1881, length 64
到 Node02 上對 eth0 抓包际看,可看到 CA 容器的流量包已到 Node02 上
[root@Node02 ~]# tcpdump -i eth0 -n src 192.168.66.226 and udp -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
05:55:08.542658 IP (tos 0x0, ttl 64, id 52637, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 33378, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2259, length 64
05:55:09.566806 IP (tos 0x0, ttl 64, id 52888, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 34260, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2260, length 64
05:55:10.567877 IP (tos 0x0, ttl 64, id 53331, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 34318, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2261, length 64
05:55:11.614841 IP (tos 0x0, ttl 64, id 54206, offset 0, flags [none], proto UDP (17), length 134)
192.168.66.226.60971 > 192.168.66.221.otv: [no cksum] OTV, flags [I] (0x08), overlay 0, instance 27634
IP (tos 0x0, ttl 64, id 35300, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2262, length 64
對 cilium_vxlan
抓包即可看到 CA 容器過來對流量包已被解封
[root@Node02 ~]# tcpdump -i cilium_vxlan -n dst 10.244.6.11 -vv
tcpdump: listening on cilium_vxlan, link-type EN10MB (Ethernet), capture size 262144 bytes
05:59:22.494598 IP (tos 0x0, ttl 64, id 25390, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2507, length 64
05:59:23.518736 IP (tos 0x0, ttl 64, id 26363, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2508, length 64
05:59:24.542563 IP (tos 0x0, ttl 64, id 26951, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2509, length 64
05:59:25.566736 IP (tos 0x0, ttl 64, id 27503, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2510, length 64
05:59:26.590731 IP (tos 0x0, ttl 64, id 28392, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2511, length 64
05:59:27.614648 IP (tos 0x0, ttl 64, id 28548, offset 0, flags [DF], proto ICMP (1), length 84)
10.244.1.154 > 10.244.6.11: ICMP echo request, id 502, seq 2512, length 64
至此被碗,CA 容器對流量已到達(dá) cilium 創(chuàng)建的虛擬網(wǎng)卡。
我們知道 Linux 內(nèi)核本質(zhì)上是事件驅(qū)動的(the Linux Kernel is fundamentally event-driven), cilium 創(chuàng)建的虛擬網(wǎng)卡接收到流量包將會觸發(fā)連接到 TC ( traffic control ) ingress 鉤子的 bpf 程序仿村,對流量包進(jìn)行相關(guān)策略對處理锐朴。
查看 cilium 官方給出的 ingress/egress datapath,可大致驗證上述 cilium 的網(wǎng)絡(luò)通信路徑蔼囊。
首先是 egress datapath
焚志,圖中橙黃色標(biāo)簽為 cilium component,有 cilium 在宿主機上創(chuàng)建的 bpf 程序(對應(yīng)著紅色標(biāo)簽的 kernel bpf 鉤子)畏鼓,若使用 L7 Policy 則還有 cilium 創(chuàng)建的 iptables 規(guī)則酱酬。流量從某個容器 endpoint 通過容器上的 veth pair 網(wǎng)卡 lxcxxx 出發(fā),即會觸發(fā) bpf_sockops.c / bpf_redir.c bpf 程序云矫,若使用了 L7 Policy 則進(jìn)入用戶空間進(jìn)行 L7 層的數(shù)據(jù)處理膳沽,若沒有使能 L7 Policy 則將觸發(fā) TC egress 鉤子,bpf_lxc 對數(shù)據(jù)進(jìn)行處理(若使能 L3 加密让禀,則觸發(fā)其他 bpf 鉤子)挑社,數(shù)據(jù)最終被路由到 cilium_hos
t 網(wǎng)關(guān)處,再根據(jù) overlay 模式(vxlan 等)將數(shù)據(jù)發(fā)送出去巡揍。
在 cilium ingress datapath
中痛阻,數(shù)據(jù)流量進(jìn)入主機網(wǎng)絡(luò)設(shè)備上,cilium 可根據(jù)相關(guān)配置腮敌,對數(shù)據(jù)流量進(jìn)行預(yù)處理(prefilter/L3 加解密/ 負(fù)載均衡/ L7 Policy 處理)或直接路由到 cilium_host
觸發(fā)相應(yīng)到 bpf 程序阱当,再到最終的 endpoint 處。