ネットワーク ポリシーを構成する

このページでは、クラスタ ネットワーク ポリシーを使用して、Pod が着信(または上り(内向き))ネットワーク トラフィックを受信できるかどうか、および発信(または下り(外向き))トラフィックを送信できるかどうかを制御する方法について説明します。

ネットワーク ポリシーを使用すると、Pod オブジェクト間の接続を制限できるため、攻撃を受けるリスクを低減できます。

ネットワーク ポリシーは、OSI モデルのレイヤ 3 またはレイヤ 4 のファイアウォールとして機能します。承認や暗号化などの追加機能はありません。

Pod オブジェクトへの受信トラフィックを制限する

NetworkPolicy オブジェクトを使用すると、Pod のネットワーク アクセス ポリシーを構成できます。NetworkPolicy オブジェクトには次の情報が含まれます。

  • ポリシーが適用される Pod オブジェクト。Pod オブジェクトと Workload は、ラベルとセレクタで定義します。

  • ネットワーク ポリシーの影響を受けるトラフィックのタイプ: 着信トラフィックの場合は上り(内向き)、発信トラフィックの場合は下り(外向き)、あるいはその両方。

  • 上り(内向き)ポリシーの場合、指定した Pod オブジェクトに接続できる Pod オブジェクト。

  • 下り(外向き)ポリシーの場合、指定した Pod オブジェクトが接続できる接続先 Pod オブジェクト。

受信トラフィック制限の例

このセクションでは、サンプル アプリケーションで受信トラフィックの制限を作成する方法について説明します。独自のアプリケーション環境に合わせてこの例を変更します。

  1. ラベル app=hello のウェブサーバー アプリケーションを実行し、クラスタ内でそれを内部公開します。

    kubectl run hello-web --labels app=hello \
        --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 \
        --port 8080 --expose
    
  2. hello-web Pod へのトラフィックを、app=foo Pod オブジェクトからのみ許可するように NetworkPolicy を構成します。GKE on Azure により、このラベルがない Pod オブジェクトからの受信トラフィック、外部トラフィック、別の Namespace 内の Pod オブジェクトからのトラフィックはブロックされます。

    次のマニフェストでは、ラベルが app=hello の Pod オブジェクトを選択し、ラベルが app=foo の Pod オブジェクトからのトラフィックのみを許可する上り(内向き)ポリシーを指定しています。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: hello-allow-from-foo
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: hello
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: foo
  3. このポリシーをクラスタに適用します。

    kubectl apply -f hello-allow-from-foo.yaml
    

上り(内向き)ポリシーを確認する

  1. app=foo というラベルを使って一時 Pod を実行します。受信トラフィックが許可されていることを確認するために、hello-web:8080 エンドポイントにリクエストを送信します。

    kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t foo-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    Pod app=foo から app=hello Pod オブジェクトへのトラフィックが有効になっている場合、出力は次のようになります。

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  2. 別のラベル(app=other)を使用して一時 Pod を実行し、同じリクエストを行って、トラフィックが許可されていないことを確認します。

    kubectl run -l app=other --image=alpine --restart=Never --rm -i -t other-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    出力で、接続がレスポンスを受信していないことがわかります。

    wget: download timed out
    

Pod オブジェクトからの送信トラフィックを制限する

着信トラフィックと同じように、発信トラフィックを制限できます。

ただし、hello-web などの内部ホスト名や、www.example.com などの外部ホスト名をクエリするには、TCP プロトコルと UDP プロトコルを使用するポート 53 で DNS トラフィックを許可する下り(外向き)ポリシーを作成する必要があります。

下り(外向き)ネットワーク ポリシーを有効にするには、app=foo というラベルの Pod オブジェクトからのアウトバンド トラフィックを制御する NetworkPolicy をデプロイし、app=hello というラベルの Pod オブジェクトへのトラフィックと DNS トラフィックのみを許可します。

次のマニフェストでは、NetworkPolicy を指定して、次の 2 つの宛先を許可する、ラベル app=foo の Pod オブジェクトからの下り(外向き)トラフィックを制御します。

  1. app=hello というラベルの、同じ名前空間内の Pod オブジェクト
  2. ポート 53(UDP および TCP)の内部エンドポイントまたは外部エンドポイント
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: foo-allow-to-hello
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: foo
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: hello
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP

このポリシーをクラスタに適用します。

kubectl apply -f foo-allow-to-hello.yaml

下り(外向き)ポリシーを検証する

  1. まず、hello-web-2 という新しいウェブ アプリケーションをデプロイし、クラスタ内でそれを内部公開します。

    kubectl run hello-web-2 --labels app=hello-2 \
      --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
    
  2. app=foo というラベルの一時 Pod を実行し、その Pod が hello-web:8080 への接続を確立できることを確認します。

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
      -- wget -qO- --timeout=2 http://hello-web:8080
    

    Pod は、次のリクエストに応答します。

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  3. Pod が hello-web-2:8080 への接続を確立できないことを確認します。

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://hello-web-2:8080
    

    出力で、接続がレスポンスを受信していないことがわかります。

    wget: download timed out
    
  4. Pod が、外部ウェブサイト(www.example.com など)への接続を確立できないことを確認します。

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://www.example.com
    

    出力で、接続がレスポンスを受信していないことがわかります。

    wget: download timed out
    

クリーンアップ

このチュートリアルで作成したリソースを削除するには、次のコマンドを実行します。

kubectl delete pods --labels app=hello-2
kubectl delete pods --labels app=hello
kubectl delete -f foo-allow-to-hello.yaml
kubectl delete -f hello-allow-from-foo.yaml

次のステップ