アプリケーションのネットワーク ポリシーの構成

このチュートリアルでは、クラスタ ネットワーク ポリシーを使用することにより、どのポッドが着信ネットワーク トラフィックを受信するか、またどのポッドが発信トラフィックを送信できるかを制御する方法を示します。

ネットワーク ポリシーを使用すると、ポッド間の接続を制限できます。したがって、ネットワーク ポリシーを使用して妥協範囲を狭めることで、セキュリティが強化されます。

このページでは、GKE でネットワーク ポリシーを構成する方法について説明します。

ネットワーク ポリシーは、接続が許可されるかどうかを決定しますが、認証やセキュリティ保護トランスポート(たとえば SSL / TLS)などの高度な機能を提供するものではないことに注意してください。

目標

このチュートリアルでは、次のことを学びます。

  • ネットワーク ポリシーを適用してクラスタを作成する方法
  • ラベルを使用してポッドへの着信トラフィックを制限する方法
  • ラベルを使用してポッドからの発信トラフィックを制限する方法

始める前に

次の手順で Kubernetes Engine API を有効にします。
  1. Google Cloud Platform Console で Kubernetes Engine ページにアクセスします。
  2. プロジェクトを作成または選択します。
  3. API と関連サービスが有効になるのを待ちます。これには数分かかることがあります。
  4. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。

  • Kubernetes Engine クラスタを作成および削除するには、gcloud を使用します。gcloudGoogle Cloud SDK に含まれています。
  • kubectl は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes を管理するために使用されます。gcloud を使用して kubectl をインストールできます。
    gcloud components install kubectl

gcloud コマンドライン ツールのデフォルトを設定する

次のコマンドを実行してデフォルト値を設定しておくと、gcloud コマンドライン ツールでプロジェクト IDCompute Engine ゾーンの各オプションを入力する時間を節約できます。
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

ステップ 1: GKE を作成する

ネットワーク ポリシーを適用してコンテナ クラスタを作成するには、次のコマンドを実行します。

gcloud container clusters create test --enable-network-policy

ステップ 2: ポッドへの着信トラフィックを制限する

Kubernetes NetworkPolicy リソースにより、ポッドのネットワーク アクセス ポリシーを設定できます。NetworkPolicy オブジェクトには、次の情報が含まれます。

  • ネットワーク ポリシーの適用対象となるポッド。通常は、ラベルセレクタによって指定されます。

  • ネットワーク ポリシーの影響を受けるインターネット トラフィックのタイプ: 着信トラフィックの場合は Ingress、発信トラフィックの場合は Egress、あるいはその両方

  • Ingress ポリシーの場合、指定したポッドに接続できるポッド

  • 出力ポリシーの場合、指定したポッドが接続できる接続先ポッド。

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

kubectl run hello-web --labels app=hello \
  --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose

次に、hello-web ポッドへのトラフィックが app=foo ポッドから送られる場合にのみ許可されるように NetworkPolicy を設定する必要があります。このラベルがないポッドからの他の着信トラフィック、外部トラフィック、および他のネームスペース内のポッドからのトラフィックはブロックされます。

次の設定を hello-allow-from-foo.yaml に保存します。

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

このポリシーは、ラベル app=hello を持つポッドを選択し、ラベル app=foo のポッドからのトラフィックのみを許可する上りポリシーを指定します。

このポリシーをクラスタに適用するには、次のコマンドを実行します。

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

上りポリシーを検証する

まず、app=foo というラベルを使って一時ポッドを実行し、そのポッドでシェルを取得します。

kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t test-1

着信トラフィックが許可されることを確認するために、hello-web:8080 エンドポイントに対してリクエストを発行します。

/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world!
Version: 1.0.0
Hostname: hello-web-2258067535-vbx6z
/ # exit

ポッド app=foo から app=hello ポッドへのトラフィックが有効になっています。

次に、別のラベル(app=other)を使って一時ポッドを実行し、そのポッド内でシェルを取得します。

kubectl run -l app=other --image=alpine --restart=Never --rm -i -t test-1

同じリクエストを発行して、トラフィックが許可されないために要求がタイムアウトすることを観察した後、ポッドシェルを終了します。

/ # wget -qO- --timeout=2 http://hello-web:8080
wget: download timed out
/ # exit

ステップ 3: ポッドからの発信トラフィックを制限する

着信トラフィックと同じように、発信(下り)トラフィックを制限することができます。

ただし、hello-web などの内部ホスト名や、www.example.com などの外部ホスト名を照会できるようにするには、下りネットワーク ポリシーで DNS(ドメイン ネーム システム)解決を可能に必要があります。DNS トラフィックは、TCP プロトコルおよび UDP プロトコルを使用するポート 53 で発生します。

下りネットワーク ポリシーを実施するには、app=foo というラベルのポッドからの送信トラフィックを制御する NetworkPolicy をデプロイし、app=hello というラベルのポッドのみへのトラフィック、および DNS トラフィックを許可します。

次の設定を foo-allow-to-hello.yaml に保存し、それをクラスタに適用します。

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

このマニフェストは、次の 2 つの宛先を許可する、ラベル app=foo のポッドからの下りトラフィックを制御するネットワーク ポリシーを指定します。

  1. app=hello というラベルの、同じ名前空間内のポッド
  2. ポート 53(UDP および TCP)のクラスタポッドまたは外部エンドポイント

下りポリシーを検証する

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

kubectl run hello-web-2 --labels app=hello-2 \
  --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose

次に、app=foo というラベルの一時ポッドを実行して、コンテナ内でシェル プロンプトを取得します。

kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never test-3

そのポッドが hello-web:8080 への接続を確立できることを確認します。

/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world!
Version: 1.0.0
Hostname: hello-web-2258067535-vbx6z

ポッドが hello-web-2:8080 への接続を確立できないことを確認します。

/ # wget -qO- --timeout=2 http://hello-web-2:8080
wget: download timed out

ポッドが www.example.com などの外部ウェブサイトへの接続を確立できないことを確認し、ポッドシェルを終了します。

/ # wget -qO- --timeout=2 http://www.example.com
wget: download timed out
/ # exit

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

  1. コンテナ クラスタを削除する: コンテナ クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)を削除します。

    gcloud container clusters delete test

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のチュートリアル