このページでは、Kubernetes が提供するロールベースのアクセス制御(RBAC)システムの概要と、Google Kubernetes Engine(GKE)で Kubernetes RBAC を使用する方法について説明します。
概要
Kubernetes にはロールベースのアクセス制御(RBAC)メカニズムが組み込まれています。このメカニズムを使用すると、権限セットを構成し、特定の Google Cloud ユーザーまたはユーザー グループがクラスタやクラスタの特定の Namespace 内にある Kubernetes オブジェクトを操作する方法を定義できます。
Kubernetes RBAC はデフォルトで有効になっています。
始める前に
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API が有効になっていることを確認します。 Google Kubernetes Engine API の有効化
- Cloud SDK がインストール済みであることを確認します。
次のいずれかの方法で gcloud
のデフォルトの設定を指定します。
gcloud init
。デフォルトの設定全般を確認する場合に使用します。gcloud config
。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。
gcloud init の使用
エラー One of [--zone, --region] must be supplied: Please specify
location
を受信した場合は、このセクションの内容を実施します。
-
gcloud init
を実行して、次の操作を行います。gcloud init
リモート サーバーで SSH を使用している場合は、
--console-only
フラグを指定して、コマンドがブラウザを起動しないようにします。gcloud init --console-only
- 手順に従って
gcloud
を承認し、Google Cloud アカウントを使用します。 - 新しい構成を作成するか、既存の構成を選択します。
- Google Cloud プロジェクトを選択します。
- デフォルトの Compute Engine ゾーンを選択します。
gcloud config の使用
- デフォルトのプロジェクト ID を設定します。
gcloud config set project PROJECT_ID
- ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
gcloud config set compute/zone COMPUTE_ZONE
- リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
gcloud config set compute/region COMPUTE_REGION
gcloud
を最新バージョンに更新します。gcloud components update
Identity and Access Management とのやり取り
GKE クラスタへのアクセス制御には、Identity and Access Management(IAM) と Kubernetes RBAC の両方を使用できます。
IAM は Kubernetes 固有のものではなく、複数の Google Cloud プロダクトの ID 管理を行います。基本的に、Google Cloud プロジェクトのレベルで機能します。
Kubernetes RBAC は Kubernetes のコア コンポーネントです。これにより、ロール(権限のセット)を作成してクラスタ内のオブジェクトやオブジェクト タイプに付与できます。
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 によって行われます。
v1.11.x 以前の GKE クラスタで Kubernetes RBAC を使用する場合の前提条件
GKE v1.11.x 以前の GKE クラスタでは、IAM は Kubernetes RBAC の Role または ClusterRole を作成する権限を付与できません。ただし、IAM ロールの Kubernetes Engine 管理者を使用すると、Kubernetes RBAC の RoleBinding または ClusterRoleBinding の作成権限を任意のユーザー(自身を含む)に付与できます。これにより、Google Cloud ユーザーを事前定義の RBAC ロールにバインドできます。
事前定義の cluster-admin
RBAC ロールは、クラスタに対する完全な権限をユーザーに付与します。したがって、RBAC の Role と ClusterRole を作成できるようにユーザーをブートストラップするには、次のコマンドを実行します。user-account は、対象ユーザーの Google Cloud ログイン メールアドレスに置き換えます。
kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin \ --user user-account
GKE 向け Google グループ
以前は、Google Cloud のユーザー アカウントまたは IAM サービス アカウントにのみロールを付与できました。GKE 向け Google グループ(ベータ版)を使用すると、ビジネス向け Google グループのグループ メンバーにロールを付与できます。このメカニズムでは、ユーザーとグループ自体は Kubernetes や Cloud Console の外部から Google Workspace 管理者によって管理されるため、クラスタ管理者はユーザーに関する詳細情報を維持する必要はありません。また、既存のユーザー アカウント管理機能と連携することもできます。たとえば、社員が退職したときに、そのユーザーのアクセス権を取り消すことができます。
この機能を使用するには、次のタスクを行います。
- 要件を満たします。
- Google グループを構成します。
- 機能を有効にしてクラスタを作成します。
- Google グループをクラスタ権限のセットに関連付けます。
要件
GKE 向け Google グループを使用するには、次の要件があります。
- Google Workspace または Cloud Identity のサブスクリプションが必要です。
RBAC で使用する Google グループの構成
この機能を使用するクラスタの構成方法と Kubernetes RBAC で Google グループを参照する構文については、このトピックの後半で説明します。まず、次の手順で Google グループを設定します。
ドメインに、
gke-security-groups@yourdomain.com
という名前の Google グループを作成します。グループ名はgke-security-groups
にする必要があります。gke-security-groups
グループにグループ メンバーに対するメンバーの表示権限があることを確認します。Google Workspace 管理コンソールで設定する方法については、こちらの記事をご覧ください。Google Workspace でのグループの管理については、グループ ヘルプセンターをご覧ください。
クラスタに別の権限を持つユーザー グループまたはグループを作成します(まだ存在しない場合)。各グループには、グループ メンバーに対するメンバーの表示権限が必要です。
これらのグループ(ユーザーではありません)を
gke-security-groups@yourdomain.com
のメンバーシップに追加します。
クラスタのリソースを作成、変更、表示する権限がグループのメンバーシップに基づいてユーザーに付与されているかどうか確認するため、GKE は、ユーザーがアクセス権を持つグループのメンバーかどうか、およびグループがドメインの gke-security-groups
グループの直接的なメンバーかどうかを確認します。
Google グループのメンバーシップに関する情報は、しばらくの間キャッシュに保存されます。グループのメンバーシップに対する変更がすべてのクラスタに反映されるまでに数分かかることがあります。グループの変更によるレイテンシに加えて、クラスタ上のユーザー認証情報の標準的なキャッシュは約 1 時間です。
GKE 向け Google グループを使用するクラスタの構成
Google グループ管理者がグループを設定したら、gcloud
コマンドで新しいクラスタを作成します。--security-group="gke-security-groups@yourdomain.com"
フラグを追加して独自のドメイン名を指定します。
以下に、cluster create コマンドの例を示します。
gcloud beta container clusters create cluster-name \
--security-group="gke-security-groups@yourdomain.com"
これで、Google グループを参照する Role、ClusterRole、RoleBinding、ClusterRoleBinding を作成できます。
権限の定義と割り当て
RBAC 権限を定義するには、次の種類の Kubernetes オブジェクトを作成します。
- ClusterRole または Role: リソースタイプとオペレーションのセットを定義します。これは、クラスタ内のユーザーまたはユーザー グループ(ClusterRole の場合)または名前空間(Role)に割り当てることができますが、ユーザーまたはユーザー グループは指定しません。
- ClusterRoleBinding または RoleBinding: ユーザーまたはユーザー グループに ClusterRole または Role を割り当てます。ClusterRoleBinding は ClusterRole と一緒に使用し、RoleBinding は ClusterRole または Role と一緒に使用します。
RBAC ロールは純粋に付加的なものであり、「拒否」ルールはありません。RBAC ロールを構成するときは、クラスタ リソースへのアクセスをユーザーに「許可する」ことについて考える必要があります。
Role または ClusterRole を使用した権限の定義
権限は、Role または ClusterRole オブジェクト内で定義します。Role が 1 つの名前空間内のリソースに対するアクセス権を定義するのに対し、ClusterRole はクラスタ全体のリソースに対するアクセス権を定義します。
Role と ClusterRole の構文は同じです。どちらにも rules
セクションがあります。ここには、Role に関連する名前空間、リソースタイプ、許可されるオペレーションを定義します。たとえば、次の Role は、accounting
名前空間のすべてのポッドに対する読み取りアクセス権(get
、watch
、list
)を付与します。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: accounting
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
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 |
Google グループ gke-security-groups@ yourdomain.com のメンバーになっている 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-123456.google.com.iam.gserviceaccount.com
# Google Group
- kind: Group
name: accounting-group@example.com
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
API の使用法と例
Kubernetes API を使用して RBAC に必要な Role
、ClusterRole
、RoleBinding
、ClusterRoleBinding
オブジェクトを作成する方法については、Kubernetes ドキュメントの役割ベースのアクセス制御による承認をご覧ください。
トラブルシューティングとデバッグ
RBAC に関する問題をデバッグするには、管理アクティビティ監査ログを使用します。これはすべてのクラスタでデフォルトで有効になっています。十分な権限がないためにリソースまたはオペレーションへのアクセスが拒否される場合は、API サーバーで RBAC DENY
エラーと、ユーザーの暗黙的および明示的なグループ メンバーシップなどの追加情報がログに記録されます。Google Groups for GKE を使用している場合は、ログメッセージに google groups
が表示されます。
Google グループとの統合に関する問題のデバッグ
次の手順では、ログを表示して、クラスタが RBAC の RoleBinding で Google グループを使用するように正常に構成されているかどうかを検証できます。
要件
ログを調べる前に、次のことを確認してください。
- 少なくとも 1 時間以上は、テスト対象のクラスタの操作(
kubectl
コマンドの実行など)をしていない。認証は 1 時間キャッシュされ、リクエストが発生したときにログに記録されるようにする必要があります。 gke-security-groups
に含まれるグループの 1 つ以上のメンバーである。これにより、一部の Google グループ情報がログに入力されます。
ログの構成
ログを使用して RBAC で Google グループをデバッグするには、次の手順を行います。
Google Cloud プロジェクトのデータアクセスロギングを有効にします。ロギングを有効にするには、次の手順を行います。
Cloud Console で、[IAM] メニューの [監査ログ] ページに移動します。
表で、[Kubernetes Engine API]を選択します。
[ログの種類]メニューで、次のいずれかを選択します。
- 管理読み取り
- データ読み取り
- データ書き込み
[保存] をクリックします。
監査ロギングを有効にする方法の詳細については、Cloud 管理ツールのドキュメントの Cloud Console でのデータアクセス ログの構成をご覧ください。
クラスタで
kubectl
を使用してコマンドを実行します。これはkubectl create ns helloworld
のような簡単なコマンドで構いません。[ログビューア] ページでカスタムクエリを入力します。クエリを実行するには:
Cloud Console で、[Logging] メニューの [ログビューア] ページに移動します。
ページ上部の [クエリのプレビュー] ボックスにある矢印をクリックします。
表示されるプルダウン ボックスで、次のクエリをコピーして貼り付けます。
resource.type="k8s_cluster" resource.labels.location="cluster-region" resource.labels.cluster_name="cluster-name" protoPayload.resourceName="authorization.k8s.io/v1beta1/subjectaccessreviews" protoPayload.response.spec.user="email-address"
ここで
- cluster-region は、クラスタのリージョンまたはゾーンです。
- cluster-name は、クラスタの名前です。
- email-address は、Google アカウントの登録メールアドレスです。
[クエリを実行] を選択します。少なくとも 1 つの結果が表示されます。そうでない場合は、時間範囲を広げてみてください。
確認するクラスタを選択します。
[ネストされたフィールドを展開] をクリックします。
フィールド
protoPayload.request.spec.group
には、次のようなグループが含まれます。gke-security-group
のメンバーであるグループ。- 自分自身がメンバーであるグループ。
このリストは、メンバーになっているグループのセットと一致する必要があります。グループが存在しない場合は、グループの設定方法に問題がある可能性があります。
必要に応じて、データアクセス ロギングを以前の設定に戻します。
制限事項
以降のセクションでは、Kubernetes RBAC の使用でわかりにくい点について説明します。
デフォルトの検出役割
クラスタは、デフォルトの ClusterRole と ClusterRoleBinding のセットで作成されます。有効な認証情報で行われたリクエストは system:authenticated
グループに配置され、それ以外のリクエストは system:unauthenticated
に配置されます。バージョン 1.14 以前の Kubernetes では、system:authenticated
と system:unauthenticated
の両方がデフォルトで system:basic-user
と system:discovery
の ClusterRole を付与します。
system:basic-user
ClusterRole を使用すると、SelfSubjectAccessReviews
を作成してクラスタ内の権限をテストできます。system:discovery
ロールを使用すると、クラスタに追加された CustomResourceDefinitions
に関する情報を表示できるディスカバリ API を読み取ることができます。
Kubernetes 1.14 では、匿名ユーザー(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
次のステップ
- IAM ポリシーの作成方法を確認する。