arrow_back

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

ログイン 参加
700 以上のラボとコースにアクセス

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

ラボ 1時間 universal_currency_alt クレジット: 5 show_chart 中級
info このラボでは、学習をサポートする AI ツールが組み込まれている場合があります。
700 以上のラボとコースにアクセス

GSP493

概要

このラボでは、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 Cloud コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く] を選択します)。

    ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。

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

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

    {{{user_0.username | "Username"}}}

    [ラボの詳細] ペインでもユーザー名を確認できます。

  4. [次へ] をクリックします。

  5. 以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。

    {{{user_0.password | "Password"}}}

    [ラボの詳細] ペインでもパスワードを確認できます。

  6. [次へ] をクリックします。

    重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  7. その後次のように進みます。

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

その後、このタブで Google Cloud コンソールが開きます。

注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニューをクリックするか、[検索] フィールドにサービス名またはプロダクト名を入力します。

Cloud Shell をアクティブにする

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

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

  2. ウィンドウで次の操作を行います。

    • Cloud Shell 情報ウィンドウで操作を進めます。
    • Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。

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

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

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

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

出力:

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

出力:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 注: 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. クラスタを確認する

事前に作成されたクラスタがコンソールに表示されていることを確認します。ナビゲーション メニュー > [Kubernetes Engine] > [クラスタ] に移動し、[rbac-demo-cluster] クラスタをクリックします。新しいクラスタで [以前の承認] が無効になっていることを確認します。

タスク 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 注: gcp auth プラグインに関連するエラーは無視します。

既存バージョンの 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 注: gcp auth プラグインに関連するエラーは無視します。
  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 注: gcp auth プラグインに関連するエラーは無視します。
  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 のバージョンによって異なりますが、オープンソースのコードベースで確認できます。

お疲れさまでした

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

次のステップと詳細情報

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

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

マニュアルの最終更新日: 2025 年 2 月 24 日

ラボの最終テスト日: 2025 年 2 月 24 日

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

始める前に

  1. ラボでは、Google Cloud プロジェクトとリソースを一定の時間利用します
  2. ラボには時間制限があり、一時停止機能はありません。ラボを終了した場合は、最初からやり直す必要があります。
  3. 画面左上の [ラボを開始] をクリックして開始します

このコンテンツは現在ご利用いただけません

利用可能になりましたら、メールでお知らせいたします

ありがとうございます。

利用可能になりましたら、メールでご連絡いたします

1 回に 1 つのラボ

既存のラボをすべて終了して、このラボを開始することを確認してください

シークレット ブラウジングを使用してラボを実行する

このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウントの競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。