From 8241812d8439a1d712ecbcb92cf34dc2318d1552 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 16:20:40 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20kube-vip=E7=92=B0=E5=A2=83=E3=81=A7?= =?UTF-8?q?=E3=81=AE=E5=AE=9FIP=E5=96=AA=E5=A4=B1=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E3=81=A8=E5=85=B1=E6=9C=89Ingress=20Controller=E7=A7=BB?= =?UTF-8?q?=E8=A1=8C=E6=89=8B=E9=A0=86=E3=82=92=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mikoto-wordpress-nginxの調査で、type: ClusterIP + kube-vipアノテーション による手動VIP付与構成では、kube-vip自体がTCP接続をプロキシするため externalTrafficPolicyを設定しても実クライアントIPが失われることが判明。 共有Ingress Controller(Cilium組み込み等)へ移行する場合の具体的な values設定とhelm upgradeコマンド例をREADMEに追加。 クラスタ構成の調査結果をCLAUDE.mdに記録。 --- CLAUDE.md | 10 ++++++++++ README.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 32a9ff0..30d12e3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,6 +26,16 @@ WordPress本体はイメージ内蔵のもの(`docker.io/wordpress:-fpm-a 3. **Commit メッセージに Claude クレジット(Co-Authored-By 等)を追記することは禁止。** `user.name = Claude` でコミットされるため、ユーザー名で判別可能。 4. `git pull` で取り込まれた変更は必ず尊重し、revert して push することは禁止(既存の共通ルールと同じ)。 +## クラスタ構成メモ(実運用環境) + +- ノード: `cpi11`(control-plane, 192.168.9.9/物理IF)、`wpi21`/`wpi22`/`wpi23`(worker)。全てRaspberry Pi(Ubuntu 25.04)。 +- CNI: **Cilium**(kube-proxyなし、eBPFベース)。`cilium-envoy` Podが動作しており、Cilium組み込みIngress Controller(Envoyベース)が利用可能。 +- Pod CIDR: `10.0.0.0/8`系、ノードごとに `/24` を割り当て(例: cpi11→`10.0.0.0/24`、wpi22→`10.0.1.0/24`、wpi21→`10.0.2.0/24`、wpi23→`10.0.3.0/24`)。 +- 外部公開: **kube-vip**(ARP方式、静的Pod `kube-vip-cpi11`)。物理ルーターのグローバルIP配下、`192.168.9.0/24` セグメント内でVIPを払い出す。このセグメントはルーターがLAN機器(スマホ/PC等)にDHCP払い出しする範囲と重複しないよう、ルーター側で範囲を絞って共存させている。**IPが希少なため濫用できない。** +- 各WordPress/PHPFPMリリースは現状、`service.type: ClusterIP` + `kube-vip.io/loadbalancerIPs`/`kube-vip.io/vipHost` アノテーションを**Helm管理外で手動付与**し、リリースごとに個別のVIPを得る運用になっている(本チャートの `templates/service.yaml` にはannotationsのテンプレート化自体が存在しないため)。 + - **既知の問題**: この構成では、kube-vipがL2 ARP応答に加えて自前でTCPコネクションをプロキシしてしまうため、`externalTrafficPolicy`(LoadBalancer/NodePort専用でありClusterIPには無効という制約とは別に、そもそもkube-vipの時点で)実クライアントIPが失われる。詳細はREADME.mdの「kube-vip等でグローバルIP/VIPが限られている環境での実IP取得(共有Ingress Controller構成)」を参照。 + - 今後、実IP取得のためCilium組み込みIngress Controller(またはingress-nginx)へ移行する方針で合意済み(2026-08-08時点、ユーザーが選択)。ただし全リリース(wordpress-nginx系だけでなくphpfpm系も含む)の移行が必要な大掛かりな作業のため、本セッションではWordPressチャート側の対応(`ingress.yaml`/`forwardRealIP`は既存機能で対応済み、README migration手順を追記)のみ実施。実際のCilium Ingress有効化・各リリースのhelm upgradeはユーザー側の作業。 + ## チャート改修履歴 ### 実IP取得の修正 + SMTP経由メール送信の追加(2026-08-08, v7.0.2-a) diff --git a/README.md b/README.md index 51687a3..22738ae 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ helm upgrade --install my-wordpress . \ - **注意**: `Local` にすると、リクエストを受けたノードにPodが存在しない場合はそのノードでの接続が失敗します。MetalLB L2モードなど、Podが存在するノードにのみトラフィックが向く構成と組み合わせて使用してください(複数ノードにPodを分散させることを推奨)。 - `service.type: ClusterIP` の場合、`externalTrafficPolicy` は無視されます(Kubernetes仕様上ClusterIPには適用不可のため)。 +- **kube-vip(ARP方式)でServiceに直接VIPを払い出している場合は要注意**: kube-vipはL2 ARP応答に加えて自前でTCP接続をプロキシする実装のため、`externalTrafficPolicy: Local` を設定してもkube-vipの時点で送信元IPが失われ、効果がありません(`type: ClusterIP` + kube-vipアノテーションによる手動VIP付与構成は特に該当します)。この場合は下記「kube-vip等でグローバルIP/VIPが限られている環境での実IP取得」の共有Ingress Controller構成を参照してください。 `nginx.forwardRealIP` は、Ingress ControllerやCDN(Cloudflareなど)、外部LBのように **X-Forwarded-For ヘッダーを付与するリバースプロキシを前段に置く場合にのみ**有効にしてください。本チャートのデフォルト構成(Service直下にPodがぶら下がる構成)ではX-Forwarded-Forを付与する層が存在しないため、`forwardRealIP` を有効にしても効果はなく、`service.externalTrafficPolicy: Local` のみで実IPが取得できます。 @@ -354,6 +355,43 @@ ingress: EOF ``` +### kube-vip等でグローバルIP/VIPが限られている環境での実IP取得(共有Ingress Controller構成) + +kube-vip(ARP方式)でVIPを払い出す構成の場合、各Serviceを個別に `type: LoadBalancer`(またはClusterIP+kube-vipアノテーションの手動払い出し)にすると、kube-vipが自前でTCP接続をプロキシする関係上、Nginxに到達する時点で送信元IPが失われ、`nginx.forwardRealIP` を有効にしても実IPは取得できません(kube-vipはL2 ARP+自前プロキシであり、X-Forwarded-Forを付与するリバースプロキシではないため)。 + +これを避けつつ、限られたIP/VIPプールの消費も抑えたい場合は、**Ingress Controllerを1つだけLoadBalancer公開し、各WordPress/PHPFPMリリースはClusterIPのままIngress経由でぶら下げる**構成を推奨します。外部消費IPはIngress Controllerの1個のみに集約され、Ingress ControllerがX-Forwarded-Forを正しく付与するため、本チャート既存の `nginx.forwardRealIP` がそのまま機能します。 + +**Ingress Controllerの選択**: 既にCilium CNIを使用している場合(`cilium-envoy` Podが動作している環境)は、追加コンポーネントなしでCilium組み込みのIngress Controllerを有効化できます。 + +```bash +# Cilium組み込みIngress Controllerが有効か確認 +kubectl get cm -n kube-system cilium-config -o yaml | grep -i ingress-controller-enabled + +# 未設定の場合、Ciliumをupgradeして有効化(既存のCilium Helm valuesに追加) +helm upgrade cilium cilium/cilium -n kube-system --reuse-values \ + --set ingressController.enabled=true \ + --set ingressController.loadbalancerMode=shared \ + --set ingressController.service.type=LoadBalancer \ + --set ingressController.service.externalTrafficPolicy=Local +``` + +Cilium Ingressを使わない場合は `ingress-nginx` 等の一般的なIngress Controllerでも構いません。その場合もController自体のServiceに `externalTrafficPolicy: Local` を設定し、kube-vipでVIPを1つだけ払い出してください。 + +**各リリースの移行例**(`mikoto-wordpress-nginx` の場合): + +```bash +helm upgrade mikoto . -n website \ + --set service.type=ClusterIP \ + --set ingress.enabled=true \ + --set ingress.className=cilium \ + --set ingress.hostname=mikoto.example.com \ + --set nginx.forwardRealIP.enabled=true +``` + +移行後は、これまで手動で付与していた `kube-vip.io/loadbalancerIPs` 等のServiceアノテーションは不要になります(Helm管理外のアノテーションのため、`kubectl annotate kube-vip.io/loadbalancerIPs- kube-vip.io/vipHost-` 等で削除してください)。DNS(またはルーターの名前解決)側で各ホスト名をIngress ControllerのVIP 1個に向ける設定も必要です。 + +`nginx.forwardRealIP.trustedProxies` のデフォルトには `10.0.0.0/8` が含まれているため、Cilium/Flannel等のPod CIDRがこの範囲内であれば追加設定は不要です。異なるPod CIDRを使用している場合は values.yaml で調整してください。 + ### リソース制限のカスタマイズ ```bash