kubernetes 集群中 cilium 的實踐及其網(wǎng)絡(luò)通信解析

Cilium Overview

Cilium 是一個基于 eBPF 和 XDP 的高性能容器網(wǎng)絡(luò)方案的開源項目救恨,目標(biāo)是為微服務(wù)環(huán)境提供網(wǎng)絡(luò)纵朋、負(fù)載均衡雷客、安全功能裙秋,主要定位是容器平臺容燕。

cilium.png

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 提供了:

    1. 具有元數(shù)據(jù)的事件監(jiān)控:當(dāng)一個 Packet 包被丟棄靠粪,這個工具不會只報告這個包的源 IP 和目的 IP蜡吧,此工具還會提供關(guān)于發(fā)送方和接送方所有相關(guān)的標(biāo)簽信息。

    2. 決策追蹤:為何一個 packet 包被丟棄占键,為何一個請求被拒絕昔善?策略追蹤框架允許追蹤正在運行的工作負(fù)載和基于任意標(biāo)簽定義的策略決策過程。

    3. 通過 Prometheus 暴露 Metrics 指標(biāo):關(guān)鍵的 Metrics 指標(biāo)可以通過 Prometheus 暴露出來到監(jiān)控看板上進(jìn)行集成展示畔乙。

    4. 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)控信息

image.png

Cilium 的網(wǎng)絡(luò)通信解析

cilium 在 kubernetes 集群中安裝好后裹纳,此處我們來探究一下在不同 node 上 pod 間的 vxlan 通信方式。

image.png

cilium 安裝完后紧武,cilium agent 會在 node 上創(chuàng)建 cilium_netcilium_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_host 網(wǎng)關(guān)處,再根據(jù) overlay 模式(vxlan 等)將數(shù)據(jù)發(fā)送出去巡揍。

image.png

在 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 處。

image.png

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糜工,一起剝皮案震驚了整個濱河市弊添,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捌木,老刑警劉巖油坝,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡免钻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門崔拥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來极舔,“玉大人,你說我怎么就攤上這事链瓦〔鹞海” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵慈俯,是天一觀的道長渤刃。 經(jīng)常有香客問我,道長贴膘,這世上最難降的妖魔是什么卖子? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮刑峡,結(jié)果婚禮上洋闽,老公的妹妹穿的比我還像新娘。我一直安慰自己突梦,他們只是感情好诫舅,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宫患,像睡著了一般刊懈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娃闲,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天虚汛,我揣著相機與錄音,去河邊找鬼皇帮。 笑死泽疆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玲献。 我是一名探鬼主播殉疼,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捌年!你這毒婦竟也來了瓢娜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤礼预,失蹤者是張志新(化名)和其女友劉穎眠砾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體托酸,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡褒颈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年柒巫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谷丸。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡堡掏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刨疼,到底是詐尸還是另有隱情泉唁,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布揩慕,位于F島的核電站亭畜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏迎卤。R本人自食惡果不足惜拴鸵,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜗搔。 院中可真熱鬧宝踪,春花似錦、人聲如沸碍扔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽不同。三九已至厉膀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間二拐,已是汗流浹背服鹅。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留百新,地道東北人企软。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像饭望,于是被迫代替她去往敵國和親仗哨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345