ロールベースアクセス制御

Kubernetesでは、ユーザーまたはアプリケーション固有のサービスアカウントにロールを付与することは、アプリケーションが指定した範囲内で動作することを保証するためのベストプラクティスです。サービスアカウントの権限の詳細については、公式Kubernetesドキュメントをご覧ください。公式Kubernetesドキュメント

Kubernetes 1.6以降、ロールベースアクセス制御はデフォルトで有効になっています。RBACを使用すると、組織内のユーザーとその役割に応じて、許可されるアクションの種類を指定できます。

RBACを使用すると、次のことができます。

  • 管理者に特権操作(新しいロールなど、クラスター全体の資源の作成)を付与する
  • ユーザーがリソース(Pod、永続ボリューム、デプロイメント)を作成する能力を、特定の名前空間、またはクラスター全体の範囲(リソースクォータ、ロール、カスタムリソース定義)に制限する
  • ユーザーが特定の名前空間またはクラスター全体の範囲でリソースを表示する能力を制限する。

このガイドは、ユーザーのKubernetes APIとのインタラクションの範囲を制限したい管理者向けです。

ユーザーアカウントの管理

すべてのKubernetesクラスタには、Kubernetesによって管理されるサービスアカウントと、通常のユーザーの2つのカテゴリのユーザーが存在します。

通常のユーザーは、外部の独立したサービスによって管理されると想定されています。秘密鍵を配布する管理者、KeystoneやGoogleアカウントのようなユーザーストア、ユーザー名とパスワードのリストを含むファイルなどです。この点で、Kubernetesには通常のユーザーアカウントを表すオブジェクトはありません。通常のユーザーは、API呼び出しを通じてクラスタに追加することはできません。

これとは対照的に、サービスアカウントはKubernetes APIによって管理されるユーザーです。それらは特定の名前空間にバインドされ、APIサーバーによって自動的に作成されるか、API呼び出しによって手動で作成されます。サービスアカウントは、シークレットとして保存された一連の資格情報に関連付けられており、クラスタ内のプロセスがKubernetes APIと通信できるようにPodにマウントされます。

APIリクエストは、通常のユーザーまたはサービスアカウントに関連付けられているか、匿名リクエストとして扱われます。これは、ワークステーションでkubectlを入力する人間のユーザーから、ノード上のkubelet、コントロールプレーンのメンバーまで、クラスタの内外にあるすべてのプロセスは、APIサーバーへのリクエストを行う際に認証する必要があるか、匿名ユーザーとして扱われることを意味します。

ロール、クラスタロール、ロールバインディング、クラスタロールバインディング

Kubernetesでは、ユーザーアカウントとサービスアカウントは、アクセスを許可されたリソースのみを表示および編集できます。このアクセスは、ロールとロールバインディングを使用して付与されます。ロールとロールバインディングは特定の名前空間にバインドされており、ユーザーに、そのロールがアクセス権限を与えるその名前空間内のリソースを表示および/または編集する機能を付与します。

クラスタスコープでは、これらはクラスタロールとクラスタロールバインディングと呼ばれます。ユーザーにクラスタロールを付与すると、クラスタ全体のすべてのリソースを表示および/または編集するアクセス権が付与されます。クラスタスコープ(名前空間、リソースクォータ、ノード)のリソースを表示および/または編集するためにも必要です。

クラスタロールは、ロールバインディングでの参照を通じて特定の名前空間にバインドできます。admineditviewのデフォルトクラスタロールは、この方法で一般的に使用されます。

これらは、Kubernetesでデフォルトで利用可能ないくつかのクラスタロールです。これらはユーザー向けのロールとして意図されています。これには、スーパーユーザーロール(cluster-admin)と、より詳細なアクセス権を持つロール(admineditview)が含まれます。

デフォルトクラスタロールデフォルトクラスタロールバインディング説明
cluster-adminsystem:mastersグループ任意のリソースに対して任意のアクションを実行するためのスーパーユーザーアクセスを許可します。ClusterRoleBindingで使用する場合、クラスタ内のすべてのリソースとすべての名前空間に対する完全な制御権を与えます。RoleBindingで使用する場合、名前空間自体を含む、rolebindingの名前空間内のすべてのリソースに対する完全な制御権を与えます。
adminなし管理者アクセスを許可し、RoleBindingを使用して名前空間内で付与されることを意図しています。RoleBindingで使用する場合、名前空間内のほとんどのリソースに対する読み書きアクセスを許可し、名前空間内のロールとロールバインディングを作成する機能も含まれます。リソースクォータまたは名前空間自体への書き込みアクセスは許可されません。
editなし名前空間内のほとんどのオブジェクトに対する読み書きアクセスを許可します。ロールまたはロールバインディングの表示または変更は許可されません。
viewなし名前空間内のほとんどのオブジェクトを表示するための読み取り専用アクセスを許可します。ロールまたはロールバインディングの表示は許可されません。エスカレートする可能性があるため、シークレットの表示は許可されません。

RBACを使用したユーザーアカウントのアクセスの制限

ロールベースアクセス制御の基本を理解したので、管理者がユーザーのアクセス範囲を制限する方法について説明しましょう。

例:特定の名前空間への読み書きアクセスをユーザーに付与する

ユーザーのアクセスを特定の名前空間に制限するには、editロールまたはadminロールを使用できます。チャートがロールとロールバインディングを作成または操作する場合、adminクラスタロールを使用する必要があります。

さらに、cluster-adminアクセス権を持つRoleBindingを作成することもできます。名前空間スコープでユーザーにcluster-adminアクセス権を付与すると、名前空間自体を含む、名前空間内のすべてのリソースに対する完全な制御権が与えられます。

この例では、editロールを持つユーザーを作成します。最初に、名前空間を作成します。

$ kubectl create namespace foo

次に、その名前空間にRoleBindingを作成し、ユーザーにeditロールを付与します。

$ kubectl create rolebinding sam-edit
    --clusterrole edit \​
    --user sam \​
    --namespace foo

例:クラスタスコープへの読み書きアクセスをユーザーに付与する

ユーザーがクラスタスコープリソース(名前空間、ロール、カスタムリソース定義など)をインストールするチャートをインストールする場合、クラスタスコープの書き込みアクセスが必要です。

そのためには、ユーザーにadminまたはcluster-adminアクセス権を付与します。

ユーザーにcluster-adminアクセス権を付与すると、kubectl drainやその他の管理タスクを含む、Kubernetesで使用可能なすべてのリソースへのアクセス権が付与されます。代わりにユーザーにadminアクセス権を提供するか、ユーザーのニーズに合わせてカスタムクラスタロールを作成することを強くお勧めします。

$ kubectl create clusterrolebinding sam-view
    --clusterrole view \​
    --user sam

$ kubectl create clusterrolebinding sam-secret-reader
    --clusterrole secret-reader \​
    --user sam

例:特定の名前空間への読み取り専用アクセスをユーザーに付与する

シークレットを表示するためのクラスタロールは利用できないことに気付いたかもしれません。viewクラスタロールは、エスカレーションに関する懸念事項のため、ユーザーにシークレットへの読み取りアクセス権を付与しません。Helmはデフォルトでリリースメタデータをシークレットとして保存します。

ユーザーがhelm listを実行するには、これらのシークレットを読み取る権限が必要です。そのため、特別なsecret-reader ClusterRoleを作成します。

cluster-role-secret-reader.yamlというファイルを作成し、以下の内容を記述します。

apiVersion: rbac.authorization.k8s.io/v1​
kind: ClusterRole​
metadata:​
  name: secret-reader​
rules:​
- apiGroups: [""]​
  resources: ["secrets"]​
  verbs: ["get", "watch", "list"]

次に、以下のコマンドを使用してClusterRoleを作成します。

$ kubectl create -f clusterrole-secret-reader.yaml​

完了したら、ユーザーにほとんどのリソースに対する読み取りアクセス権を付与し、その後、シークレットへの読み取りアクセス権を付与します。

$ kubectl create namespace foo

$ kubectl create rolebinding sam-view
    --clusterrole view \​
    --user sam \​
    --namespace foo

$ kubectl create rolebinding sam-secret-reader
    --clusterrole secret-reader \​
    --user sam \​
    --namespace foo

例:クラスタスコープでユーザーに読み取り専用のアクセス権を付与します。

特定のシナリオでは、ユーザーにクラスタスコープのアクセス権を付与することが有益な場合があります。例えば、ユーザーがhelm list --all-namespacesコマンドを実行する場合、APIはユーザーがクラスタスコープの読み取りアクセス権を持っていることを要求します。

そのためには、上記のようにユーザーにviewsecret-readerの両方のアクセス権を、ClusterRoleBindingを使用して付与します。

$ kubectl create clusterrolebinding sam-view
    --clusterrole view \​
    --user sam

$ kubectl create clusterrolebinding sam-secret-reader
    --clusterrole secret-reader \​
    --user sam

補足事項

上記の例では、Kubernetesで提供されるデフォルトのClusterRoleを使用しています。ユーザーに付与されるリソースへのアクセス制御をより詳細に行うには、Kubernetesのドキュメントで独自のCustom RolesとClusterRolesの作成方法を確認してください。