TT Lab
はじめる
学ぶ 学習パス コース

CCA — Cilium認定アソシエイト

kube-proxyのないクラスタを宣言する

TT Labで続きを見る

目標

kube-proxyを置き換えるCiliumの設定をvaluesファイルで正確に宣言し、実際のワークロードとServiceでバックエンドが認識される過程を確認し、「本当にkube-proxyがないのか」を自分で証明するスクリプトを作ります。

なぜ重要なのか

kubeProxyReplacement: trueの1行で終わりそうに見えますが、現場ではそうはいきません。k8sServiceHostを抜くと、Ciliumが起動中にAPIサーバーを見つけられず、クラスター全体が立ち上がりません。また、既存のクラスターでkube-proxyを削除しながら切り替えると、ノードに残ったKUBE-チェーンがeBPFの経路と衝突します。そのため、実務の正攻法は最初からインストールしないことであり、それが実際に守られているかは、チェーンの数を数えて確認する必要があります。

このラボでは、その過程を3つに分けて身に付けます。valuesファイルの作成は「何を有効にするのか」を、実際のリソースのapplyは「ラベルとセレクターがどのようにバックエンドを作るのか」を、検証スクリプトは「どのように証明するのか」を扱います。3つ目が特に重要です。ドキュメントに書かれた機能と、このノードで実際に動作していることは、別の命題だからです。

Cilium Helm valuesとスクリプトは/root/cca-config/の下に作成し、Kubernetesの基本リソースは実際にapplyします。

ステップ

  1. ネームスペースcca-netを作成してください。
  2. /root/cca-config/cilium-values.yamlを作成し、最上位にkubeProxyReplacement: true、k8sServiceHost: 10.0.0.120、k8sServicePort: 6443、そしてipam.mode: kubernetesを書いてください。
  3. 同じファイルに続けて、routingMode: tunnel、tunnelProtocol: vxlan、bpf.masquerade: true、l7Proxy: true、encryption.enabled: true、encryption.type: wireguardを追加してください。
  4. ノードlab-node-0とlab-node-1にラベルcca.homelab/tier=gpuを、ノードlab-node-2にラベルcca.homelab/tier=cpuを付けてください。
  5. ネームスペースcca-netにDeployment webをレプリカ3でデプロイしてください。Podのラベルはapp=web、イメージはnginx:1.27-alpine、PodスペックのnodeSelectorはcca.homelab/tier: gpuです。
  6. 同じネームスペースにService webを作成してください。タイプはClusterIP、portは80、targetPortは8080、selectorはapp=webです。
  7. /root/cca-config/verify-kubeproxy-free.shを作成し、実行権限を付与してください。このスクリプトは、(1) kubectlでkube-systemのkube-proxy Podの数を数え、(2) iptables-saveの出力からKUBE-チェーンの数を数え、(3) ciliumの状態でKubeProxyReplacementの値を確認する必要があります。数が0でなければ、メッセージを出力してexit 1で終了させてください。

参考

ラボ用のネームスペースを作成する

ネームスペースcca-netを作成してください。

最も単純な最初のステップです。名前だけを正確に合わせてください。

kube-proxy置き換えの中核となる値を書く

/root/cca-config/cilium-values.yamlを作成し、最上位にkubeProxyReplacement: true、k8sServiceHost: 10.0.0.120、k8sServicePort: 6443、そしてipam.mode: kubernetesを書いてください。

kube-proxyがなければ、APIサーバーのVIPを解決する主体はCilium自身ですが、ブートストラップの時点ではまだ起動していません。そのため、実際のアドレスを別途伝える必要があります。IPAMは、ノードのPodCIDRをそのまま使うモードを選んでください。

データパスのオプションを埋める

同じファイルに続けて、routingMode: tunnel、tunnelProtocol: vxlan、bpf.masquerade: true、l7Proxy: true、encryption.enabled: true、encryption.type: wireguardを追加してください。

同じファイルに続けて書きます。アンダーレイがPodCIDRの経路を知らないホームラボなのでカプセル化が必要で、SNATもiptablesではなくeBPFに任せる必要があります。HTTPメソッド単位のポリシーを使うには、有効にしなければならないスイッチがもう1つあります。

ノードに性能区分のラベルを付ける

ノードlab-node-0とlab-node-1にラベルcca.homelab/tier=gpuを、ノードlab-node-2にラベルcca.homelab/tier=cpuを付けてください。

Kubernetesから見ると、すべてのGPUはただのGPU 1個です。意味のある配置をするには、人間がラベルで意味を埋め込む必要があります。ラベルのキーにスラッシュが含まれている点に注意してください。

配置制約を付けたワークロードをデプロイする

ネームスペースcca-netにDeployment webをレプリカ3でデプロイしてください。Podのラベルはapp=web、イメージはnginx:1.27-alpine、PodスペックのnodeSelectorはcca.homelab/tier: gpuです。

PodテンプレートにnodeSelectorを入れます。前のステップで付けたラベルのキーと値が正確に同じである必要があり、食い違うとPodはPendingのままになります。

Serviceでまとめてバックエンドを確認する

同じネームスペースにService webを作成してください。タイプはClusterIP、portは80、targetPortは8080、selectorはapp=webです。

Serviceのポートとコンテナのポートは異なることがあります。selectorがPodのラベルと食い違うと、Serviceは作成されますが、バックエンドが0個になります。この状態が、kube-proxyでもeBPFでもトラフィックが届かない最も一般的な原因です。

検証スクリプトを作成する

/root/cca-config/verify-kubeproxy-free.shを作成し、実行権限を付与してください。このスクリプトは、(1) kubectlでkube-systemのkube-proxy Podの数を数え、(2) iptables-saveの出力からKUBE-チェーンの数を数え、(3) ciliumの状態でKubeProxyReplacementの値を確認する必要があります。数が0でなければ、メッセージを出力してexit 1で終了させてください。

主張ではなく、計測でなければなりません。kube-proxy Podの数とノードのKUBE-チェーンの数を数えて0であることを確認し、Cilium側の状態もあわせて確認する必要があります。失敗したら0以外の終了コードを返し、ファイルに実行権限も付与してください。