役割ベースのアクセス制御

このページでは、Kubernetes が提供する役割ベースのアクセス制御(RBAC)システムの概要と、Google Kubernetes Engine で Kubernetes RBAC を使用する方法について説明します。

概要

Kubernetes には役割ベースのアクセス制御(RBAC)メカニズムが組み込まれています。このメカニズムを使用すると、権限セットを構成し、特定の Google Cloud ユーザーまたはユーザー グループがクラスタやクラスタの特定の名前空間内にある Kubernetes オブジェクトを操作する方法を定義できます。

Kubernetes RBAC はデフォルトで有効になっています。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Enable Google Kubernetes Engine API を有効にする
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト 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 クラスタへのアクセス制御には、Cloud Identity and Access Management Kubernetes RBAC の両方を使用できます。

  • Cloud IAM は Kubernetes 固有のものではなく、複数の Google Cloud プロダクトの ID 管理を行います。基本的に、Google Cloud プロジェクトのレベルで機能します。

  • Kubernetes RBAC は Kubernetes のコア コンポーネントです。これにより、役割(権限のセット)を作成してクラスタ内のオブジェクトやオブジェクト タイプに付与できます。

GKE では、Cloud IAM と Kubernetes RBAC が連携し、いずれかのツールにより、十分な権限があるユーザーに操作の実行を許可します。デフォルトでは、Google Cloud ユーザーには Kubernetes RBAC RoleBinding がないため、これは GKE クラスタのブートストラップで重要な部分となります。

Google Cloud アカウントを使用してユーザーを認証するには、これらのアカウントを使用して認証を行うようにクライアントが構成されている必要があります。たとえば、kubectl を使用する場合、認証を必要とするコマンドを実行する前に、Google Cloud で認証を行うように kubectl コマンドを構成する必要があります。

v1.11.x 以前の GKE クラスタで Kubernetes RBAC を使用する場合の前提条件

GKE v1.11.x 以前の GKE クラスタでは、Cloud IAM は Kubernetes RBAC のRole または ClusterRole を作成する権限を付与できません。ただし、Cloud 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 のユーザー アカウントまたは Cloud IAM サービス アカウントにのみ役割を付与できました。GKE 向け Google グループ(ベータ版)では、G Suite Google グループのメンバーに役割を付与できます。このメカニズムでは、ユーザーとグループは Kubernetes や Cloud Console の外部から G Suite 管理者によって管理されるので、クラスタ管理者がユーザーの詳細情報を維持する必要はありません。また、既存のユーザー アカウント管理機能と連携することもできます。たとえば、社員が退職したときに、そのユーザーのアクセス権を取り消すことができます。

この機能を使用するには、G Suite Google グループを構成しクラスタを作成してこの機能を有効にします。さらに、これらの Google グループにクラスタ権限のセットを関連付けます。

RBAC で使用する Google グループの構成

この機能を使用するクラスタの構成方法と Kubernetes RBAC で G Suite Google グループを参照する構文については、このトピックの後半で説明します。まず、次の手順で Google グループを設定します。

  1. ドメインに、gke-security-groups@[yourdomain.com] という名前の G Suite Google グループを作成します。グループ名は gke-security-groups にする必要があります。
  2. クラスタに別の権限を持つユーザー グループまたはグループを作成します(まだ存在しない場合)。
  3. これらのグループ(ユーザーではありません)を gke-security-groups@[yourdomain.com] のメンバーシップに追加します。

クラスタのリソースを作成、変更、表示する権限がグループのメンバーシップに基づいてユーザーに付与されているかどうか確認するため、GKE は、ユーザーがアクセス権を持つグループのメンバーかどうかを確認し、グループがドメインの gke-security-groups グループのメンバーかどうかを確認します。

G Suite Google グループのメンバーシップに関する情報は、しばらくの間キャッシュに保存されます。グループのメンバーシップに対する変更がすべてのクラスタに反映されるまでに数分かかることがあります。

GKE 向け Google グループを使用するクラスタの構成

G Suite Google グループ管理者がグループを設定したら、gcloud コマンドで新しいクラスタを作成し、独自のドメイン名を使用して --security-group="gke-security-groups@[yourdomain.com]" オプションを追加します。次に、クラスタ作成コマンドの例を示します。

gcloud beta container clusters create my-cluster \
  --security-group="gke-security-groups@[yourdomain.com]"

これで、G Suite 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 名前空間のすべてのポッドに対する読み取りアクセス権(getwatchlist)を付与します。

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"]

RoleClusterRole

ClusterRole によって付与される権限はクラスタ全体に適用されます。ClusterRole を使用すると、Role の場合と異なる種類のリソースへのアクセスを制御できます。たとえば、次のようなものです。

  • ノードなどのクラスタ スコープのリソース
  • リソース以外のエンドポイント(/healthz など)
  • 名前空間全体の名前空間を指定されたリソース(名前空間に関係なく、クラスタ全体のすべてのポッド)

RoleBinding または ClusterRoleBinding を使用した役割の割り当て

Role または ClusterRole を作成したら、RoleBinding または ClusterRoleBinding を使用してユーザーまたはユーザー グループに役割を割り当てます。ユーザーとグループは subjects と呼ばれ、次のいずれかになります。

Subject のタイプ kind の値 name の値
Google Cloud ユーザー アカウント User Google Cloud の登録済みメールアドレス
Kubernetes サービス アカウント ServiceAccount クラスタ内の Kubernetes ServiceAccount オブジェクトの名前
Cloud IAM サービス アカウント User 自動的に生成された Cloud IAM サービス アカウントのメールアドレス
確認済みドメインの G Suite Google グループのアドレス(ベータ版) Group Google グループ gke-security-groups@[yourdomain.com] のメンバーになっている Google グループのメールアドレス。

次の RoleBinding は、ユーザー、Kubernetes サービス アカウント、Cloud 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
# Cloud IAM service account
- kind: User
  name: test-account@test-project-123456.google.com.iam.gserviceaccount.com
# G Suite Google Group
- kind: Group
  name: accounting-group@example.com
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

API の使用法と例

Kubernetes API を使用して RBAC に必要な RoleClusterRoleRoleBindingClusterRoleBinding オブジェクトを作成する方法については、Kubernetes ドキュメントの役割ベースのアクセス制御による承認をご覧ください。

注意点

以降のセクションでは、Kubernetes RBAC の使用でわかりにくい点について説明します。

デフォルトの検出役割

クラスタは、デフォルトの ClusterRole と ClusterRoleBinding のセットで作成されます。有効な認証情報で行われたリクエストは system:authenticated グループに配置され、それ以外のリクエストは system:unauthenticated に配置されます。バージョン 1.14 以前の Kubernetes では、system:authenticatedsystem:unauthenticated の両方がデフォルトで system:basic-usersystem:discovery の ClusterRole を付与します。

system:basic-user ClusterRole を使用すると、SelfSubjectAccessReviews の作成をユーザーに許可できます。これにより、ユーザーはクラスタ内での自身の権限をテストできます。system:discovery 役割を使用すると、Discovery API の読み取りをユーザーに許可できます。この API を使用すると、クラスタに追加された CustomResourceDefinitions の情報を取得できます。

Kubernetes 1.14 では、匿名ユーザー(system:unauthenticated)に system:basic-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 スコープがない場合に発生します。たとえば、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 を使用する新しい役割バインディングを作成するには、次の操作を行います。

  1. サービス アカウントの一意の ID を特定します。

    gcloud iam service-accounts describe [SERVICE_ACCOUNT_EMAIL]
    
  2. 一意の ID を使用して、役割バインディングを作成します。

    kubectl create clusterrolebinding [CLUSTERROLEBINDING_NAME] \
      --clusterrole cluster-admin \
      --user [UNIQUE_ID]
    

次のステップ