arrow_back

Kubernetes Engine におけるロールベース アクセス制御の使用

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

Kubernetes Engine におけるロールベース アクセス制御の使用

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

GSP493

Google Cloud セルフペース ラボ

概要

このラボでは、Kubernetes Engine クラスタにおけるロールベースのアクセス制御(RBAC)の使用方法とデバッグについて説明します。

RBAC リソースの定義はすべての Kubernetes プラットフォームで一貫していますが、クラウド プロバイダ上でプロジェクトを作成する際には、基盤となる認証プロバイダ認可プロバイダとのインタラクションを理解しておく必要があります。

RBAC は、クラスタ内でのオペレーションを柔軟に制限できる強力なセキュリティ メカニズムです。このラボでは、RBAC の次の 2 つのユースケースを取り上げます。

  1. ユーザー ペルソナ(具体的には、オーナーと監査者)に異なる権限を割り当てる。
  2. クラスタ内で実行しているアプリケーションに制限付きの API アクセスを付与する。

RBAC が持つ柔軟性が、ときには複雑なルールを生み出してしまうことがあるため、シナリオ 2 に RBAC の一般的なトラブルシューティングに関する手順を含めています。

アーキテクチャ

このラボでは、Kubernetes Engine クラスタ内での RBAC の使用に焦点を当てます。ユーザー ペルソナごとに異なるレベルのクラスタ権限を付与する方法について説明します。このラボでは、ユーザー ペルソナを表す 2 つのサービス アカウントと、dev、test、prod の 3 つの Namespace をプロビジョニングします。「オーナー」ペルソナは 3 つの Namespace すべてに対する読み取り / 書き込みアクセス権を持ち、「監査者」ペルソナは dev Namespace のみに制限された読み取り専用アクセス権を持ちます。

このラボは、GKE(Google Kubernetes Engine)でのロールベース アクセス制御の使用について理解を深めていただくことを目的に、GKE Helmsman のエンジニアが作成したものです。GitHub でデモを確認できます。アセットにぜひ貢献していただければ幸いです。

アーキテクチャ図

設定と要件

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

こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、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 の概要ガイドをご覧ください。

リージョンとゾーンを設定する

一部の Compute Engine リソースは、リージョン内やゾーン内に存在します。リージョンとは、リソースを実行できる特定の地理的なロケーションです。1 つのリージョンには 1 つ以上のゾーンがあります。

リージョンおよびゾーンの詳細と一覧については、リージョンとゾーンのドキュメントをご覧ください。

次のコマンドを実行して、ラボのリージョンとゾーンを設定します(ご利用の環境に最も適したリージョンとゾーンを使用してください)。

gcloud config set compute/region {{{project_0.default_region|REGION}}} gcloud config set compute/zone {{{project_0.default_zone|ZONE}}}

タスク 1. デモのクローンを作成する

  1. 次のコマンドを実行して、このラボに必要なリソースをダウンロードします。
gsutil cp gs://spls/gsp493/gke-rbac-demo.tar . tar -xvf gke-rbac-demo.tar
  1. 抽出されたディレクトリに移動します。
cd gke-rbac-demo

Kubernetes Engine クラスタをプロビジョニングする

次に、Terraform の構成を適用します。

  1. プロジェクトのルート内から、make を使用して Terraform の構成を適用します。
make create

このデモの設定には最大で 10~15 分かかります。エラーが発生しない限り、完了までお待ちください。make create の実行は中断しないでください。

  1. リソースの作成中に、google_compute_instance が作成されたことが表示されたら、Google Cloud Platform(GCP)Console の [Compute Engine] > [VM インスタンス] で進行状況を確認できます。[VM インスタンス] ページの [更新] ボタンを使用して、最新情報を表示します。

完了すると、Terraform によって、クラスタが正常に作成されたことを示すメッセージが表示されます。

  1. GCP Console でクラスタが正常に作成されたことを確認します。ナビゲーション メニュー > [Kubernetes Engine] > [クラスタ] に移動し、作成されたクラスタをクリックします。新しいクラスタで [以前の承認] が無効になっていることを確認します。

GCP コンソールでのクラスタの設定

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 Kubernetes Engine クラスタをプロビジョニングする

タスク 2. シナリオ 1: ユーザー ペルソナごとの権限の割り当て

IAM - ロール

iam.tf 内の Terraform の構成の一部として、以下の権限を持つ kube-api-ro-xxxxxxxxxxxxxxxx はランダムな文字列)という名前のロールが作成されています。これらの権限は、Kubernetes API へのアクセスを必要とするすべてのユーザーに必要な最小限の権限です。

  • container.apiServices.get
  • container.apiServices.list
  • container.clusters.get
  • container.clusters.getCredentials

ユーザーをシミュレートする

テストユーザーとして動作する 3 つのサービス アカウントが作成されています。

  • admin: クラスタとすべてのリソースに対する管理者権限を持ちます
  • owner: 共通のクラスタ リソースに対する読み取り / 書き込み権限を持ちます
  • auditor: dev Namespace 内のみでの読み取り専用権限を持ちます
  1. 以下のコマンドを実行します。
gcloud iam service-accounts list

Terraform スクリプトによって、3 つのテストホストがプロビジョニングされています。各ノードに kubectlgcloud がインストールされ、異なるユーザー ペルソナをシミュレートするように構成されています。

  • gke-tutorial-admin: kubectl と gcloud がクラスタ管理者として認証されています。
  • gke-tutorial-owner: owner アカウントをシミュレートします。
  • gke-tutorial-auditor: auditor アカウントをシミュレートします。
  1. 以下のコマンドを実行します。
gcloud compute instances list

出力:

NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS rbac-demo-cluster-default-pool-a9cd3468-4vpc {{{project_0.default_zone|ZONE}}} n1-standard-1 10.0.96.5 RUNNING rbac-demo-cluster-default-pool-a9cd3468-b47f {{{project_0.default_zone|ZONE}}} n1-standard-1 10.0.96.6 RUNNING rbac-demo-cluster-default-pool-a9cd3468-rt5p {{{project_0.default_zone|ZONE}}} n1-standard-1 10.0.96.7 RUNNING gke-tutorial-auditor {{{project_0.default_zone|ZONE}}} f1-micro 10.0.96.4 35.224.148.28 RUNNING gke-tutorial-admin {{{project_0.default_zone|ZONE}}} f1-micro 10.0.96.3 35.226.237.142 RUNNING gke-tutorial-owner {{{project_0.default_zone|pZONE}}} f1-micro 10.0.96.2 35.194.58.130 RUNNING

ロールベース アクセス制御のルールを作成する

admin インスタンスにログインして rbac.yaml マニフェストを適用し、Namespace、Role、RoleBinding を作成します。

  1. SSH を使用して admin に接続します。
gcloud compute ssh gke-tutorial-admin Ignore the error which relates to gcp auth plugin.

既存バージョンの 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. ~/.bashrcexport USE_GKE_GCLOUD_AUTH_PLUGIN=True を設定します。
echo "export USE_GKE_GCLOUD_AUTH_PLUGIN=True" >> ~/.bashrc
  1. 次のコマンドを実行します。
source ~/.bashrc
  1. 次のコマンドを実行して、このクラスタ用の構成を強制的に client-go 認証情報プラグインの構成に更新します。
gcloud container clusters get-credentials rbac-demo-cluster --zone {{{project_0.default_zone|ZONE}}}

更新が正常に完了したら、次のメッセージが表示されます。

Kubeconfig entry generated for dev-cluster.

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

  1. Namespace、Role、Binding を作成します。
kubectl apply -f ./manifests/rbac.yaml

出力:

namespace/dev created namespace/prod created namespace/test created role.rbac.authorization.k8s.io/dev-ro created clusterrole.rbac.authorization.k8s.io/all-rw created clusterrolebinding.rbac.authorization.k8s.io/owner-binding created rolebinding.rbac.authorization.k8s.io/auditor-binding created

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 RBAC ルールを作成する

オーナーとしてリソースを管理する

  1. ターミナル ウィンドウの上部にある + をクリックして、新しい Cloud Shell ターミナルを開きます。

次に、SSH を使用して owner インスタンスに接続し、各 Namespace にシンプルな Deployment を作成します。

  1. SSH を使用して「owner」インスタンスに接続します。
gcloud compute ssh gke-tutorial-owner Ignore the error which relates to gcp auth plugin.
  1. ゾーンに関するプロンプトが表示されたら、「n」を入力してデフォルトのゾーンが使用されるようにします。

  2. gke-gcloud-auth-plugin をインストールします。

sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin echo "export USE_GKE_GCLOUD_AUTH_PLUGIN=True" >> ~/.bashrc source ~/.bashrc gcloud container clusters get-credentials rbac-demo-cluster --zone {{{project_0.default_zone|ZONE}}}
  1. 各 Namespace にサーバーを作成します。最初は dev を作成します。
kubectl create -n dev -f ./manifests/hello-server.yaml

出力:

service/hello-server created deployment.apps/hello-server created
  1. 次に prod を作成します。
kubectl create -n prod -f ./manifests/hello-server.yaml

出力:

service/hello-server created deployment.apps/hello-server created
  1. 次に test を作成します。
kubectl create -n test -f ./manifests/hello-server.yaml

出力:

service/hello-server created deployment.apps/hello-server created

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 各 Namespace にサーバーを作成する

オーナーはすべての Pod を表示することもできます。

  • 「owner」インスタンスで次のコマンドを実行し、すべての Namespace の hello-server Pod 全一覧を表示します。
kubectl get pods -l app=hello-server --all-namespaces

出力:

NAMESPACE NAME READY STATUS RESTARTS AGE dev hello-server-6c6fd59cc9-h6zg9 1/1 Running 0 6m prod hello-server-6c6fd59cc9-mw2zt 1/1 Running 0 44s test hello-server-6c6fd59cc9-sm6bs 1/1 Running 0 39s

監査者としてリソースを表示する

次に、新しいターミナルを開き、SSH を使用して auditor インスタンスに接続し、すべての Namespace を確認します。

  1. ターミナル ウィンドウの上部にある + をクリックして、新しい Cloud Shell ターミナルを開きます。

  2. SSH を使用して「auditor」インスタンスに接続します。

gcloud compute ssh gke-tutorial-auditor Ignore the error which relates to gcp auth plugin.
  1. ゾーンに関するプロンプトが表示されたら、「n」を入力してデフォルトのゾーンが使用されるようにします。

  2. gke-gcloud-auth-plugin をインストールします。

sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin echo "export USE_GKE_GCLOUD_AUTH_PLUGIN=True" >> ~/.bashrc source ~/.bashrc gcloud container clusters get-credentials rbac-demo-cluster --zone {{{project_0.default_zone|ZONE}}}
  1. 「auditor」インスタンスで次のコマンドを実行し、すべての Namespace の hello-server Pod 全一覧を表示します。
kubectl get pods -l app=hello-server --all-namespaces

次のようなエラーが表示されます。

Error from server (Forbidden): pods is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot list pods at the cluster scope: Required "container.pods.list" permission

このエラーは実行者に十分な権限がないことを示しています。監査者ロールで表示できるのは dev Namespace 内のリソースに限られるため、リソースを表示するときには dev Namespace を指定する必要があります。

次に、dev Namespace 内の Pod を表示してみましょう。

  1. 「auditor」インスタンスで次のコマンドを実行します。
kubectl get pods -l app=hello-server --namespace=dev

出力:

NAME READY STATUS RESTARTS AGE hello-server-6c6fd59cc9-h6zg9 1/1 Running 0 13m
  1. test Namespace 内の Pod を表示してみます。
kubectl get pods -l app=hello-server --namespace=test

出力:

Error from server (Forbidden): pods is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot list pods in the namespace "test": Required "container.pods.list" permission.
  1. prod Namespace 内の Pod を表示してみます。
kubectl get pods -l app=hello-server --namespace=prod

出力:

Error from server (Forbidden): pods is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot list pods in the namespace "prod": Required "container.pods.list" permission.

最後に、dev Namespace で Deployment の作成と削除を試行して、監査者には読み取り専用権限しかないことを確認します。

  1. 「auditor」インスタンスで、Deployment を作成してみます。
kubectl create -n dev -f manifests/hello-server.yaml

出力:

Error from server (Forbidden): error when creating "manifests/hello-server.yaml": services is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot create services in the namespace "dev": Required "container.services.create" permission. Error from server (Forbidden): error when creating "manifests/hello-server.yaml": deployments.extensions is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot create deployments.extensions in the namespace "dev": Required "container.deployments.create" permission.
  1. 「auditor」インスタンスで、Deployment を削除してみます。
kubectl delete deployment -n dev -l app=hello-server

出力:

Error from server (Forbidden): deployments.extensions "hello-server" is forbidden: User "gke-tutorial-auditor@myproject.iam.gserviceaccount.com" cannot update deployments.extensions in the namespace "dev": Required "container.deployments.update" permission.

タスク 3. シナリオ 2: クラスタ アプリケーションへの API 権限の割り当て

このシナリオでは、Kubernetes API へのアクセスを必要とするアプリケーションをデプロイし、一般的なユースケースをトラブルシューティングしながら RBAC ルールを構成します。

サンプル アプリケーションをデプロイする

サンプル アプリケーションは、API サーバーからデフォルトの Namespace 内のすべての Pod を定期的に取得し、各 Pod にタイムスタンプ ラベルを適用する単一の Pod として動作します。

  1. admin インスタンス(最初の Cloud Shell タブ)から、pod-labeler アプリケーションをデプロイします。これにより、Pod の Role、ServiceAccount、RoleBinding もデプロイされます。
kubectl apply -f manifests/pod-labeler.yaml

出力:

role.rbac.authorization.k8s.io/pod-labeler created serviceaccount/pod-labeler created rolebinding.rbac.authorization.k8s.io/pod-labeler created deployment.apps/pod-labeler created

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 サンプル アプリケーションをデプロイする

RBAC の構成ミスを診断する

次に、Pod のステータスを確認します。コンテナの作成が終了すると、エラーが出力されます。Pod のイベントとログを確認して、エラーを調べます。

  1. admin インスタンスで Pod のステータスを確認します。
kubectl get pods -l app=pod-labeler

出力:

NAME READY STATUS RESTARTS AGE pod-labeler-6d9757c488-tk6sp 0/1 Error 1 1m
  1. admin インスタンスで、次のコマンドを実行して Pod のイベント ストリームを表示します。
kubectl describe pod -l app=pod-labeler | tail -n 20

次のように表示されます。

Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 7m35s default-scheduler Successfully assigned default/pod-labeler-5b4bd6cf9-w66jd to gke-rbac-demo-cluster-default-pool-3d348201-x0pk Normal Pulling 7m34s kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk pulling image "gcr.io/pso-examples/pod-labeler:0.1.5" Normal Pulled 6m56s kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk Successfully pulled image "gcr.io/pso-examples/pod-labeler:0.1.5" Normal Created 5m29s (x5 over 6m56s) kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk Created container Normal Pulled 5m29s (x4 over 6m54s) kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk Container image "gcr.io/pso-examples/pod-labeler:0.1.5" already present on machine Normal Started 5m28s (x5 over 6m56s) kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk Started container Warning BackOff 2m25s (x23 over 6m52s) kubelet, gke-rbac-demo-cluster-default-pool-3d348201-x0pk Back-off restarting failed container
  1. admin インスタンスで、次のコマンドを実行して Pod のログを確認します。
kubectl logs -l app=pod-labeler

出力:

Attempting to list pods Traceback (most recent call last): File "label_pods.py", line 13, in ret = v1.list_namespaced_pod("default",watch=False) File "build/bdist.linux-x86_64/egg/kubernetes/client/apis/core_v1_api.py", line 12310, in list_namespaced_pod File "build/bdist.linux-x86_64/egg/kubernetes/client/apis/core_v1_api.py", line 12413, in list_namespaced_pod_with_http_info File "build/bdist.linux-x86_64/egg/kubernetes/client/api_client.py", line 321, in call_api File "build/bdist.linux-x86_64/egg/kubernetes/client/api_client.py", line 155, in __call_api File "build/bdist.linux-x86_64/egg/kubernetes/client/api_client.py", line 342, in request File "build/bdist.linux-x86_64/egg/kubernetes/client/rest.py", line 231, in GET File "build/bdist.linux-x86_64/egg/kubernetes/client/rest.py", line 222, in request kubernetes.client.rest.ApiException: (403) Reason: Forbidden HTTP response headers: HTTPHeaderDict({'Date': 'Fri, 25 May 2018 15:33:15 GMT', 'Audit-Id': 'ae2a0d7c-2ab0-4f1f-bd0f-24107d3c144e', 'Content-Length': '307', 'Content-Type': 'application/json', 'X-Content-Type-Options': 'nosniff'}) HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pods is forbidden: User \"system:serviceaccount:default:default\" cannot list pods in the namespace \"default\": Unknown user \"system:serviceaccount:default:default\"","reason":"Forbidden","details":{"kind":"pods"},"code":403}

このエラーから、API を使用して Pod を一覧表示しようとしたときに、権限のエラーが発生していることがわかります。

  1. 次の手順では、正しい ServiceAccount を使用していることを確認します。

ServiceAccount 名を修正する

Pod の構成を調べると、カスタム サービス アカウントではなく、デフォルトの ServiceAccount が使用されていることがわかります。

  1. admin インスタンスで次のコマンドを実行します。
kubectl get pod -oyaml -l app=pod-labeler

出力:

restartPolicy: Always schedulerName: default-scheduler securityContext: fsGroup: 9999 runAsGroup: 9999 runAsUser: 9999 serviceAccount: default

pod-labeler-fix-1.yaml ファイルの Deployment のテンプレート仕様に修正が含まれています。

# 修正 1、serviceAccount を設定してロールベース アクセス制御のルールを適用する serviceAccount: pod-labeler

次にこの修正を適用し、適用後の変更を確認します。

  1. admin インスタンスで、次のコマンドを実行して修正 1 を適用します。
kubectl apply -f manifests/pod-labeler-fix-1.yaml

出力:

role.rbac.authorization.k8s.io/pod-labeler unchanged serviceaccount/pod-labeler unchanged rolebinding.rbac.authorization.k8s.io/pod-labeler unchanged deployment.apps/pod-labeler configured
  1. Deployment 構成の変更を確認します。
kubectl get deployment pod-labeler -oyaml

変更された出力:

... restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: pod-labeler ...

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 ServiceAccount 名を修正する

権限の不足を診断する

もう一度、Pod のステータスを確認してください。まだエラーが表示されていますが、今回はメッセージが異なることがわかります。

  1. admin インスタンスで Pod のステータスを確認します。
kubectl get pods -l app=pod-labeler

出力:

NAME READY STATUS RESTARTS AGE pod-labeler-c7b4fd44d-mr8qh 0/1 CrashLoopBackOff 3 1m

この出力を表示するには、前述のコマンドの再実行が必要になる場合があります。

  1. admin インスタンスで、Pod のログを確認します。
kubectl logs -l app=pod-labeler

出力:

File "/usr/local/lib/python3.8/site-packages/kubernetes/client/rest.py", line 292, in PATCH return self.request("PATCH", url, File "/usr/local/lib/python3.8/site-packages/kubernetes/client/rest.py", line 231, in request raise ApiException(http_resp=r) kubernetes.client.rest.ApiException: (403) Reason: Forbidden HTTP response headers: HTTPHeaderDict({'Audit-Id': 'f6c67c34-171f-42f3-b1c9-833e00cedd5e', 'Content-Type': 'application/json', 'X-Content-Type-Options': 'nosniff', 'Date': 'Mon, 23 Mar 2020 16:35:18 GMT', 'Content-Length': '358'}) HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pods \"pod-labeler-659c8c99d5-t96pw\" is forbidden: User \"system:serviceaccount:default:pod-labeler\" cannot patch resource \"pods\" in API group \"\" in the namespace \"default\"","reason":"Forbidden","details":{"name":"pod-labeler-659c8c99d5-t96pw","kind":"pods"},"code":403}

PATCH オペレーションで失敗しているため、Stackdriver にもエラーが表示されます。これは、アプリケーションのログでは十分な詳細が得られない場合に役立ちます。

  1. Google Cloud コンソールでナビゲーション メニューを選択し、[オペレーション] の [ロギング] をクリックします。

  2. クエリビルダーのダイアログ ボックスに次のコードを貼り付けて、[クエリを実行] をクリックします。

protoPayload.methodName="io.k8s.core.v1.pods.patch"
  1. ログレコードの隣にある下矢印をクリックし、詳細を確認します。

アプリケーションのロールと権限を識別する

ClusterRoleBinding を使用して、ServiceAccount のロールと権限を確認します。

  1. admin インスタンスで、rolebinding の定義を調べます。
kubectl get rolebinding pod-labeler -oyaml

出力:

apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"pod-labeler","namespace":"default"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"Role","name":"pod-labeler"},"subjects":[{"kind":"ServiceAccount","name":"pod-labeler"}]} creationTimestamp: "2020-03-23T16:29:05Z" name: pod-labeler namespace: default resourceVersion: "2886" selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/pod-labeler uid: 0e4d5be7-d986-40d0-af1d-a660f9aa4336 roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pod-labeler subjects: - kind: ServiceAccount name: pod-labeler

RoleBinding に、デフォルトの Namespace で pod-labeler ロールを調べる必要があることが示されます。ここで、このロールには、Pod を一覧表示する権限のみが付与されていることがわかります。

  1. admin インスタンスで、pod-labeler ロールの定義を調べます。
kubectl get role pod-labeler -oyaml

出力:

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pod-labeler","namespace":"default"},"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["list"]}]} creationTimestamp: "2020-03-23T16:29:05Z" name: pod-labeler namespace: default resourceVersion: "2883" selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/pod-labeler uid: c8191869-c7de-42c6-98fc-79a91d9b02a1 rules: - apiGroups: - "" resources: - pods verbs: - list

アプリケーションには PATCH 権限が必要であるため、ここで、ロールの「verbs」リストにこの権限を追加します。

pod-labeler-fix-2.yaml ファイルの rules/verbs セクションに修正が含まれています。

rules: - apiGroups: [""] # "" はコア API グループを示す resources: ["pods"] verbs: ["list","patch"] # 修正 2: Pod のパッチ適用(更新)権限の追加

修正を適用し、適用後の構成を確認します。

  1. admin インスタンスで fix-2 を適用します。
kubectl apply -f manifests/pod-labeler-fix-2.yaml

出力:

role.rbac.authorization.k8s.io/pod-labeler configured serviceaccount/pod-labeler unchanged rolebinding.rbac.authorization.k8s.io/pod-labeler unchanged deployment.apps/pod-labeler unchanged

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 アプリケーションのロールと権限を識別する

  1. admin インスタンスで変更内容を確認します。
kubectl get role pod-labeler -oyaml

出力:

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pod-labeler","namespace":"default"},"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["list","patch"]}]} creationTimestamp: "2020-03-23T16:29:05Z" name: pod-labeler namespace: default resourceVersion: "8802" selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/pod-labeler uid: c8191869-c7de-42c6-98fc-79a91d9b02a1 rules: - apiGroups: - "" resources: - pods verbs: - list - patch

pod-labeler はバックオフ ループ内にある可能性があるため、修正をテストするための最も簡単な方法は、既存の Pod を強制終了して、新しい Pod で置き換えることです。

  1. admin インスタンスで、次のコマンドを実行して既存の Pod を強制終了し、Deployment コントローラで置き換えます。
kubectl delete pod -l app=pod-labeler

出力:

pod "pod-labeler-659c8c99d5-t96pw" deleted

構成が正しいことを確認する

最後に、新しい pod-labeler が実行されていることを検証し、「updated」ラベルが適用されたことを確認します。

  1. admin インスタンスで Pod の全一覧とそのラベルを表示します。
kubectl get pods --show-labels

出力:

NAME READY STATUS RESTARTS NAME READY STATUS RESTARTS AGE LABELS pod-labeler-659c8c99d5-5qsmw 1/1 Running 0 31s app=pod-labeler,pod-template-hash=659c8c99d5,updated=1584982487.6428008
  1. Pod のログを表示し、エラーがなくなっていることを確認します。
kubectl logs -l app=pod-labeler

出力:

Attempting to list pods labeling pod pod-labeler-659c8c99d5-5qsmw labeling pod pod-labeler-659c8c99d5-t96pw ...

重要ポイント

  • コンテナと API サーバーのログは、ロールベース アクセス制御の問題を診断する手がかりを得るために適したソースです。
  • RoleBinding または ClusterRoleBinding を使用して、Pod の権限を指定しているロールを確認します。
  • API サーバーのログは、Kubernetes リソースの下の Stackdriver にあります。
  • すべての API 呼び出しが Stackdriver のログに記録されるわけではありません。Kubernetes Engine で使用される Kubernetes の監査ポリシーによって、頻繁なペイロードや詳細なペイロードは省略されます。具体的なポリシーは Kubernetes のバージョンによって異なりますが、オープンソースのコードベースで確認できます。

タスク 4. 破棄

ラボの作業が終了し、作成されたリソースをクリーンアップする準備ができたら、次のコマンドを実行してすべてのリソースを削除します。

  1. exit」と入力して踏み台インスタンスからログアウトします。

  2. 次のコマンドを実行して環境を破棄します。

make teardown

出力:

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

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 破棄

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

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

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

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

Terraform で特定のリソースを更新中に、無効なフィンガープリントに関するエラーが表示されることがあります。Error: Error applying plan というメッセージとともに次のエラーが表示された場合は、コマンドを再実行してください。

  • module.network.google_compute_subnetwork.cluster-subnet: 1 error(s) occurred
  • google.compute_subnetwork.cluster-subnet: Error updating subnetwork /kube-net-subnet: googleapi: Error412: Invalid fingerprint, conditionNotMet

お疲れさまでした

このラボでは、ユーザー ペルソナにさまざまな権限を割り当てて、クラスタ内で実行されているアプリケーションに制限付きの API アクセスを付与することで、ロールベース アクセス制御を実現する方法について学びました。

クエストを完了する

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

次のラボを受講する

Google Kubernetes Engine Security: Binary Authorization に進んでクエストを続けるか、以下をご確認ください。

次のステップと詳細情報

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

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

マニュアルの最終更新日: 2023 年 10 月 9 日

ラボの最終テスト日: 2023 年 10 月 9 日

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