GSP493
概要
このラボでは、Kubernetes Engine クラスタにおけるロールベースのアクセス制御(RBAC)の使用方法とデバッグについて説明します。
RBAC リソースの定義はすべての Kubernetes プラットフォームで一貫していますが、クラウド プロバイダ上でプロジェクトを作成する際には、基盤となる認証プロバイダ認可プロバイダとのインタラクションを理解しておく必要があります。
RBAC は、クラスタ内でのオペレーションを柔軟に制限できる強力なセキュリティ メカニズムです。このラボでは、RBAC の次の 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 コンソールにログインする方法
-
[ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。
左側の [ラボの詳細] パネルには、以下が表示されます。
- [Google Cloud コンソールを開く] ボタン
- 残り時間
- このラボで使用する必要がある一時的な認証情報
- このラボを行うために必要なその他の情報(ある場合)
-
[Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウでリンクを開く] を選択します)。
ラボでリソースが起動し、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
-
必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}}
[ラボの詳細] パネルでも [ユーザー名] を確認できます。
-
[次へ] をクリックします。
-
以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}}
[ラボの詳細] パネルでも [パスワード] を確認できます。
-
[次へ] をクリックします。
重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。
注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
-
その後次のように進みます。
- 利用規約に同意してください。
- 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
- 無料トライアルには登録しないでください。
その後、このタブで Google Cloud コンソールが開きます。
注: Google Cloud のプロダクトやサービスのリストを含むメニューを表示するには、左上のナビゲーション メニューをクリックします。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
- Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン をクリックします。
接続した時点で認証が完了しており、プロジェクトに各自の PROJECT_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
Your Cloud Platform project in this session is set to YOUR_PROJECT_ID
gcloud
は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
- (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
-
[承認] をクリックします。
-
出力は次のようになります。
出力:
ACTIVE: *
ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (省略可)次のコマンドを使用すると、プロジェクト 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. デモのクローンを作成する
- 次のコマンドを実行して、このラボに必要なリソースをダウンロードします。
gsutil cp gs://spls/gsp493/gke-rbac-demo.tar .
tar -xvf gke-rbac-demo.tar
- 抽出されたディレクトリに移動します。
cd gke-rbac-demo
Kubernetes Engine クラスタをプロビジョニングする
次に、Terraform の構成を適用します。
- プロジェクトのルート内から、
make
を使用して Terraform の構成を適用します。
make create
このデモの設定には最大で 10~15 分かかります。エラーが発生しない限り、完了までお待ちください。make create
の実行は中断しないでください。
- リソースの作成中に、
google_compute_instance
が作成されたことが表示されたら、Google Cloud Platform(GCP)Console の [Compute Engine] > [VM インスタンス] で進行状況を確認できます。[VM インスタンス] ページの [更新] ボタンを使用して、最新情報を表示します。
完了すると、Terraform によって、クラスタが正常に作成されたことを示すメッセージが表示されます。
- GCP Console でクラスタが正常に作成されたことを確認します。ナビゲーション メニュー > [Kubernetes Engine] > [クラスタ] に移動し、作成されたクラスタをクリックします。新しいクラスタで [以前の承認] が無効になっていることを確認します。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Kubernetes Engine クラスタをプロビジョニングする
タスク 2. シナリオ 1: ユーザー ペルソナごとの権限の割り当て
IAM - ロール
iam.tf
内の Terraform の構成の一部として、以下の権限を持つ kube-api-ro-xxxxxxxx
(xxxxxxxx
はランダムな文字列)という名前のロールが作成されています。これらの権限は、Kubernetes API へのアクセスを必要とするすべてのユーザーに必要な最小限の権限です。
- container.apiServices.get
- container.apiServices.list
- container.clusters.get
- container.clusters.getCredentials
ユーザーをシミュレートする
テストユーザーとして動作する 3 つのサービス アカウントが作成されています。
-
admin: クラスタとすべてのリソースに対する管理者権限を持ちます
-
owner: 共通のクラスタ リソースに対する読み取り / 書き込み権限を持ちます
-
auditor: dev Namespace 内のみでの読み取り専用権限を持ちます
- 以下のコマンドを実行します。
gcloud iam service-accounts list
Terraform スクリプトによって、3 つのテストホストがプロビジョニングされています。各ノードに kubectl
と gcloud
がインストールされ、異なるユーザー ペルソナをシミュレートするように構成されています。
-
gke-tutorial-admin: kubectl と gcloud がクラスタ管理者として認証されています。
-
gke-tutorial-owner:
owner
アカウントをシミュレートします。
-
gke-tutorial-auditor:
auditor
アカウントをシミュレートします。
- 以下のコマンドを実行します。
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 を作成します。
- 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 での認証に、デフォルトのプロバイダ固有のコードではなく、新しいバイナリ プラグインが使用されるようにするには、以下の手順で操作します。
- 接続したら、以下のコマンドを実行して
gke-gcloud-auth-plugin
を VM にインストールします。
sudo apt-get install google-cloud-sdk-gke-gcloud-auth-plugin
-
~/.bashrc
で export USE_GKE_GCLOUD_AUTH_PLUGIN=True
を設定します。
echo "export USE_GKE_GCLOUD_AUTH_PLUGIN=True" >> ~/.bashrc
- 次のコマンドを実行します。
source ~/.bashrc
- 次のコマンドを実行して、このクラスタ用の構成を強制的に client-go 認証情報プラグインの構成に更新します。
gcloud container clusters get-credentials rbac-demo-cluster --zone {{{project_0.default_zone|ZONE}}}
更新が正常に完了したら、次のメッセージが表示されます。
Kubeconfig entry generated for dev-cluster.
新しく作成されたクラスタが、踏み台に対する標準の kubectl
コマンドで使用できるようになります。
- 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 ルールを作成する
オーナーとしてリソースを管理する
- ターミナル ウィンドウの上部にある + をクリックして、新しい Cloud Shell ターミナルを開きます。
次に、SSH を使用して owner インスタンスに接続し、各 Namespace にシンプルな Deployment を作成します。
- SSH を使用して「owner」インスタンスに接続します。
gcloud compute ssh gke-tutorial-owner
Ignore the error which relates to gcp auth plugin.
-
ゾーンに関するプロンプトが表示されたら、「n
」を入力してデフォルトのゾーンが使用されるようにします。
-
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}}}
- 各 Namespace にサーバーを作成します。最初は
dev
を作成します。
kubectl create -n dev -f ./manifests/hello-server.yaml
出力:
service/hello-server created
deployment.apps/hello-server created
- 次に
prod
を作成します。
kubectl create -n prod -f ./manifests/hello-server.yaml
出力:
service/hello-server created
deployment.apps/hello-server created
- 次に
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 を確認します。
-
ターミナル ウィンドウの上部にある + をクリックして、新しい Cloud Shell ターミナルを開きます。
-
SSH を使用して「auditor」インスタンスに接続します。
gcloud compute ssh gke-tutorial-auditor
Ignore the error which relates to gcp auth plugin.
-
ゾーンに関するプロンプトが表示されたら、「n
」を入力してデフォルトのゾーンが使用されるようにします。
-
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}}}
- 「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 を表示してみましょう。
- 「auditor」インスタンスで次のコマンドを実行します。
kubectl get pods -l app=hello-server --namespace=dev
出力:
NAME READY STATUS RESTARTS AGE
hello-server-6c6fd59cc9-h6zg9 1/1 Running 0 13m
- 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.
- 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 の作成と削除を試行して、監査者には読み取り専用権限しかないことを確認します。
- 「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.
- 「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 として動作します。
-
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 のイベントとログを確認して、エラーを調べます。
-
admin インスタンスで Pod のステータスを確認します。
kubectl get pods -l app=pod-labeler
出力:
NAME READY STATUS RESTARTS AGE
pod-labeler-6d9757c488-tk6sp 0/1 Error 1 1m
-
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
-
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 を一覧表示しようとしたときに、権限のエラーが発生していることがわかります。
- 次の手順では、正しい ServiceAccount を使用していることを確認します。
ServiceAccount 名を修正する
Pod の構成を調べると、カスタム サービス アカウントではなく、デフォルトの ServiceAccount が使用されていることがわかります。
-
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
次にこの修正を適用し、適用後の変更を確認します。
-
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
- Deployment 構成の変更を確認します。
kubectl get deployment pod-labeler -oyaml
変更された出力:
...
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: pod-labeler
...
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
ServiceAccount 名を修正する
権限の不足を診断する
もう一度、Pod のステータスを確認してください。まだエラーが表示されていますが、今回はメッセージが異なることがわかります。
-
admin インスタンスで Pod のステータスを確認します。
kubectl get pods -l app=pod-labeler
出力:
NAME READY STATUS RESTARTS AGE
pod-labeler-c7b4fd44d-mr8qh 0/1 CrashLoopBackOff 3 1m
この出力を表示するには、前述のコマンドの再実行が必要になる場合があります。
-
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 にもエラーが表示されます。これは、アプリケーションのログでは十分な詳細が得られない場合に役立ちます。
-
Google Cloud コンソールでナビゲーション メニューを選択し、[オペレーション] の [ロギング] をクリックします。
-
クエリビルダーのダイアログ ボックスに次のコードを貼り付けて、[クエリを実行] をクリックします。
protoPayload.methodName="io.k8s.core.v1.pods.patch"
- ログレコードの隣にある下矢印をクリックし、詳細を確認します。
アプリケーションのロールと権限を識別する
ClusterRoleBinding を使用して、ServiceAccount のロールと権限を確認します。
-
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 を一覧表示する権限のみが付与されていることがわかります。
-
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 のパッチ適用(更新)権限の追加
修正を適用し、適用後の構成を確認します。
-
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
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
アプリケーションのロールと権限を識別する
-
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 で置き換えることです。
-
admin インスタンスで、次のコマンドを実行して既存の Pod を強制終了し、Deployment コントローラで置き換えます。
kubectl delete pod -l app=pod-labeler
出力:
pod "pod-labeler-659c8c99d5-t96pw" deleted
構成が正しいことを確認する
最後に、新しい pod-labeler
が実行されていることを検証し、「updated」ラベルが適用されたことを確認します。
-
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
- 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. 破棄
ラボの作業が終了し、作成されたリソースをクリーンアップする準備ができたら、次のコマンドを実行してすべてのリソースを削除します。
-
「exit
」と入力して踏み台インスタンスからログアウトします。
-
次のコマンドを実行して環境を破棄します。
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 との契約が適用されます。