Contents
1. 前提条件と環境チェック
1‑1. CNI がポリシー対応であることを確認
| CNI | 推奨最低バージョン (2024‑06) | 確認コマンド例 |
|---|---|---|
| Calico | v3.26 以上(policyEnabled デフォルト true) |
bash\nkubectl get ds -n kube-system calico-node -o jsonpath="{.spec.template.spec.containers[0].image}"\n |
| Cilium | v1.13 以上(BPF が有効か必ず確認) |
bash\ncilium version\ncilium status --brief\n |
ポイント
- バージョンが古い場合は公式手順でアップグレードしてください。
- Calico はpolicyEnabled: trueがデフォルトですが、カスタム ConfigMap を使用している環境では明示的に確認が必要です。
1‑2. マネージドクラスタ側の NetworkPolicy 機能有効化
| プラットフォーム | 有効化チェックコマンド(2024‑06) |
|---|---|
| GKE (VPC‑Native) | bash\ngcloud container clusters describe $CLUSTER \\\n --format="json(networkConfig.networkPolicy.enabled)" |
| AKS | bash\naz aks show -g $RESOURCE_GROUP -n $CLUSTER \\\n --query "networkProfile.networkPolicy" -o tsv |
- GKE:
enabledがtrueの場合は NetworkPolicy コントローラが自動でデプロイされます。 - AKS:
azure(Azure ネイティブ)またはcalicoを選択していることを必ず確認してください。
1‑3. NamespaceSelector が未指定 の落とし穴
NetworkPolicy は同一 Namespace 内の Pod に対してだけ適用されます。
別 Namespace の Pod を対象にしたい場合は spec.podSelector と併せて spec.namespaceSelector を明示的に記述する必要があります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 例: dev Namespace の pod が prod Namespace の myapp にアクセスできるようにする apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: cross-ns-allow namespace: prod spec: podSelector: matchLabels: app: myapp policyTypes: [Ingress] ingress: - from: - namespaceSelector: matchLabels: env: dev # dev Namespace に付与したラベル podSelector: matchLabels: role: frontend |
注意:
namespaceSelectorを忘れるとポリシーが期待通りに機能せず、全トラフィックがデフォルト deny になるケースがあります。
2. 基本的な NetworkPolicy の作成・適用手順
2‑1. 最小構成サンプル(Ingress + Egress)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-app namespace: demo-ns spec: podSelector: matchLabels: app: myapp # ポリシー対象 Pod policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: role: frontend # 許可する送信元ラベル ports: - protocol: TCP port: 80 egress: - to: - ipBlock: cidr: 10.0.0.0/8 # 許可 CIDR ports: - protocol: TCP port: 443 |
適用コマンド
|
1 2 3 4 5 6 |
mkdir -p ~/np-demo && cat >~/np-demo/allow-app.yaml <<'EOF' # ← 上記 YAML を貼り付け EOF kubectl apply -f ~/np-demo/allow-app.yaml |
2‑2. リソースの確認
| コマンド | 主な目的 |
|---|---|
kubectl get netpol -n demo-ns |
作成済みポリシー一覧 |
kubectl describe netpol allow-app -n demo-ns |
Spec と Events を詳細にチェック |
kubectl get pods -n demo-ns --show-labels |
ラベルがポリシーと一致しているか確認 |
ポイント
describeのEventsにNetworkPolicyCreated以外のエラーが無ければ、CNI がオブジェクトを受理しています。
3. 接続テストで効果を検証する方法
3‑1. テスト用 Pod の準備(Namespace とラベル)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
kubectl create ns demo-ns # フロントエンド側 (許可) kubectl run busybox-frontend --image=busybox \ -n demo-ns --restart=Never --command -- sleep 3600 kubectl label pod/busybox-frontend role=frontend -n demo-ns # バックエンド側 (非許可) kubectl run busybox-backend --image=busybox \ -n demo-ns --restart=Never --command -- sleep 3600 kubectl label pod/busybox-backend role=backend -n demo-ns |
3‑2. Ingress(受信)テスト
| ケース | 実行コマンド | 期待結果 |
|---|---|---|
許可 (role=frontend) |
bash\nkubectl exec -n demo-ns busybox-frontend -- wget -qO- http://myapp.demo-ns.svc.cluster.local:80\n |
HTTP 200 が返る |
遮断 (role=backend) |
bash\nkubectl exec -n demo-ns busybox-backend -- wget -S -O- http://myapp.demo-ns.svc.cluster.local:80\n |
Connection timed out もしくは Failed to connect が出る |
3‑3. Egress(送信)テスト
|
1 2 3 4 |
# myapp Pod にシェルで入る(app=myapp ラベルが前提) MYAPP_POD=$(kubectl get pod -n demo-ns -l app=myapp -o jsonpath="{.items[0].metadata.name}") kubectl exec -n demo-ns -it $MYAPP_POD -- sh |
シェル内で以下を実行:
| 宛先 | コマンド例 | 期待結果 |
|---|---|---|
| 許可された CIDR (10.1.2.3) | wget https://10.1.2.3 |
成功(0 exit code) |
| 未許可外部 (www.google.com) | wget https://www.google.com |
タイムアウトまたは Connection refused |
検証のコツ:
kubectl logs -n kube-system <cni‑pod>で「policy drop」や「policy allow」のログが出ているか確認すると、ポリシー適用状態を二重チェックできます。
4. CNI プラグイン別トラブルシューティング
4‑1. Calico
| コマンド | 内容 |
|---|---|
calicoctl node status |
Node の健康状態、Felix 同期状況、ポリシー数を表示 |
kubectl logs -n kube-system -l k8s-app=calico-node --tail=100 | grep -i error |
エラーログ抽出 |
calicoctl get networkpolicy -o yaml |
クラスタ全体の NetworkPolicy を一覧取得 |
よくある失敗と対処
| 失敗要因 | 症状 | 解決策 |
|---|---|---|
| ラベル不一致 | describe は正しいが通信が遮断 |
Pod に付与したラベルを kubectl get pod -L <label> で再確認 |
| NamespaceSelector の未設定 | 別 Namespace の Pod が誤って許可/遮断 | 必要に応じて spec.namespaceSelector を追加 |
| Felix が BPF モードになっていない | ポリシーが無視され、全トラフィックが許可 | calicoctl node status で BPF: disabled と表示されたら felixConfiguration の bpfEnabled: true に変更 |
4‑2. Cilium
| コマンド | 内容 |
|---|---|
cilium status --brief |
BPF、CNI、Hubble が有効か一目で確認 |
cilium monitor --type policy,drop |
ポリシー判定(ALLOW/DENY)をリアルタイムで出力 |
cilium policy get -n demo-ns allow-app -o yaml |
特定ポリシーの詳細表示 |
よくある失敗と対処
| 失敗要因 | 症状 | 解決策 |
|---|---|---|
| IPBlock の CIDR 記述ミス | 想定外の通信が遮断/許可 | cilium policy get で ipBlock.cidr が正しいか確認 |
| BPF プログラム未ロード | 全トラフィックが許可状態になる | cilium status の bpf: enabled を必ずチェック |
| NamespaceSelector の省略 | 他 Namespace の Pod に影響が及ぶ | namespaceSelector を明示し、kubectl get netpol -A -o yaml | grep namespaceSelector で抜け漏れを検出 |
5. 可視化ツール・CLI 活用とベストプラクティス
5‑1. インタラクティブ CLI ― k9s
|
1 2 3 |
k9s # 起動 :np # NetworkPolicy ビューへジャンプ(ショートカット) |
- 一覧に
Namespace | Name | PolicyTypes | Ageが表示され、Enter でdescribe相当の詳細が即座に確認可能。 - 大規模クラスターではフィルタ (
/role=frontend) を活用すると便利です。
5‑2. ポリシー依存関係チェック ― np-check
|
1 2 3 |
go install github.com/np-guard/np-check@latest np-check --namespace demo-ns |
出力例:
|
1 2 3 |
[WARN] Unmatched selector: NetworkPolicy "allow-app" selects pods with label app=myapp, but no such pod exists. [INFO] All policies have at least one matching pod. |
- 未マッチングポリシー を早期に検出し、CI/CD パイプラインで自動化できます。
5‑3. 可視化 UI ― netpol‑visualizer
|
1 2 3 4 5 |
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/main/examples/netpol-visualizer.yaml # ローカルで UI にアクセス kubectl port-forward -n default svc/netpol-visualizer 8080:80 |
ブラウザ http://localhost:8080 でポリシーと Pod の関係が GraphViz ベースの図として表示され、「どのポリシーがどの Pod に影響しているか」 を一目で把握できます。
5‑4. ベストプラクティスまとめ
| 項目 | 推奨アクション |
|---|---|
| ラベル統制 | kubectl get pods -A --show-labels → ラベル命名規則(例: <app>/<role>)を全チームで統一 |
| デフォルト deny の明示化 | 必要最小限の Ingress/Egress だけ許可し、残りは暗黙的に遮断。policyTypes を忘れずに記載 |
| CI/CD でポリシー検証 | PR 時点で np-check と kube-score(NetworkPolicy 評価)を実行し、失敗したらマージ不可 |
| ログ・モニタリング自動化 | - Calico → CloudWatch / Stackdriver に calicoctl node status 出力を送信 - Cilium → Loki/Prometheus に cilium monitor のメトリクスを流す |
| 定期的な可視化レビュー | 週1回は k9s または netpol‑visualizer でポリシー全体像を確認し、不要になったルールは削除 |
| NamespaceSelector の必須化 | 複数 Namespace に跨る通信が必要な場合は必ず namespaceSelector を記述。未設定時は自動的に同一 Namespace 限定になることをドキュメントで周知 |
6. まとめ
- CNI とクラウド側の前提条件
- Calico ≥ v3.26、Cilium ≥ v1.13 を使用し、
policyEnabled:true(Calico)や BPF 有効(Cilium)を確認。 -
GKE は
networkPolicy.enabled: true、AKS はnetworkProfile.networkPolicy = azure|calicoが必須。 -
NetworkPolicy の作成・適用
-
最小構成 YAML を
kubectl apply -fでデプロイし、kubectl get/describeでリソースとイベントを検証。 -
効果の検証
-
busyboxPod で Ingress と Egress の「許可」・「遮断」シナリオを実行し、期待通りの結果が得られたら完了。 -
プラグイン別トラブルシューティング
- Calico:
calicoctl node statusとログでポリシー同期状態を確認。 -
Cilium:
cilium monitorでリアルタイム判定、BPF が有効か必ずチェック。 -
可視化と自動化
- k9s・np-check・netpol‑visualizer を組み合わせてポリシー全体像を把握し、CI/CD に
np-checkを組み込んで品質を維持。
これらの手順とツールを体系的に活用すれば、Kubernetes の NetworkPolicy が正しく機能しているかを自信を持って検証できるだけでなく、運用上のリスクも最小化できます。実務環境へ安全に導入し、インフラのセキュリティレベル向上にぜひ活かしてください。
参考リンク(2024‑06 時点)
| 項目 | URL |
|---|---|
| Kubernetes 公式 NetworkPolicy ドキュメント | https://kubernetes.io/docs/concepts/services-networking/network-policies/ |
| GKE ネットワークポリシーガイド(VPC‑Native) | https://cloud.google.com/kubernetes-engine/docs/how-to/network-policy |
| AKS ネットワークポリシードキュメント | https://learn.microsoft.com/azure/aks/use-network-policies |
| Calico Release Notes (v3.26) | https://github.com/projectcalico/calico/releases/tag/v3.26.0 |
| Cilium Release Notes (v1.13) | https://github.com/cilium/cilium/releases/tag/v1.13.0 |
| np-check GitHub リポジトリ | https://github.com/np-guard/np-check |
| netpol‑visualizer Manifest | https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/main/examples/netpol-visualizer.yaml |