このページでは、Kubernetes に組み込まれたロールベース アクセス制御(RBAC)メカニズムを使用して、Google Kubernetes Engine(GKE)クラスタ内のリソースに対するアクションを認可する方法について説明します。
RBAC は Kubernetes のコア セキュリティ機能で、きめ細かい権限を作成して、ユーザーとワークロードがクラスタ内のリソースに対して実行できるアクションを管理できます。プラットフォーム管理者として RBAC のロールを作成し、それらのロールをサービス アカウントや Google グループなどの認証済みユーザーであるサブジェクトにバインドします。Kubernetes RBAC はデフォルトで有効になっています。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
- RBAC ポリシーの設計を改善するためのガイドラインについては、GKE RBAC のベスト プラクティスをご覧ください。
Identity and Access Management とのやり取り
GKE クラスタへのアクセス制御には、Identity and Access Management(IAM) と Kubernetes RBAC の両方を使用できます。
IAM は Kubernetes 固有のものではなく、複数の Google Cloud プロダクトの ID 管理を行います。基本的に、Google Cloud プロジェクトのレベルで機能します。
Kubernetes RBAC は Kubernetes のコア コンポーネントです。これにより、ロール(権限のセット)を作成してクラスタ内のオブジェクトやオブジェクト タイプに付与できます。
アクションを認可するために、GKE はまず RBAC ポリシーを確認します。RBAC ポリシーがない場合、GKE は IAM 権限を確認します。
GKE では、IAM と Kubernetes RBAC が連携し、いずれかのツールにより、十分な権限があるユーザーに操作の実行を許可します。デフォルトでは、Google Cloud ユーザーには Kubernetes RBAC RoleBinding がないため、これは GKE クラスタのブートストラップで重要な部分となります。
Google Cloud アカウントを使用してユーザーを認証するには、これらのアカウントを使用して認証を行うようにクライアントが構成されている必要があります。たとえば、kubectl
を使用する場合、認証を必要とするコマンドを実行する前に、Google Cloud で認証を行うように kubectl
コマンドを構成する必要があります。
ほとんどの場合、IAM の代わりに Kubernetes RBAC を使用できます。GKE ユーザーには、少なくともクラスタを含むプロジェクトの container.clusters.get
IAM 権限が必要です。この権限は、container.clusterViewer
ロールだけでなく、より権限の高いロールにも含まれています。container.clusters.get
権限は、ユーザーがプロジェクトのクラスタに対する認証を行う場合に必要ですが、ユーザーがこれらのクラスタ内でアクションを実行することは許可されません。認可は、IAM または Kubernetes RBAC によって行われます。
権限を定義して割り当てる
次のように、ClusterRole
オブジェクトと Role
オブジェクトで RBAC ルールを定義してから、それらのルールを ClusterRoleBinding
オブジェクトと RoleBinding
オブジェクトに割り当てることができます。
- ClusterRole: リソースと許可されたオペレーションのクラスタレベルのグループ化のことで、
RoleBinding
またはClusterRoleBinding
を使用してユーザーまたはグループに割り当てることができます。 - Role: リソースと許可されたオペレーションの名前空間のグループ化のことで、
RoleBinding
を使用してユーザーまたはユーザー グループに割り当てることができます。 - ClusterRoleBinding: クラスタ内のすべての名前空間のユーザーまたはグループに
ClusterRole
を割り当てます。 - RoleBinding:
Role
またはClusterRole
を特定の名前空間内のユーザーまたはグループに割り当てます。
RoleBinding
を使用してユーザーまたはグループに ClusterRole
を割り当てると、それらのユーザーとグループは、RoleBinding
で指定した名前空間のリソースにのみアクセスできます。ユーザーまたはグループがすべての名前空間のリソースにアクセスできるようにするには、代わりに ClusterRoleBinding
を使用します。
Role または ClusterRole を使用して権限を定義する
権限は、Role または ClusterRole オブジェクト内で定義します。Role が 1 つの名前空間内のリソースに対するアクセス権を定義するのに対し、ClusterRole はクラスタ全体のリソースに対するアクセス権を定義します。
Role と ClusterRole の構文は同じです。どちらにも rules
セクションがあり、ここでは、Role に対して、ルールによってオペレーションが適用され許可されたリソースを定義します。たとえば、次の Role は、accounting
名前空間のすべての Pod に対する読み取りアクセス権(get
、watch
、list
)を付与します。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: accounting
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
許可されているフィールドの詳細な一覧については、Role と ClusterRole の API ドキュメントをご覧ください。
Role
と ClusterRole
ClusterRole によって付与される権限はクラスタ全体に適用されます。ClusterRole を使用すると、Role の場合と異なる種類のリソースへのアクセスを制御できます。たとえば、次のようなものです。
- ノードなどのクラスタ スコープのリソース
- リソース以外の REST エンドポイント(
/healthz
など) - Namespace 全体の名前空間を指定されたリソース(Namespace に関係なく、クラスタ全体のすべての Pod)
RoleBinding または ClusterRoleBinding を使用してロールを割り当てる
Role または ClusterRole を作成したら、RoleBinding または ClusterRoleBinding を使用してユーザーまたはユーザー グループにロールを割り当てます。ユーザーとグループは subjects
と呼ばれ、次のいずれかになります。
Subject のタイプ | kind の値 |
name の値 |
---|---|---|
Google Cloud ユーザー アカウント | User |
Google Cloud の登録済みメールアドレス |
Kubernetes サービス アカウント | ServiceAccount |
クラスタ内の Kubernetes ServiceAccount オブジェクトの名前 |
IAM サービス アカウント | User |
自動的に生成された IAM サービス アカウントのメールアドレス |
確認済みドメインの Google グループのアドレス | Group |
gke-security-groups グループのメンバーである Google Workspace グループのメールアドレス。RBAC 向け Google グループの設定手順については、RBAC 向け Google グループを構成するをご覧ください。 |
次の RoleBinding は、ユーザー、Kubernetes サービス アカウント、IAM サービス アカウント、Google グループに pod-reader
Role を割り当てます。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: accounting
subjects:
# Google Cloud user account
- kind: User
name: janedoe@example.com
# Kubernetes service account
- kind: ServiceAccount
name: johndoe
# IAM service account
- kind: User
name: test-account@test-project.iam.gserviceaccount.com
# Google Group
- kind: Group
name: accounting-group@example.com
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
kubectl
を使用して API アクセスを確認する
kubectl
には、API 承認レイヤにすばやくクエリを実行するための auth can-i
サブコマンドが用意されています。プラットフォーム管理者として、実行できる操作を決定するために、ユーザーの権限を借用することが必要な場合があります。auth can-i
を使用して、追加の --as
フラグを渡します。
--as
フラグを指定せずに kubectl auth can-i
コマンドを実行すると、Identity and Access Management(IAM)が認可を行います。一方、--as
フラグを追加すると、Kubernetes RBAC が認可を行います。したがって、RBAC に必要な Role
オブジェクトと RoleBinding
オブジェクトを作成する必要があります。
詳細については、Checking API Access をご覧ください。
API の使用法と例
Kubernetes API を使用して RBAC に必要な Role
、ClusterRole
、RoleBinding
、ClusterRoleBinding
オブジェクトを作成する方法については、Kubernetes ドキュメントのロールベース アクセス制御による承認をご覧ください。
トラブルシューティングとデバッグ
RBAC に関する問題をデバッグするには、管理アクティビティ監査ログを使用します。これはすべてのクラスタでデフォルトで有効になっています。十分な権限がないためにリソースまたはオペレーションへのアクセスが拒否される場合は、API サーバーで RBAC DENY
エラーと、ユーザーの暗黙的および明示的なグループ メンバーシップなどの追加情報がログに記録されます。Google Groups for RBAC を使用している場合は、ログ メッセージに google groups
が表示されます。
制限事項
以降のセクションでは、Kubernetes RBAC および IAM の使用でわかりにくい点について説明します。
デフォルトの検出ロール
クラスタは、デフォルトの ClusterRole と ClusterRoleBinding のセットで作成されます。有効な認証情報で行われたリクエストは system:authenticated
グループに配置され、それ以外のリクエストは system:unauthenticated
に配置されます。
system:basic-user
ClusterRole を使用すると、SelfSubjectAccessReviews
を作成してクラスタ内の権限をテストできます。system:discovery
ロールを使用すると、クラスタに追加された CustomResourceDefinitions
に関する情報を表示できるディスカバリ API を読み取ることができます。
匿名ユーザー(system:unauthenticated
)は system:public-info-viewer
ClusterRole を受け取ります。これにより、/healthz
API と /version
API への読み取り専用アクセス権が付与されます。
system:discovery
ClusterRole で許可される API エンドポイントを確認するには、次のコマンドを実行します。
kubectl get clusterroles system:discovery -o yaml
Google Cloud VM インスタンスのサービス アカウントで発生する Forbidden エラー
VM インスタンスに userinfo-email
スコープがない場合、次のエラーが発生することがあります。
Error from server (Forbidden): error when creating ... "role-name" is forbidden: attempt to grant extra privileges:...
たとえば、VM に cloud-platform
スコープがあり、userinfo-email
スコープがないとします。VM がアクセス トークンを取得すると、Google Cloud はそのトークンを cloud-platform
のスコープに関連付けます。Kubernetes API サーバーがアクセス トークンに関連する ID を Google Cloud に確認すると、サービス アカウントのメールアドレスではなく、サービス アカウント固有の ID が返されます。
認証に成功するには、userinfo-email
スコープの新しい VM を作成するか、一意の ID を使用する新しいロール バインディングを作成します。
userinfo-email
スコープを持つ新しい VM インスタンスを作成するには、次のコマンドを実行します。
gcloud compute instances create INSTANCE_NAME \
--service-account SERVICE_ACCOUNT_EMAIL \
--scopes userinfo-email
すでに存在する VM のサービス アカウントの一意の ID を使用する新しいロール バインディングを作成するには、次の操作を行います。
サービス アカウントの一意の ID を特定します。
gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAIL
たとえば、次の出力では
my-iam-account@somedomain.com
サービス アカウントのuniqueId
が表示されています。displayName: Some Domain IAM service account email: my-iam-account@somedomain.com etag: BwWWja0YfJA name: projects/project-name/serviceAccounts/my-iam-account@somedomain.com oauth2ClientId: '123456789012345678901' projectId: project-name uniqueId: '123456789012345678901'
サービス アカウントの
uniqueId
を使用してロール バインディングを作成します。kubectl create clusterrolebinding CLUSTERROLEBINDING_NAME \ --clusterrole cluster-admin \ --user UNIQUE_ID
ロールとロール バインディングを作成または更新するための権限
Kubernetes では、次の条件を満たす場合にのみ、特定の権限を持つロールやロール バインディングを作成または更新できます。
- ロールの作成または更新: ロールに付与する同じ権限を持っている必要があります。あるいは、ロールで
escalate
動詞を実行する権限が必要です。 - ロール バインディングの作成または更新: バインドされるロールに付与されている権限と、ロール バインディングと同じスコープが付与されている必要があります。あるいは、参照されるロールで
bind
動詞を実行するための権限が必要です。
ロールで付与する権限が RBAC ではなく IAM 許可ポリシーを使用して最初に付与されている場合、ロールまたはロール バインディングのリクエストが失敗することがあります。たとえば、IAM 権限 container.pods.*
と container.roles.create
が付与されたユーザーからの、次のロール作成リクエストについて考えてみます。
kubectl create role allowed-to-view-pods --resource pods --verb list,get
IAM を使用して、ユーザーにこれらの権限のみが付与されていた場合、次のエラーが発生する可能性があります。
Error from server (Forbidden): clusterroles.rbac.authorization.k8s.io "allowed-to-view-pods" is forbidden:
user "caller@example.com" (groups=["system:authenticated"]) is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["pods"], Verbs:["list" "get"]}
この制限を緩和するには、IAM ではなく RBAC を使用して、呼び出し元にこのロールの権限を付与します。
代わりに、RBAC または IAM を使用して、呼び出し元に escalate
動詞、bind
動詞、またはそれらの両方を付与できます。ただし、呼び出し元はどのロールにも任意の権限を付与可能になるため、GKE ではこの方法はおすすめしません。
次のステップ
- IAM ポリシーの作成方法を確認する。
- RBAC 用に Google グループを構成する方法を学習する。