始める前に、少し話がそれますが。 Flannel CNI の最後のリリースから約 1 か月が経ちました。勢いに乗って昨年末に完成させるつもりでしたが、1ヶ月以内に予定していた内容をすべて完成させることができました。しかし、最後の投稿が公開されてから間もなく、私は感染してしまい、回復するまでに1週間以上かかりました。しかし、回復後の状態は私を少し混乱させました。私はいつも集中するのが難しく、気が散りやすいと感じていました。ネット上で広まっている「脳の霧」に近いかもしれないが、Cilium も霧のようなものだ。ネットワークに関する知識が不足し、eBPF の経験も不足していたため、私の学習プロセスは断続的なものでした。かつて私はこの記事が中止されるのではないかと疑っていました。 その記事には必ず問題があるはずだ。何か問題や提案がございましたら、お気軽にお知らせください。 背景昨年、私は「CiliumによるKubernetesネットワークセキュリティの強化」[1]という記事を書きました。その中で、私はCiliumに触れ、Ciliumのネットワークポリシーを使用して、ネットワークレベルでポッド間の通信を制限する方法を学びました。しかし、当時の私はその実装原理を深く理解しておらず、Kubernetes ネットワークや CNI についても十分に理解していませんでした。今回は、実際の環境を通じて Cilium のネットワークを探索します。 この記事では、Cilium バージョン v1.12.3、オペレーティング システムが Ubuntu 20.04、カーネル バージョンが 5.4.0-91-generic を使用しています。 CiliumについてCilium[2]は、革新的なカーネルテクノロジーeBPF[3]を搭載した、コンテナワークロード(クラウドネイティブ)間のネットワーク接続のプロビジョニング、セキュリティ保護、監視を行うオープンソースソフトウェアです。 Kubernetes 上の cilium eBPF とは何ですか?Linux カーネルは、監視/観測性、ネットワーク、セキュリティ機能を実装するのに常に理想的な場所でした。ただし、多くの場合、これは簡単な作業ではありません。これらのタスクではカーネル ソース コードの変更やカーネル モジュールのロードが必要であり、最終的な実装では既存の抽象化レイヤーに新しい抽象化を重ね合わせることになるためです。 eBPF は、カーネル ソース コードを変更したりカーネル モジュールをロードしたりすることなく、カーネル内でサンドボックス プログラムを実行できる革新的なテクノロジです。 Linux カーネルをプログラム可能にすることで、システムの複雑さを増したり、実行効率やセキュリティを犠牲にしたりすることなく、既存の抽象化レイヤーに基づいて (新しいレイヤーを追加するのではなく)、よりスマートで機能豊富なインフラストラクチャ ソフトウェアを構築できるようになります。 Linux カーネルは、ネットワーク スタック上に一連の BPF フックを提供しており、これを通じて BPF プログラムの実行をトリガーできます。 Cilium datapah はこれらのフックを使用して BPF プログラムをロードし、より高度なネットワーク構造を作成します。 CiliumのリファレンスドキュメントeBPF Datapath[4]を読むと、Ciliumが以下のフックを使用していることがわかります。
これらのフックは後ほど使用するので、ここで詳しく説明します。 環境構築前回の記事では、k3s を使用し、CNI プラグインを手動でインストールして実験環境を構築しました。今回は、k8eがデフォルトのCNI実装としてCiliumを使用しているため、k8e[5]を直接使用します。 私は今でもホームラボにデュアルノード クラスター (ubuntu-dev2: 192.168.1.12、ubuntu-dev3: 192.168.1.13) を作成しています。 マスターノード: curl - sfL https://getk8e.com/install.sh | API_SERVER_IP = 192.168 .1 .12 K8E_TOKEN = ilovek8e INSTALL_K8E_EXEC = " server --cluster-init --write - kubeconfig-mode 644 --write-kubeconfig ~/.kube/config" sh - ワーカーノード: curl - sfL https://getk8e.com/install.sh | K8E_TOKEN = ilovek8e K8E_URL = https://192.168.1.12:6443sh - サンプル アプリケーションをデプロイし、さまざまなノードにスケジュールします。 ノード1 = Ubuntu - dev2 使いやすくするために、サンプル アプリケーション、繊毛ポッド、その他の情報を環境変数として設定します。 ノード1 = ubuntu-dev2 トラフィックのデバッグこれは、リクエストの発信元からネットワーク パケットをずっと追跡するという、従来と同じルーチンです。今回は、サービスを使用してアクセスします: curl http://10.42.0.51:80/get。 kubectl get po httpbin - n デフォルト- o ワイド ステップ1: コンテナがリクエストを送信するポッドカールのルーティングテーブルを確認します。 kubectl exec curl -nデフォルト-- ip ルート 取得 10.42.0.51 ネットワーク パケットがイーサネット インターフェイス eth0 に送信され、arp を使用してその MAC アドレス ae:36:76:3e:c3:03 が見つかることがわかります。 kubectl exec curl -nデフォルト-- arp -n インターフェース eth0 の情報を表示します。 kubectl exec curl -nデフォルト-- ip リンク show eth0 MAC アドレスが ae:36:76:3e:c3:03 ではないことがわかります。名前の @if43 から、その veth ペアのインデックスが 43 であることがわかります。次に、ノード NODE1 にログインして、インデックス インターフェイスの情報を照会します。 IPリンク| grep -A1 ^ 43 このインターフェース lxc48c4aa0637ce の MAC はまさに ae:36:76:3e:c3:03 であることがわかります。 過去の経験[6]によれば、この仮想イーサネットインターフェースlxc48c4aa0637ceは、ホストのルートネットワーク名前空間に配置された仮想イーサネットポートです。一方では、トンネルを介してコンテナのイーサネット インターフェイス eth0 に接続されており、いずれかの端に送信されたネットワーク パケットは、もう一方の端に直接到達します。一方、ホスト名前空間内のブリッジに接続されているはずですが、上記の結果にはブリッジの名前が見つかりません。 IPリンクから表示: 1 : lo : < LOOPBACK 、 UP 、 LOWER_UP > mtu 65536 qdisc noqueue 状態UNKNOWNモード DEFAULTグループデフォルト qlen 1000 複数のイーサネット インターフェイス (cilium_net、cilium_host、cilium_vxlan、cilium_health) と、コンテナー ネットワーク名前空間のイーサネット インターフェイスへのトンネル ピア lxcxxxx が表示されます。 繊毛交差節 ネットワーク パケットは lxcxxx に到達した後どのように進むべきでしょうか?次はeBPFが登場する番です。 cilium_net、cilium_host、cilium_health についてはこの記事では取り上げないので、次の図には示されていないことに注意してください。 ステップ2: Pod1 LXC BPF 入力現在のノードの繊毛ポッド(先ほど設定した変数 $cilium1)に入り、bpftool コマンドを使用して、veth にアタッチされている BPF プログラムを確認します。 kubectl exec - n kube -システム $cilium1 - c cilium -エージェント-- bpftool net show dev lxc48c4aa0637ce ノード $NODE1 にログインし、tc コマンドを使用してクエリを実行することもできます。記事の冒頭にあるデータパス セクションで、ここでイングレスを指定していることに注意してください。コンテナの eth0 とホスト ネットワーク名前空間の lxc がチャネルを形成するため、コンテナの出力トラフィックは lxc の入力トラフィックになります。同様に、コンテナの入力トラフィックは lxc の出力トラフィックです。 #NODE1 の場合 詳細情報はプログラム ID 2901 からご覧いただけます。 kubectl exec - n kube -システム $cilium1 - c cilium -エージェント-- bpftool prog show id 2901 ここで、BPF プログラム bpf_lxc.o のコンテナからの部分がロードされていることがわかります。 Ciliumソースコードbpf_lxc.c[7]の__section("from-container")セクションに移動すると、プロシージャ名はhandle_xgressです。 ハンドル_xgress #1 (1):ネットワークパケットのヘッダー情報がhandle_xgressに送信され、L3プロトコルがチェックされます。 (2):すべてのIPv4ネットワークパケットはtail_handle_ipv4によって処理されます。 (3): コアロジックはhandle_ipv4_from_lxcにあります。 tail_handle_ipv4 が handle_ipv4_from_lxc にジャンプする方法。ここではテイルズコール[8]が使われます。 Tails 呼び出しを使用すると、BPF プログラムが完了し、特定の条件が満たされたときに、元のプログラムに戻らずに、別の指定されたプログラムが実行されるように構成できます。ここでは詳細には触れませんが、興味のある方は公式ドキュメント[9]を参照してください。 (4):次に、eBPFマップcilium_ipcacheからターゲットエンドポイントを照会し、トンネルエンドポイント192.168.1.13を見つけます。このアドレスはターゲットが配置されているノードの IP アドレスであり、タイプはです。 kubectl exec - n kube - system $cilium1 - c cilium -エージェント-- cilium マップ get cilium_ipcache | grep 10.42.0.51 (5): policy_can_access これはエクスポートポリシーを実行するためのチェックですが、この記事では取り上げておらず、詳しく説明しません。 (6):その後の処理には2つのモードがある。
ここでもトンネルモードを使用します。ネットワーク パケットは、トンネル エンドポイントをトンネル ピアとして使用して、処理のために encap_and_redirect_lxc に渡されます。最後に、イーサネット インターフェイス cilium_vxlan である ENCAP_IFINDEX (この値は、cilium-agent の起動時に取得されるインターフェイスのインデックス値) に転送されます。 ステップ3: ノード1 vxlan BPF 出力まず、このインターフェース上の BPF プログラムを見てみましょう。 kubectl exec -n kube -システム $cilium1 -c cilium -エージェント--bpftool net show dev cilium_vxlan コンテナの出力トラフィックは cilium_vxlan の出力でもあるため、ここでの手順は to-overlay です。 プログラムは`bpf_overlay.c`[10]にあります。このプログラムの処理は非常に簡単です。 IPv6 プロトコルの場合、パケットは IPv6 アドレスを使用して一度カプセル化されます。こちらは IPv4 で、直接 CTX_ACT_OK を返します。ネットワーク パケットはカーネル ネットワーク スタックに渡され、eth0 インターフェイスに入ります。 ステップ4: NODE1 NIC BPF 出力まずBPFプログラムを見てみましょう。 kubectl exec -n kube -システム $cilium1 -c cilium -エージェント--bpftool net show dev eth0 出力プログラムto-netdevは`bpf_host.c`[11]にあります。実際には、重要な処理は行われません。 CTX_ACT_OK を返してカーネル ネットワーク スタックに渡してさらに処理します。つまり、ネットワーク パケットを vxlan トンネルのもう一方の端、つまりノード 192.168.1.13 に送信します。中間データの送信では、実際には、ホストの eth0 インターフェイスから基盤ネットワークを経由してターゲット ホストの eth0 インターフェイスまで、基盤ネットワークが使用されます。 ステップ5: NODE2 NIC BPFイングレスvxlan ネットワーク パケットがノードの eth0 インターフェイスに到着すると、BPF プログラムもトリガーされます。 kubectl exec -n kube -システム $cilium2 -c cilium -エージェント--bpftool net show dev eth0 今回のトリガーはbpf_host.c[12]にあるfrom-netdevです。 から vxlan トンネル モードの場合、ここでのロジックは非常に単純です。ネットワーク パケットが vxlan であり、vlan が許可されていると判断された場合、直接 CTX_ACT_OK を返し、カーネル ネットワーク スタックに処理を渡します。 ステップ6: NODE2 vxlan BPF イングレスネットワーク パケットはカーネル ネットワーク スタックを通過し、インターフェイス cilium_vxlan に到達します。 kubectl exec - n kube -システム $cilium2 - c cilium -エージェント-- bpftool net show dev cilium_vxlan このプログラムは`bpf_overlay.c`[13]にあります。 オーバーレイから (1): lookup_ip4_endpointは、ターゲットアドレスがeBPFマップcilium_lxc内の現在のノードにあるかどうかを確認します(このマップは現在のノード内のエンドポイントのみを格納します)。 kubectl exec - n kube - system $cilium2 - c cilium -エージェント-- cilium マップ get cilium_lxc | grep 10.42.0.51 ここで、ターゲット エンドポイント情報 (ID、イーサネット ポート インデックス、MAC アドレス) を見つけることができます。 NODE2 ノードでインターフェース情報を確認し、このネットワーク ポートが仮想イーサネット デバイス lxc65015af813d1 であることを確認します。これは、ポッド httpbin インターフェース eth0 のちょうど反対側の端です。 IPリンク| grep - B1 - i d2 : ad (2)ipv4_local_deliveryのロジックは`l3.h`[14]にあり、エンドポイントのLXC ID(29)にあるBPFプログラムを末尾呼び出しします。 ステップ7: Pod2 LXC BPF出力次のコマンドを実行しても、期待される出力 to-container (および from-container) が見つかりません。 kubectl exec -n kube -system $cilium2 -c cilium -agent --bpftool net show |グレップ 29 以前使用されていた BPF プログラムはすべてインターフェースに接続されていましたが、ここでは vxlan 接続プログラムが直接末尾呼び出されます。 to-containerは`bpf-lxc.c`[15]にあります。 コンテナへのハンドル (1)ipv4_policyは設定されたポリシーを実行する (2):ポリシーが通過すると、redirect_epが呼び出され、ネットワークパケットが仮想イーサネットインターフェースlxc65015af813d1に送信されます。 veth に入ると、それに接続されているコンテナの eth0 インターフェースに直接到達します。 ステップ8: ポッド2に到達するネットワーク パケットが pod2 に到着します。完成写真を添付します。 繊毛パケットフロー 要約する私の個人的な意見を述べさせてください。この記事で紹介したコンテンツは、Cilium の氷山の一角にすぎません。カーネルの知識と C 言語の知識が不足しているため、勉強するのは非常に困難です。 Cilium には、まだ詳細に研究されていないコンテンツが多数あります。 Cilium は本当に複雑だと言わざるを得ません。私の知る限り、Cilium はエンドポイント、ノード、ポリシー、ルート、接続ステータス、その他多くのデータなど、BPF マップ内に独自のデータセットを保持しており、これらはすべてカーネルに保存されています。さらに、BPF プログラムの開発および保守コストは、機能の複雑さに応じて増大します。 BPF プログラムを使用して L7 機能を開発することがどれほど複雑になるかは想像しにくいです。おそらくこれが、L7 シナリオを処理するためにプロキシを使用する理由です。 最後に、Cilium を学習した私の経験を共有したいと思います。 最初のステップは、BPF プログラムを読むことです。プロジェクト内の bpf コードは静的コードであり、構成関連の if else ステートメントが多数含まれています。実行時に構成に従ってコンパイルされます。この場合、Cilium pod に入ることができます。 /run/cilium/state/templates ディレクトリには、アプリケーション構成後のソース ファイルがあり、コードの量が大幅に少なくなります。 /run/cilium/state/globals/node_config には現在使用されている構成があり、これらの構成と組み合わせてコードを読み取ることができます。 脚注
参考文献[1] 「Cilium で Kubernetes ネットワークセキュリティを強化する」: https://atbug.com/enhance-kubernetes-network-security-with-cilium/ [2] 繊毛: https://cilium.io [3] eBPF: https://ebpf.io [4] CiliumリファレンスドキュメントeBPFデータパス: https://docs.cilium.io/en/stable/concepts/ebpf/intro/ [5] k8e: https://getk8e.com [6] 過去の経験: https://atbug.com/deep-dive-k8s-network-mode-and-communication/ [7] bpf_lxc.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_lxc.c#L1320 [8] テイルズコール: https://docs.cilium.io/en/stable/bpf/#tail-calls [9] 公式ドキュメント: https://docs.cilium.io/en/stable/bpf/#tail-calls [10] bpf_overlay.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_overlay.c#L528 [11] bpf_host.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_host.c#L1081 [12] bpf_host.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_host.c#L1040 [13] bpf_overlay.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_overlay.c#L430 [14] l3.h: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/lib/l3.h#L114 [15] bpf-lxc.c: https://github.com/cilium/cilium/blob/1c466d26ff0edfb5021d024f755d4d00bc744792/bpf/bpf_lxc.c#L2131 |
<<: プライベートクラウドの構築には、ALLINONE と階層独立構築・最適化のどちらを使うべきでしょうか?
>>: 異なる Kubernetes バージョンでの ServiceAccount トークンの使用
長い歴史を持つ偉大な国として、中国文化は非常に広大かつ奥深いため、毎年多くの外国人学者が中国を訪れ、...
画像出典: Tuchong Creative Yandex はロシアで最も広く使用されている検索エン...
CloudconeはDouble 12の特別プロモーションを開始しました。3つの安価なVPSは5Tト...
「国民が大胆になればなるほど、土地の生産性は高まる」。この言葉は、インターネット時代の電子商取引ライ...
長い間、ドメイン名には注目していませんでした。一般的なドメイン名販売業者のプロモーション情報をお送り...
WebSound.co.uk という会社は英国に登録されています。本当に英国人によって開設されたかど...
SEO 担当者として、このタイトルを見て、ナンセンスだと思いますか? ネットワーク プロモーションは...
最も影響力のある 3 つのクラウド コンピューティング ベンダーについて話すとき、人々は間違いなく ...
ChatGPTはインターネット上で人気を博しており、その背後にあるAIモデルのトレーニングも広く注目...
[51CTO.com からのオリジナル記事] 今年、この流行病は世界に多大な影響をもたらし、人々の生...
多くの初心者は、検索エンジンに含まれない問題に悩まされています。誰もが初心者の頃にこの状況を経験した...
新年を迎えた今、マシンを購入する際に、トラフィック制限のある大きな帯域幅を選択するか、トラフィック制...
自分のウェブサイトをデザインするときは、ウェブサイトがスパイダー トラップに陥らないように、いくつか...
WeChatのミニゲームには現在独自のシステムがあり、商業広告は無視できない重要な要素となっています...
百度と奇虎360の間の検索紛争を受けて、国家著作権局は最近、360 Searchが百度のコンテンツを...