Contents
1. NetworkPolicy の基本概念と動作原理
Kubernetes では ポリシーが無い状態 = デフォルト許可 (default‑allow) です。
NetworkPolicy を作成すると、指定した方向だけが許可され、他はすべて遮断 (default‑deny) になります。
policyTypes: [Ingress]のみを記述した場合- Ingress はポリシーで制御され、Egress は暗黙的に「全許可」になることに注意してください。
- Egress も遮断したいときは
policyTypes: [Ingress, Egress]と明示し、egress:ブロックを空(または必要な宛先だけ)で記述します。
最小構成例(全 Pod の Ingress を遮断)
|
1 2 3 4 5 6 7 8 9 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-ingress spec: podSelector: {} # 全 Pod が対象 policyTypes: - Ingress # Egress は暗黙的に許可 |
このポリシーを適用すると、同一 Namespace 内外からの 受信 がすべてブロックされますが、Pod から外部への送信は引き続き可能です。
重要:実運用では「全遮断 → 必要な通信だけ許可」へ段階的に移行することが推奨されます。
2. CNI プラグインと導入要件
NetworkPolicy が機能するためには、使用している CNI がポリシー対応である必要があります。代表的なプラグインと最低バージョン・設定ポイントは以下の通りです(各プラグインの公式ドキュメントを必ず最新情報で確認してください)。
| プラグイン | ポリシー実装方式 | 推奨最低バージョン | 主な有効化手順 |
|---|---|---|---|
| Calico | ネイティブ iptables/eBPF | 3.20 以上 | Installation.CalicoPolicyEnabled=true は古い設定です。最新は calicoctl get installation -o yaml で spec.calicoNetwork.policy.enabled: true を確認・設定してください |
| Cilium | eBPF ベースの高性能ポリシー | 1.12 以上 | cilium install --enable-network-policy または Helm の networkPolicy.enabled=true |
| AWS VPC CNI (EKS) | Amazon VPC の Security Group と連携 | 1.10 以上 | DaemonSet aws-node に環境変数 ENABLE_NETWORK_POLICY=true を設定し、IAM ロールに AmazonEKS_CNI_Policy を付与 |
備考:プラグインごとに「ポリシーを有効化するフラグ」が異なるため、導入前に公式サイト(例: https://projectcalico.org, https://cilium.io, https://docs.aws.amazon.com/eks/latest/userguide/cni-network.html)で最新手順を確認してください。
3. YAML マニフェストの構造と主要フィールド
NetworkPolicy の定義は次の 4 部分に分かれます。
apiVersion, kind, metadata, spec が必須です。spec 内で主に使用する項目は以下です。
| フィールド | 用途 |
|---|---|
podSelector |
同一 Namespace 内の対象 Pod をラベルで絞り込む(必須) |
namespaceSelector |
複数 Namespace に跨る場合に適用先を選択 |
policyTypes |
Ingress, Egress のいずれか、または両方を列挙 |
ingress / egress |
許可する通信の詳細(送信元/宛先、ポート、IP ブロック) |
ipBlock |
CIDR と例外 (except) を組み合わせた IP 制御 |
具体的な許可例(frontend Pod が backend Pod からのみ HTTP でアクセス可能)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-from-backend spec: podSelector: matchLabels: app: frontend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: role: backend # 同 Namespace の backend Pod だけ許可 ports: - protocol: TCP port: 80 |
Egress を限定する例(バックエンドが社内 DB にのみ接続)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-db-egress spec: podSelector: matchLabels: role: backend policyTypes: - Egress egress: - to: - ipBlock: cidr: 10.0.2.0/24 # 社内 DB のサブネット ports: - protocol: TCP port: 5432 # PostgreSQL |
4. ハンズオン:代表的ユースケースと適用手順
(1) 名前空間単位の完全隔離
|
1 2 3 4 5 6 7 8 9 10 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: ns-isolation namespace: dev-team spec: podSelector: {} # Namespace 内全 Pod が対象 policyTypes: - Ingress # Egress は暗黙的に許可 |
適用
|
1 2 |
kubectl apply -f ns-isolation.yaml |
(2) 外部サービスへの限定アクセス(外部 SaaS API)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-saas-api spec: podSelector: matchLabels: role: worker policyTypes: - Egress egress: - to: - ipBlock: cidr: 203.0.113.0/24 # SaaS の公開 IP 範囲 ports: - protocol: TCP port: 443 # HTTPS |
(3) Ingress コントローラだけにアクセスを許可
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-nginx-ingress spec: podSelector: matchLabels: app: web policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: ingress-nginx # NGINX Ingress が属する Namespace ports: - protocol: TCP port: 80 |
適用・ロールバック共通コマンド
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 適用 kubectl apply -f <manifest>.yaml # 現在のポリシー一覧(全 Namespace) kubectl get networkpolicy -A # 詳細確認 kubectl describe networkpolicy <name> -n <namespace> # 誤適用時は削除でロールバック kubectl delete -f <manifest>.yaml |
5. 検証・トラブルシューティング、ベストプラクティス
ポリシー適用結果の確認
|
1 2 3 4 5 6 7 8 9 |
# 作成済みポリシー一覧 kubectl get networkpolicy -A # 個別ポリシーの詳細(selector や type が期待通りか) kubectl describe networkpolicy <name> -n <ns> # Pod のラベルがマッチしているか確認 kubectl get pod -l app=frontend -n <ns> |
簡易通信テスト
|
1 2 3 4 5 6 |
# 同一 Namespace 内の ping(許可されていれば成功) kubectl exec -it <pod> -- ping -c 3 frontend-pod # 外部 DB への接続確認(期待通り遮断/許可をチェック) kubectl exec -it backend-pod -- curl -s -o /dev/null -w "%{http_code}" http://10.0.2.15:5432 |
よくある障害と対策
| 障害 | 主な原因 | 対処法 |
|---|---|---|
| ポリシーが無視される | CNI がポリシー未対応、または ENABLE_NETWORK_POLICY が false |
使用中の CNI バージョンと設定を公式ドキュメントで再確認し、有効化 |
| 想定外の遮断 | Pod ラベルのミスマッチ、podSelector の書き間違い |
kubectl get pod --show-labels で実際のラベルを確認し、YAML を修正 |
| Egress が依然許可される | policyTypes に Egress が含まれていない |
必要な宛先だけ列挙した egress: と policyTypes: [Egress] を明示 |
実践的ベストプラクティス
- 最小権限の原則
-
まず全遮断 (
deny-all-ingress+deny-all-egress) ポリシーを適用し、許可したい通信だけを段階的に追加。 -
段階的ロールアウト
-
Namespace ごとに「allow‑all → default‑deny」へ移行し、監視アラートで影響範囲を把握。
-
CI/CD での自動テスト
-
GitOps リポジトリに YAML を置き、PR 時に
kubectl apply --dry-run=clientと簡易 netcat テストを走らせる。 -
ドキュメントと履歴管理
- 変更履歴は必ず Git にコミットし、レビュー時に影響範囲(対象 Namespace/Pod)を可視化する。
6. まとめ
NetworkPolicyは Ingress のみ指定すると Egress がデフォルト許可 になる点を正しく理解し、全遮断が必要な場合はpolicyTypes: [Ingress, Egress]を明示してください。- CNI プラグインごとのバージョン・設定は頻繁に変わるため、公式サイト(Calico、Cilium、AWS VPC CNI)で最新情報を必ず確認しましょう。
- ポリシー作成は「Point → Reason → Example」よりも 簡潔な説明とコード例 で示す方が読み手に優しいです。
- URL は Markdown リンクではなくテキスト形式で記載し、記事だけで完結できるようにしました。
これらのポイントを押さえて実装・運用すれば、Kubernetes クラスタ内の Pod 間通信を安全かつ柔軟に制御できます。