arrow_back

Google Kubernetes Engine でのネットワーク ポリシーの使用方法

参加 ログイン
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

Google Kubernetes Engine でのネットワーク ポリシーの使用方法

Lab 1時間 universal_currency_alt クレジット: 1 show_chart 入門
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

GSP480

Google Cloud セルフペース ラボ

概要

このラボでは、ネットワーク通信に詳細な制限を適用して、Kubernetes Engine のセキュリティを高める方法について説明します。

最小権限の原則は、重要なシステムを障害や悪意のある行為からより強固に保護するうえで、重要な設計上の考慮事項として広く知られています。この原則では、すべてのコンポーネントには、正当な目的に必要な情報とリソースのみに絞ってアクセス権を付与します。このドキュメントでは、Kubernetes Engine のネットワーク層内に最小権限の原則を実装する方法について説明します。

ネットワーク接続は、Kubernetes Engine インフラストラクチャの 2 つの層で制限できます。最初の詳細度の低いメカニズムは、ネットワーク、サブネットワーク、ホストレベルでのファイアウォール ルールの適用です。これらのルールは、Kubernetes Engine の外部で、VPC レベルで適用されます。

ファイアウォール ルールは強固なセキュリティ保護機構ですが、Kubernetes ではネットワーク ポリシーを使用して、より詳細なルールを定義できます。ネットワーク ポリシーは、クラスタ内通信を制限するために使用されます。ネットワーク ポリシーは、ホストのネットワーク Namespace に接続されている Pod には適用されません。

このラボでは、限定公開の Kubernetes Engine クラスタと、そのクラスタへのアクセスに使用する踏み台インスタンスをプロビジョニングします。踏み台インスタンスは、クラスタへのアクセス権を持つ単一のホストを提供します。このホストを限定公開の Kubernetes ネットワークと組み合わせて使用することで、クラスタが一般のインターネットの悪意のある行為にさらされないようにします。踏み台は、ユーザーにクラウド ネットワークへの VPN アクセスがない場合に特に役立ちます。

クラスタ内には、シンプルな HTTP サーバーと 2 つのクライアント Pod がプロビジョニングされます。ネットワーク ポリシーとラベル付けを使用して、クライアント Pod の 1 つからの接続のみを許可する方法について説明します。

このラボは、GKE Binary Authorization に関する理解を深めていただくために GKE Helmsman のエンジニアによって作成されました。デモは、Cloud Shell で gsutil cp -r gs://spls/gke-binary-auth/* . cd gke-binary-auth-demo コマンドを実行してデモを確認できます。アセットにぜひ貢献していただければ幸いです。

アーキテクチャ

Dataplane V2 を使用して、限定公開で Standard モードの Kubernetes クラスタを定義します。Dataplane V2 はデフォルトで使用できるネットワーク ポリシーです。

クラスタが限定公開なので、インターネットからは API にもワーカーノードにもアクセスできません。代わりに、踏み台インスタンスを定義し、ファイアウォール ルールを使用して踏み台インスタンスにアクセスできるようにします。踏み台の IP アドレスは、クラスタの承認済みネットワークとして定義され、API へのアクセス権が付与されます。

クラスタ内で、次の 3 つのワークロードをプロビジョニングします。

  1. hello-server: これは、内部でアクセス可能なエンドポイントを持つ、シンプルな HTTP サーバーです。
  2. hello-client-allowed: これは、hello-server へのアクセスを繰り返し試行する単一の Pod です。Pod には、ネットワーク ポリシーによって hello-server への接続が許可されることを示すラベルが付けられます。
  3. hello-client-blocked: これは hello-client-allowed と同じコードを実行しますが、Pod には、ネットワーク ポリシーによって hello-server への接続が許可されないことを示すラベルが付けられます。

Kubernetes クラスタの図

設定と要件

[ラボを開始] ボタンをクリックする前に

こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、Google Cloud のリソースを利用できる時間を示しています。

このハンズオンラボでは、シミュレーションやデモ環境ではなく、実際のクラウド環境を使ってご自身でラボのアクティビティを行うことができます。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。

このラボを完了するためには、下記が必要です。

  • 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。
  • ラボを完了するために十分な時間を確保してください。ラボをいったん開始すると一時停止することはできません。
注: すでに個人の Google Cloud アカウントやプロジェクトをお持ちの場合でも、このラボでは使用しないでください。アカウントへの追加料金が発生する可能性があります。

ラボを開始して Google Cloud コンソールにログインする方法

  1. [ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。 左側の [ラボの詳細] パネルには、以下が表示されます。

    • [Google コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google コンソールを開く] をクリックします。 ラボでリソースが起動し、別のタブで [ログイン] ページが表示されます。

    ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。

    注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
  3. 必要に応じて、[ラボの詳細] パネルから [ユーザー名] をコピーして [ログイン] ダイアログに貼り付けます。[次へ] をクリックします。

  4. [ラボの詳細] パネルから [パスワード] をコピーして [ようこそ] ダイアログに貼り付けます。[次へ] をクリックします。

    重要: 認証情報は左側のパネルに表示されたものを使用してください。Google Cloud Skills Boost の認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  5. その後次のように進みます。

    • 利用規約に同意してください。
    • 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
    • 無料トライアルには登録しないでください。

その後このタブで Cloud Console が開きます。

注: 左上にある [ナビゲーション メニュー] をクリックすると、Google Cloud のプロダクトやサービスのリストが含まれるメニューが表示されます。 ナビゲーション メニュー アイコン

Cloud Shell をアクティブにする

Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。

  1. Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン 「Cloud Shell をアクティブにする」アイコン をクリックします。

接続した時点で認証が完了しており、プロジェクトに各自の PROJECT_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。

Your Cloud Platform project in this session is set to YOUR_PROJECT_ID

gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。

  1. (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
  1. [承認] をクリックします。

  2. 出力は次のようになります。

出力:

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project

出力:

[core] project = <project_ID>

出力例:

[core] project = qwiklabs-gcp-44776a13dea667a6 注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。

デモのクローンを作成する

  1. Cloud Storage バケットから、このラボ演習に必要なリソースをコピーします。
gsutil cp -r gs://spls/gsp480/gke-network-policy-demo .
  1. このデモ用のディレクトリに移動します。
cd gke-network-policy-demo
  1. デモファイルを実行可能にします。
chmod -R 755 *

タスク 1. ラボの設定

まず、Google Cloud リージョンとゾーンを設定します。

  1. Google Cloud リージョンを設定します。
gcloud config set compute/region "{{{project_0.default_region|placeholder}}}"
  1. Google Cloud ゾーンを設定します。 gcloud config set compute/zone "{{{project_0.default_zone|placeholder}}}"

このラボでは以下の Google Cloud サービス API を使用します。これらはすでに有効になっています。

  • compute.googleapis.com
  • container.googleapis.com
  • cloudbuild.googleapis.com

また、Terraform の構成では 3 つのパラメータを使用して、Kubernetes Engine クラスタを作成する場所を指定します。

  • project ID
  • region
  • zone

わかりやすくするため、これらのパラメータは terraform ディレクトリ内の terraform.tfvars というファイルに指定されます。

  1. 適切な API を有効にし、gcloud のデフォルトに基づいて terraform/terraform.tfvars ファイルを生成するために、次のコマンドを実行します。
make setup-project
  1. 確認を求められたら「y」と入力します。

これにより、必要なサービス API が有効になり、以下のキーで terraform/terraform.tfvars ファイルが生成されます。

  1. 次のコマンドを実行して、それぞれの値が gcloud config list の出力と一致することを確認します。
cat terraform/terraform.tfvars

Kubernetes Engine クラスタのプロビジョニング

  1. 次に、プロジェクト ルート内で Terraform 構成を適用します。
make tf-apply
  1. プロンプトが表示されたら、生成されたプランを確認し、「yes」と入力して環境をデプロイします。

デプロイには数分かかります。

タスク 2. 検証

クラスタの作成が成功したことを示すメッセージが Terraform によって出力されます。

...snip... google_container_cluster.primary: Still creating... (3m0s elapsed) google_container_cluster.primary: Still creating... (3m10s elapsed) google_container_cluster.primary: Still creating... (3m20s elapsed) google_container_cluster.primary: Still creating... (3m30s elapsed) google_container_cluster.primary: Creation complete after 3m34s (ID: gke-demo-cluster) Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

完了したタスクをテストする

[進行状況を確認] をクリックして、実行したタスクを確認します。Terraform に必要なインフラストラクチャが正常にデプロイされていれば、評価スコアが表示されます。

Terraform を使用した必要なインフラストラクチャの設定(ラボの設定)
  1. 次に、残りの手順を実行するために、踏み台に SSH で接続します。
gcloud compute ssh gke-demo-bastion

既存バージョンの kubectl と Kubernetes カスタム クライアントには、クライアントと Google Kubernetes Engine との間の認証を管理するためのプロバイダ固有のコードが含まれています。v1.26 以降、このコードが OSS kubectl の一部として含まれなくなります。GKE ユーザーは、別の認証プラグインをダウンロードし、それを使用して GKE 固有のトークンを生成することが必要になります。この新しい gke-gcloud-auth-plugin バイナリは、Kubernetes client-go 認証情報プラグイン メカニズムを使って、GKE に対応できるよう kubectl の認証機能を拡張します。詳細については、こちらのブログ投稿をご覧ください。

kubectl での認証に、デフォルトのプロバイダ固有のコードではなく、新しいバイナリ プラグインが使用されるようにするには、以下の手順を踏みます。

  1. 接続したら、以下のコマンドを実行して gke-gcloud-auth-plugin を VM にインストールします。
sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin
  1. Set export USE_GKE_GCLOUD_AUTH_PLUGIN=True in ~/.bashrc:
echo "export USE_GKE_GCLOUD_AUTH_PLUGIN=True" >> ~/.bashrc
  1. 次のコマンドを実行します。
source ~/.bashrc
  1. 次のコマンドを実行して、このクラスタ用の構成を強制的に client-go 認証情報プラグインの構成に更新します。
gcloud container clusters get-credentials gke-demo-cluster --zone {{{project_0.default_zone|placeholder}}}

成功すると、このメッセージが表示されます。

kubeconfig entry generated for gke-demo-cluster.

新しく作成されたクラスタが、踏み台に対する標準の kubectl コマンドで使用できるようになります。

タスク 3. hello サーバーのインストール

テスト アプリケーションは、hello-server としてデプロイされている 1 つのシンプルな HTTP サーバーと 2 つのクライアント(一方には app=hello というラベル、もう一方には app=not-hello というラベルが付けられている)で構成されます。

これら 3 つのサービスはすべて、hello-app マニフェストを適用することでデプロイできます。

  1. 踏み台で、次のコマンドを実行します。
kubectl apply -f ./manifests/hello-app/

出力:

deployment.apps/hello-client-allowed created deployment.apps/hello-client-blocked created service/hello-server created deployment.apps/hello-server created
  1. 3 つの Pod すべてが正常にデプロイされていることを確認します。
kubectl get pods

hello-client-allowed、hello-client-blocked、hello-server のデプロイごとに 1 つの Pod が実行されていることがわかります。

NAME READY STATUS RESTARTS AGE hello-client-allowed-7d95fcd5d9-t8fsk | 1/1 Running 0 14m hello-client-blocked-6497db465d-ckbn8 | 1/1 Running 0 14m hello-server-7df58f7fb5-nvcvd | 1/1 Running 0 14m

完了したタスクをテストする

[進行状況を確認] をクリックして、実行したタスクを確認します。シンプルな HTTP hello サーバーが正常にデプロイされていれば、評価スコアが表示されます。

hello サーバーのインストール

タスク 4. hello サーバーへのデフォルト アクセスの確認

  1. 最初に、「許可される」クライアントに対して tail を実行します。
kubectl logs --tail 10 -f $(kubectl get pods -oname -l app=hello)

Ctrl+C キーを押して終了します。

  1. 次に、「ブロックされる」クライアントのログに tail を実行します。
kubectl logs --tail 10 -f $(kubectl get pods -oname -l app=not-hello)
  1. Ctrl+C キーを押して終了します。

両方の Pod が hello-server サービスに正常に接続できることがわかります。これは、アクセスを制限するためのネットワーク ポリシーをまだ定義していないためです。それぞれのウィンドウに、サーバーからの正常なレスポンスが表示されます。

Hostname: hello-server-7df58f7fb5-nvcvd Hello, world! Version: 1.0.0 Hostname: hello-server-7df58f7fb5-nvcvd Hello, world! Version: 1.0.0 Hostname: hello-server-7df58f7fb5-nvcvd ...

タスク 5. ネットワーク ポリシーを使用したアクセスの制限

次に、app=hello というラベルが付いていないすべての Pod からの hello-server Pod へのアクセスをブロックします。

使用するポリシー定義は、manifests/network-policy.yaml に含まれています。

  1. 次のコマンドを実行して、ポリシーを適用します。
kubectl apply -f ./manifests/network-policy.yaml

出力:

networkpolicy.networking.k8s.io/hello-server-allow-from-hello-client created
  1. 「ブロックされる」クライアントのログに、再度 tail を実行します。
kubectl logs --tail 10 -f $(kubectl get pods -oname -l app=not-hello)

今回は、「ブロックされる」クライアントのログの末尾を示す次のような出力がウィンドウに表示されます。

wget: download timed out wget: download timed out wget: download timed out wget: download timed out wget: download timed out wget: download timed out wget: download timed out wget: download timed out wget: download timed out ...

ネットワーク ポリシーによって、ラベルが付いていない Pod からの hello-server への通信が禁止されるようになりました。

  1. Ctrl+C キーを押して終了します。

タスク 6. ネットワーク ポリシーによる Namespace の制限

前の例では、Pod のラベルに基づいて接続を制限するネットワーク ポリシーを定義しました。代わりに Namespace 全体にラベルを付けると、特にチームやアプリケーションに独自の Namespace が付与されている場合に便利です。

そこで、指定した Namespace からのトラフィックのみを許可するようにネットワーク ポリシーを変更し、hello-allowed Pod をその新しい Namespace に移動します。

  1. まず、既存のネットワーク ポリシーを削除します。
kubectl delete -f ./manifests/network-policy.yaml

出力:

networkpolicy.networking.k8s.io "hello-server-allow-from-hello-client" deleted
  1. Namespace を指定したバージョンを作成します。
kubectl create -f ./manifests/network-policy-namespaced.yaml

出力:

networkpolicy.networking.k8s.io/hello-server-allow-from-hello-client created
  1. デフォルトの Namespace 内の hello-allowed-client Pod のログを確認します。
kubectl logs --tail 10 -f $(kubectl get pods -oname -l app=hello)

この Pod が hello-server に接続できなくなっていることがわかります。

  1. Ctrl+C キーを押して終了します。

  2. 最後に、hello-client アプリの 2 番目のコピーを新しい Namespace にデプロイします。

kubectl -n hello-apps apply -f ./manifests/hello-app/hello-client.yaml

出力:

deployment.apps/hello-client-allowed created deployment.apps/hello-client-blocked created

完了したタスクをテストする

[進行状況を確認] をクリックして、実行したタスクを確認します。hello-client アプリの 2 番目のコピーが新しい Namespace に正常にデプロイされていれば、評価スコアが表示されます。

hello-client アプリの 2 番目のコピーの新しい Namespace へのデプロイ

タスク 7. 検証

次に、2 つの新しい hello-app クライアントのログを検証します。

  1. 次のコマンドを実行して、hello-apps Namespace 内の「hello」というラベルが付いたアプリのログを表示します。
kubectl logs --tail 10 -f -n hello-apps $(kubectl get pods -oname -l app=hello -n hello-apps)

出力:

Hostname: hello-server-6c6fd59cc9-7fvgp Hello, world! Version: 1.0.0 Hostname: hello-server-6c6fd59cc9-7fvgp Hello, world! Version: 1.0.0 Hostname: hello-server-6c6fd59cc9-7fvgp Hello, world! Version: 1.0.0 Hostname: hello-server-6c6fd59cc9-7fvgp Hello, world! Version: 1.0.0 Hostname: hello-server-6c6fd59cc9-7fvgp

Kubernetes 1.10.x 以降、ネットワーク ポリシーで特定の Namespace 内の Pod へのアクセスを制限できなくなったため、いずれのクライアントも正常に接続できています。Pod のラベル、Namespace のラベル、あるいは両方の union(OR 結合)を許可リストに登録できます。ただし、Pod のラベルと Namespace のラベルの交差(AND 結合)を許可リストに登録することはまだできません。

  1. Ctrl+C キーを押して終了します。

タスク 8. 破棄

このラボで使用したすべてのリソースは Qwiklabs によってシャットダウンされますが、次のクリーンアップ手順に従うことで、費用を抑えてクラウドにおけるマナーを保つことができます。

  1. 踏み台インスタンスからログアウトします。
exit
  1. 次のコマンドを実行して環境を破棄します。
make teardown

出力:

...snip... google_compute_subnetwork.cluster-subnet: Still destroying... (ID: us-east1/kube-net-subnet, 20s elapsed) google_compute_subnetwork.cluster-subnet: Destruction complete after 25s google_compute_network.gke-network: Destroying... (ID: kube-net) google_compute_network.gke-network: Still destroying... (ID: kube-net, 10s elapsed) google_compute_network.gke-network: Still destroying... (ID: kube-net, 20s elapsed) google_compute_network.gke-network: Destruction complete after 26s Destroy complete! Resources: 5 destroyed.

タスク 9. 独自の環境でのトラブルシューティング

Terraform の実行中に、インストール スクリプトの実行が「Permission denied」というエラーで失敗する

Terraform で使用している認証情報には、選択されているプロジェクトでリソースを作成するのに必要な権限がありません。gcloud config list で表示されるアカウントに、リソースの作成に必要な権限があることを確認してください。権限がある場合は、gcloud auth application-default login を実行してアプリケーションのデフォルト認証情報を生成し直してください。

Terraform オペレーション中の無効なフィンガープリント エラー

Terraform で特定のリソースを更新中に、無効なフィンガープリントに関するエラーが表示されることがあります。

以下のエラーが表示された場合は、シンプルにコマンドを再実行してください。Terraform のフィンガープリント エラー

お疲れさまでした

きめの細かい制限をネットワーク通信に適用することで、Kubernetes Engine のセキュリティが向上しました。

クエストを完了する

このセルフペース ラボは、「Google Kubernetes Engine Best Practices: Security」クエストの一部です。クエストとは学習プログラムを構成する一連のラボのことで、完了すると成果が認められてバッジが贈られます。バッジは公開して、オンライン レジュメやソーシャル メディア アカウントにリンクできます。このラボの修了後、こちらのクエストに登録すれば、すぐにクレジットを受け取ることができます。受講可能なすべてのクエストについては、Google Cloud Skills Boost カタログをご覧ください。

次のラボを受講する

デフォルトの GKE クラスタ構成の強化に進んでクエストを続けるか、以下の Google Cloud Skills Boost ラボをご確認ください。

次のステップと詳細情報

Google Cloud トレーニングと認定資格

Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。

マニュアルの最終更新日: 2023 年 10 月 18 日
ラボの最終テスト日: 2023 年 10 月 18 日

Copyright 2024 Google LLC. 本ソフトウェアは「現状有姿」で提供されており、いかなる使用および目的に関しても保証および表明は伴いません。本ソフトウェアのご利用には、Google との契約が適用されます。