このチュートリアルでは、クラスタ ネットワーク ポリシーを使用することにより、どの Pod が着信ネットワーク トラフィックを受信するか、またどの Pod が発信トラフィックを送信できるかを制御する方法を示します。詳細については、クラスタ ネットワーク ポリシーの作成をご覧ください。
ネットワーク ポリシーを使用すると、Pod 間の接続を制限できます。したがって、ネットワーク ポリシーを使用して妥協範囲を狭めることで、セキュリティが強化されます。
ネットワーク ポリシーは、接続が許可されるかどうかを決定しますが、認可やセキュリティ保護トランスポート(たとえば SSL / TLS)などの高度な機能を提供するものではないことに注意してください。
目標
このチュートリアルでは、次のことを学びます。- ネットワーク ポリシーを適用してクラスタを作成する方法
- ラベルを使用して Pod への着信トラフィックを制限する方法
- ラベルを使用して Pod からの発信トラフィックを制限する方法
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
次の手順で Kubernetes Engine API を有効にします。- Google Cloud コンソールの Kubernetes Engine ページにアクセスします。
- プロジェクトを作成または選択します。
- API と関連サービスが有効になるのを待ちます。 これには数分かかることがあります。
-
Make sure that billing is enabled for your Google Cloud project.
このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。
-
gcloud
は、Kubernetes Engine クラスタの作成と削除に使用されます。gcloud
はgcloud
CLI に含まれています。 -
kubectl
は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes の管理に使用されます。gcloud
を使用してkubectl
をインストールできます。gcloud components install kubectl
GitHub からサンプルコードのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/networking/network-policies
gcloud
コマンドライン ツールのデフォルト値を設定する
次のようにしてデフォルト値を設定しておくと、gcloud
コマンドライン ツールでプロジェクト ID および Compute Engine ゾーン オプションを入力する時間が節約されます。
gcloud config set project project-id gcloud config set compute/zone compute-zone
ネットワーク ポリシーを適用した GKE クラスタを作成する
ネットワーク ポリシーを適用してコンテナ クラスタを作成するには、次のコマンドを実行します。
gcloud container clusters create test --enable-network-policy
Pod への着信トラフィックを制限する
Kubernetes NetworkPolicy
リソースにより、Pod のネットワーク アクセス ポリシーを構成できます。NetworkPolicy
オブジェクトには次の情報が含まれます。
ネットワーク ポリシーの適用対象となる Pod。通常は、ラベルセレクタによって指定されます。
ネットワーク ポリシーの影響を受けるトラフィックのタイプ: 着信トラフィックの場合は Ingress、発信トラフィックの場合は Egress、あるいはその両方
Ingress ポリシーの場合、指定したポッドに接続できるポッド
Egress ポリシーの場合、指定した Pod が接続できる接続先 Pod
まず、ラベル 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
次に、hello-web
Pod へのトラフィックが app=foo
Pod から送られる場合にのみ許可されるように NetworkPolicy
を構成します。このラベルがない Pod からの他の着信トラフィック、外部トラフィック、他の Namespace 内の Pod からのトラフィックはブロックされます。
次のマニフェストでは、ラベルが app=hello
の Pod を選択し、ラベルが app=foo
の Pod からのトラフィックのみを許可する Ingress ポリシーを指定しています。
このポリシーをクラスタに適用するには、次のコマンドを実行します。
kubectl apply -f hello-allow-from-foo.yaml
上り(内向き)ポリシーを検証する
まず、app=foo
というラベルを使って一時 Pod を実行し、その Pod でシェルを取得します。
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
Pod app=foo
から app=hello
Pod へのトラフィックが有効になっています。
次に、別のラベル(app=other
)を使って一時 Pod を実行し、その Pod 内でシェルを取得します。
kubectl run -l app=other --image=alpine --restart=Never --rm -i -t test-1
同じリクエストを発行して、トラフィックが許可されないために要求がタイムアウトすることを観察した後、Pod シェルを終了します。
/ # wget -qO- --timeout=2 http://hello-web:8080
wget: download timed out / # exit
Pod からの発信トラフィックを制限する
着信トラフィックと同じように、発信トラフィックを制限できます。
ただし、hello-web
などの内部ホスト名や、www.example.com
などの外部ホスト名を照会できるようにするには、下り(外向き)ネットワーク ポリシーで DNS(ドメイン ネーム システム)解決を可能に必要があります。DNS トラフィックは、TCP プロトコルおよび UDP プロトコルを使用するポート 53 で発生します。
下り(外向き)ネットワーク ポリシーを有効にするには、app=foo
というラベルの Pod からの送信トラフィックを制御する NetworkPolicy
をデプロイし、DNS トラフィックに加えて、app=hello
というラベルの Pod へのトラフィックのみを許可します。
次のマニフェストは、次の 2 つの宛先を許可する、ラベルが app=foo
の Pod からの下り(外向き)トラフィックを制御するネットワーク ポリシーを指定します。
app=hello
というラベルの、同じ Namespace 内の Pod- ポート 53(UDP および TCP)のクラスタ Pod または外部エンドポイント
このポリシーをクラスタに適用するには、次のコマンドを実行します。
kubectl apply -f foo-allow-to-hello.yaml
下り(外向き)ポリシーを検証する
まず、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
次に、app=foo
というラベルの一時 Pod を実行し、コンテナ内でシェルを開きます。
kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never test-3
その Pod が hello-web:8080
への接続を確立できることを確認します。
/ # wget -qO- --timeout=2 http://hello-web:8080
Hello, world!
Version: 1.0.0
Hostname: hello-web-2258067535-vbx6z
Pod が hello-web-2:8080
への接続を確立できないことを確認します。
/ # wget -qO- --timeout=2 http://hello-web-2:8080
wget: download timed out
Pod が www.example.com
などの外部ウェブサイトへの接続を確立できないことを確認し、Pod シェルを終了します。
/ # wget -qO- --timeout=2 http://www.example.com
wget: download timed out
/ # exit
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
コンテナ クラスタを削除する: コンテナ クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)を削除します。
gcloud container clusters delete test