大規模環境でCiliumを運用して得られた課題と知見

1K Views

December 03, 24

スライド概要

2024/11/28-29 に開催されたCloudNative Days Winter 2024の、terashima と 武 直樹の発表資料です。

CloudNative Days Winter 2024
https://event.cloudnativedays.jp/cndw2024

profile-image

サイボウズ株式会社の主に開発本部の資料を公開するアカウントです。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

大規模環境でCiliumを運用して得られた課題と知見 サイボウズ株式会社 Naoki Take Tomoya Terashima 1

2.

NecoとCilium 4

3.

CybozuのKubernetes Cluster(Neco) ▌オンプレ環境のKubernetesクラスタ (数百台規模) ▌サーバーからミドルウェアまで全て管理している ⚫ Neco-networkチームでは4名でKubernetesのNetworking部分 のコンポーネントを開発/運用 デプロイ ミドルウェアの提供・運用 サーバー・クラスタの自動管理 利用 5

4.

Ciliumとは ▌CNIプラグイン ⚫ コンテナのネットワーク疎通 ▌CNCF Graduated Project ▌eBPFをデータプレーンに活用 ▌豊富な機能 ⚫ NetworkPolicy ⚫ L4/L7 LB ⚫ kube-proxy置換(脱iptables) ⚫ etc… This presentation is not affiliated with or otherwise sponsored by eBPF Foundation. 6

5.

Necoで利用しているCiliumの主な機能 ▌L4LB o eBPFベースの高性能かつ高可用なL4LBを提供 o ノード故障などによるロードバランサ構成の変化の影響を最小限に抑えて通 信を捌くことができる ▌kube-proxy置換 o 従来のiptablesベースのkube-proxyをeBPFベースの実装に置き換える ことで、性能/スケーラビリティ問題を解消 ▌ネットワークポリシー o Kubernetes標準のネットワークポリシーより高度な制御を実装可能 o L3、L4ルールの他にL7ルールやDNSルールを記述できる 7

6.

本発表の趣旨 ▌Ciliumの導入によりさまざまなメリットを享受できている一方で、Cilium に起因する問題もいくつか発生しています。 ▌本発表ではNecoで遭遇したCilium関連の問題とそれに対する対応を いくつか紹介します。 8

7.

Ciliumに関連する障害とその対応 9

8.

Ciliumに関連する障害とその対応 1. kube-apiserverと通信できなくなった時cilium-agentが停止してしまう 2. Connection Tracking Tableが溢れそうになった 3. CiliumIdentityの氾濫によるPod作成失敗 4. CiliumEndpointが作成されず、Pod が通信できなくなった 10

9.

1. kube-apiserverと通信できなくなった時 cilium-agentが停止してしまう 11

10.

cilium-agent と cilium-operator ▌cilium-agent ⚫ DaemonSetとして各nodeに存在 ⚫ ノード内のeBPFプログラムを管理し、コンテナの作成・削除・設定情報の変 更に応じて、データプレーンであるeBPFのプログラムをビルド・ロードして更新 ▌cilium-operator ⚫ クラスタ内に1つ以上(Deployment) ⚫ CRDの登録・IPAM・各種ガベージコレクションなどを担当 12

11.

kube-apiserverに対するヘルスチェック ▌cilium-agentはkube-apiserverに対して定期的に疎通性を確認 ⚫ livenessProbeの処理の中で実施 13

12.

kube-apiserver と cilium-agentの共倒れ ▌kube-apiserverから正常応答がない場合ヘルスチェックが失敗 →livenessProbeが落ちる→kubeletにkillされる 14

13.

LoadBalancer と CiliumのBGP機能 ▌NecoではLoadBalancer ServiceをCilium組み込みのBGP 機能を利用して提供 ▌Service作成時に割り当てられた VIPはcilium-agent内のBGP speakerによりクラスタの外部に広 報される 15

14.

実際に起きた障害 1. etcdの不具合によりkubeapiserverが正常に処理できなくなる 障害が発生 2. cilium-agentとそのBGP広報機能 が停止 3. クラスタ内全てのLB Serviceにア クセスできない状態に・・・ (注: 幸いなことに開発環境でのできごとです) 16

15.

問題点 ▌CiliumによるL4LB機能がKubernetesのコントロールプレーンに依存 ▌Kubernetesのコントロールプレーンが落ちても既存のワークロードには影 響が出ないようにしたい 17

16.

対策 ▌kube-apiserverに対するヘルスチェックを無効にするオプションを upstreamに提案/実装 → マージされた (半年ぐらいかかった) daemon: Make cilium status independent from k8s status https://github.com/cilium/cilium/pull/32724 18

17.

2. Connection Tracking Tableが 溢れそうになった 19

18.

Connection Tracking Table ▌Connection Tracking (CT) o 通信の状態を保存してNATやネットワークポリシーに活用 ▌CiliumではeBPF Mapを用いて実装されている o 以下CT Mapと呼ぶ ▌NecoではNodeごとの管理 o Nodeのメモリ上に保存 o 容量上限が存在 ▪ 当時は約10Mコネクションを 同時に保存できる状態 20

19.

eBPF(BPF) Mapについて ▌eBPFプログラムの中で利用できる キーバリューストア ▌eBPFプログラム間、ユーザスペース /カーネルスペースのプログラム間での データのやりとりに利用される https://docs.cilium.io/en/latest/reference-guides/bpf/architecture/ 21

20.

発生した事象 ▌CT Mapの使用率が40%弱から80%に急増 ▌あと数時間で使用率100%に… o 使用率が100%になると、新規のコネクションを保存するために古いコネク ションの情報を捨ててしまう→既存の通信が切断する可能性 80% 40% 22

21.

原因 ▌あるワークロードが接続する対象が約2倍に増えた ことによるコネクション数の増加 ▌デフォルトだとGCの間隔が長かった(~12h) o 終了したコネクション用のエントリは定期的にGC 処理で削除されている o 短命なコネクションが短時間に大量に生成され たことで、Mapの容量を圧迫していた 23

22.

対策 ▌100%に達する前にCT Mapの容量拡張を実施 o bpf-map-pressure-exporterというツールを開発(※)して、Mapの 容量を監視していたので気づけた (※)当時necoで使っていたCilium 1.13ではCT Map ▌GCの設定を見直し 容量のメトリクスが非対応だったため独自開発 o GC間隔の上限値を引き下げ → 効果ありそう 20% 24

23.

(余談) Ciliumの設定変更/更新について ▌基本的にはrollout restartで無停止更新できるはず・・・ ▌Map容量の変更はCT Mapの作り直しになるため、無停止ではできな かった o メンテナンスウィンドウ内等、かつアプリ的にも断(1分弱)が許容される 場合はOK o そうでない場合は1台ずつNode上のPodをdrainして更新 ▪ 1クラスタあたり~1週間ぐらいかかる場合もある 25

24.

Ciliumに関連する障害とその対応 1. kube-apiserverと通信できなくなった時cilium-agentが停止してしまう 2. Connection Tracking Tableが溢れそうになった 3. CiliumIdentityの氾濫によるPod作成失敗 4. CiliumEndpointが作成されず、Podが通信できなくなった 26

25.

Ciliumによる通信制御の仕組み 27

26.

Pod間通信とネットワークポリシー ▌ネットワークポリシーなし app2.default.svc app1.default.svc どちらの通信も成功する 28

27.

Pod間通信とネットワークポリシー ▌ネットワークポリシーあり Clientからapp1への通信 を拒否するポリシー Clientからapp1への通信 が拒否されてる 29

28.

通信制御に必要なCiliumのカスタムリソース CiliumIdentityを指してる ▌CiliumEndpoint o Podと1対1で作成される o 通信に必要なeBPF関連のリソースを制御 ▌CiliumIdentity 同じDeploymentに所属して いるのでラベルが同じ ⚫ Podに付与されたラベルの集合ごとに作成される ⚫ 制御対象を識別 ⚫ (単にIdentityと言っている場合、これを指します) 30

29.

Pod作成とCiliumEndpoint/CiliumIdentityの関係 31

30.

3. CiliumIdentityの氾濫によるPod作成失敗 32

31.

発生した障害 「その1」 1. ユニークなラベル集合を持ったJob Podが大量に作成された 2. CiliumIdentityが大量に作成された 3. ネットワークポリシーを管理するeBPFマップの使用率が100%になった 4. Pod作成の際にCiliumのCNI呼び出しが失敗するようになった 33

32.

発生した障害 「その2」 1. ユニークなラベル集合を持ったJob Podが大量に作成された 2. CiliumIdentityが大量に作成された 3. ネットワークポリシーを管理するeBPFマップの使用率が高くなった 4. cilium-agentの負荷が上昇した 5. Pod作成の際にCiliumのCNI呼び出しが時間制限で失敗するように なった 34

33.

eBPFマップ使用率が100%になった ※「その1」の障害時は観測できる情報が少なかったため、 「その2」の障害時のデータを主に紹介します eBPFマップ使用率が(100%にはならないけど)高くなった 35

34.

CiliumIdentityの大量生成 ▌Job Podは1Podごとにユニークなラベル集合になっていた Podの数分 CiliumIdentityが 生成される 36

35.

CiliumIdentityの大量生成 ▌当時のNecoでは5分ごとに約1000個のJob Podが作成されていた ▌Kubernetes1.27からJob Podに付くラベルが変更された(障害その2) ⚫ controller-uid → batch.kubernetes.io/controller-uid ⚫ job-name → batch.kubernetes.io/job-name k8s1.27適用 CiliumIdentityの時間あたりの作成数の推移 対策実施 37

36.

CiliumのカスタムリソースとeBPF CiliumIdentity毎にエントリが挿入される CiliumEndpointごとにeBPFプログラムと eBPFマップが作成される 38

37.

CiliumIdentityの増加とeBPFマップ使用率 CiliumIdentity 作成レート eBPFマップ使用率 0.8 CiliumIdentity生成レートとネットワークポリシー用eBPFマップ利用率の推移 39

38.

CiliumIdentity増加のPod作成への影響 ▌BPFマップ使用率が100%になった場合、エントリの挿入に失敗して Pod作成が失敗した ▌様々な要因によりcilium-agentの負荷が上昇し、Pod作成の遅延、 タイムアウトによる失敗が増加した 40

39.

対策 ▌CiliumIdentity生成に関わるラベルを制限する ⚫ Limiting Identity-Relevant Labels ▌「その1」の際の対策 「その1」の障害はk8s 1.27以前に発生 ⚫ controller-uid, job-nameを対象ラベルから除外する ⚫ BPFマップ使用率のメトリクスを収集する ▌「その2」の際の対策 ⚫ 対象ラベルをホワイトリスト形式にする 現在許可しているラベルたち 41

40.

対策結果 対策実施 CiliumIdentity 作成レート CiliumIdentity生成レートとeBPFマップ利用率の推移 BPFマップ使用率 42

41.

4. CiliumEndpointが作成されず、 Podが通信できなくなった 43

42.

発生した障害 1. あるPodが通信できない状態に陥っていた 2. そのPodの通信がネットワークポリシーにより拒否されていた 3. Podに対応するCiliumEndpointが存在していなかった 4. Podを再作成して、CiliumEndpointが正常に作成されて解消した 44

43.

調査 ドロップされた通信ログ 16777233は外部通信に割り当てられるIdentity X.X.X.Xが通信できないPodのアドレス ネットワークポリシーで拒否されてる 同一Deployment配下の別の正常なPodの通信ログ 同一Deployment配下のPod間でIdentityが食い違っている 45

44.

調査 eBPFマップに誤ったCiliumIdentityが登録されていた 同一Deployment配下の他のPodは正常に登録されていた 46

45.

調査 レプリカ数4のDeploymentに対して3つしかCiliumEndpointが存在しない 47

46.

CiliumEndpointとネットワークポリシー ▌CiliumEndpointを通じてCiliumIdentityを他のノードに伝搬する 48

47.

CiliumIdentityとeBPFとネットワークポリシー ▌正常な場合 IPアドレスからIdentityに 解決する 49

48.

CiliumIdentiyとeBPFとネットワークポリシー ▌CiliumEndpointがなく、CiliumIdentityがうまく伝搬しない場合 Identityを解決できないので 正常な通信を拒否してしまう 50

49.

調査(再掲) ドロップされた通信ログ 16777233は外部通信に割り当てられるIdentity 同一Deployment配下の別の正常なPodの通信ログ 同一Deployment配下のPod間でIdentityが食い違っている 51

50.

対策 ▌CiliumEndpointが存在しないPodを再起動する ⚫ CiliumEndpointはPod作成のタイミングで作成されるから ▌PodとCiliumEndpointの整合性を検査するツールを開発してアラートを 設定する ⚫ https://github.com/cybozu/neco-containers/tree/main/cep-checker 52

51.

まとめ 53

52.

障害一行サマリ 1. kube-apiserverと通信できなくなった時cilium-agentが停止してしまう ⚫ 様々な機能があるので意外な依存関係に注意! 2. Connection Tracking Tableが溢れそうになった ⚫ デフォルトのGC間隔は環境によっては長すぎる場合がある! 3. CiliumIdentityの氾濫によるPod作成失敗 ⚫ CiliumIdentityの生成に関わるラベル集合の設計が重要! 4. CiliumEndpointが作成されず、Podが通信できなくなった ⚫ 内部アーキテクチャを理解して適切な対処を迅速に実施する! 54

53.

Cilium運用のポイント ▌ 設定変更時は通信断に細心の注意を払う o eBPFの設定変更は要注意 ▌ 負荷が上昇しやすい条件を把握しておく o Connection Tracking o CiliumIdentity ▌ 内部アーキテクチャを理解する ▌ 最新の情報をチェックする 55

54.

まとめ ▌Ciliumは高度な通信制御を高パフォーマンスで提供してくれる ▌コミュニティがオープンで議論や開発が活発 ▌フラグや設定値のチューニングが難しい ▌運用に実装レベルでの挙動の把握が必要 これからもCilium運用に関する知見を共有していきます!! 56

55.

CiliumのeBPFマップサイズについて ▌bpf-map-dynamic-size-ratio o cilium-agentが各種eBPFマップのサイズをシステムのメモリから自動計算する o デフォルト有効で、デフォルト値は0.25% o 各eBPFマップのサイズに上限が設けられている ▪ TCP用のconntrackマップは16Mエントリが上限 ▌bpf-ct-global-tcp-max o 明示的にTCP用conntrackマップサイズを指定できる o Dynamic size ratioより優先される 58

56.

Conntrack GCの間隔 ▌GCの間隔は自動計算されている o デフォルトは10秒~12時間 o conntrack-gc-max-interval ▪ 自動計算の最大値を変更できる ▪ 1.14から使える o conntrack-gc-interval ▪ 固定値にもできる 59

57.

conntrackマップが一杯になった時の挙動 ▌BPF_MAP_TYPE_LRU_HASHを利用しているので、カーネルの レイヤでevictionされる o https://docs.ebpf.io/linux/maptype/BPF_MAP_TYPE_LRU_HASH/ 60

58.

ネットワークポリシー用eBPFマップサイズ ▌bpf-policy-map-max o ネットワークポリシー用のeBPFマップのサイズを指定できる 61