Kubernetes

kubernetesでRBAC(Role based access control)認証を理解しながら設定を試してみる

kubernetes RBAC認証をやってみる

概要

ロールベースのアクセス制御 (RBAC:Role-based access controlの) は、組織内の個々のユーザーの役割に基づいて、
システムへのアクセス権限を管理する仕組みたいですね。

RBACの仕組みを考える上で、必要な知識をざっくり理解してから設定を試してみたいと思います。

環境

  • minikube version: v1.32.0
  • Kubernetes v1.28.3
  • Ubuntu 22.04.4 LTS(WSL)

RBACの前提知識

RBACには、ユーザに必要なKubernetes操作(API)権限を付与するものです。

なので、ユーザとKubernetes操作(API)がどんなものが理解しないと
どんな権限(Role)を設定していいかわからないと思います。

まず、「Kubernetesのユーザ」「KubernetesのAPI」をざっくり理解しましょう。

Kubernetesのユーザとは

Kubernetesクラスターには、ユーザーが「サービスアカウント」と「通常のユーザー」の2種類あります。

サービスアカウントはシステム間のやり取り用(CDCIツールとかはこれ)、
通常のユーザーは人間用(kubectlコマンドの操作はこれ)ですね。

詳しくは公式ドキュメントを参照してください。

KubernetesのAPIとは

概要

Kubernetesは、すべての操作とコンポーネント間の通信、および外部ユーザーのコマンドは、
REST API にて操作を行っています。

詳しくは以下ドキュメントを参照してください。

RBACでルールを設定するには、このAPIの仕様をある程度理解した方がいいので、
もう少しだけKubernetes API の理解を深めていきましょう。

Kubernetesの API形式は?

REST API呼び出しなので、全てのリソースはURL形式でアクセスできるパスがあります。

すべてのリソース タイプは、クラスター ( /apis/GROUP/VERSION/*) または、
名前空間 ( /apis/GROUP/VERSION/namespaces/NAMESPACE/*) の形式のようです。

詳しくは以下ドキュメントを参照してください。

リソース タイプのざっくりとした一覧はここが参考になります。

また、リソースは全てAPIグループ配下にあります。主なグループは以下になります。

  • core(legacyとも呼ばれる)グループは、RESTパス /api/v1 にある
  • 名前付きのグループは、RESTパス /apis/$GROUP_NAME/$VERSION にある

詳細はここで確認ください。

リソース(Pod)がどのグループを使っているのかは”kubectl api-resources ”コマンドで確認することができます。

詳細は過去に書いたこの記事を参照してください。

https://0222-nnn.com/kubernetes-kubectl-api-resources-コマンドでapi-リソースを調べてみる/#st-toc-h-11

リソースの詳細なURL(API)はここで確認できます。

KubernetesのAPIリソースに対する操作は?

Kubernetes API は、HTTP 経由で提供されるリソースベース (RESTful) のプログラム インターフェースなので
標準の HTTP メソッドのPOST、PUT、PATCH、DELETE、GET にてリソースの取得、作成、更新、削除による操作を行います。

詳細はここで確認ください。

KubernetesのRBACとは?

KubernetesのRBACを設定するには、「認可」「オブジェクト」「権限」の知識が必要になります。
この点をざっくり理解していきましょう。

Kubernetesの認可とは?

Kubernetes APIへのアクセスコントロールは、ユーザ認証(Authentication)を確認後、
リクエストのリソースに対して認可(Authorization)されているか確認します。

Kubernetes API サーバーでは、認可(Authorization)がいくつか存在しており、
RBACとは、Kubernetes API サーバーのいくつかある認可モードのうちの1つです。

詳細はここで確認ください。

KubernetesのRBACのオブジェクとは?

RBACでは、「Role」「ClusterRole」「RoleBinding」「ClusterRoleBinding」の
4種類のオブジェクトがあります。

Role、ClusterRole には、権限のセットを表すルールが含まれています。
権限はホワイトリスト(許可)方式でブラックリスト(拒否)方式はありません。

RoleBinding、ClusterRoleBindingは、ロール(Role、ClusterRole )で定義された権限を
ユーザー又はサービスアカウントに紐づけ保持します。

4種類(Role、ClusterRole、 RoleBinding、ClusterRoleBinding)の主な違いは以下です。

オブジェクト 説明
ClusterRole 任意の Namespace またはクラスタ全体に適用できる一連の権限。
Role 1 つの Namespace に制限されている一連の権限。
RoleBinding Roleまたは ClusterRoleを特定の Namespace 内のユーザーやサービスアカウントにバインドします。
ClusterRoleBinding クラスタ内のすべての Namespace のユーザーやサービスアカウントにClusterRoleをバインドします。

主な用途としては、Namespace 内でロールを定義する場合は Role を使用し、
クラスター全体でロールを定義する場合は ClusterRole を使用します。

ちなみに、Role と ClusterRole は似ていますが、Kubernetes のオブジェクトは Namespace に属するか、属さないかのいずれかであるため、両者は別々に定義されています。

詳細はここで確認ください。

RoleとClusterRoleの操作権限について

Kubernetesでは、APIリソースに対する操作は、HTTP メソッド(POST、PUT、PATCH、DELETE、GET )にて実行しますが、これをAPI verbsと呼ぶようです。

Kubernetes API の get, create, update, patch, delete, proxy は、それぞれ特定の1つのリソースに対して操作を行います。

一方、list は複数のリソースの一覧を取得し、watch はリソースの状態の変化をリアルタイムで監視します。deletecollection は、特定の条件に合致する複数のリソースを一括で削除する操作です。

HTTPメソッドとAPI verbs を一覧にすると以下のようになります。

HTTP メソッド request verb kubectl 例
POST create kubectl create XX
GET, HEAD get (個別リソース) kubectl get po XX
list (リソースの一覧) kubectl get po
watch (リソースの変更監視) kubectl get po XX --watch
PUT update kubectl replace XX
PATCH patch kubectl patch XX
DELETE delete (個別リソース) kubectl delete XX
deletecollection (リソースの一括削除) kubectl delete XX

詳細はここで確認ください。

Kubernetesの操作権限は、このapiGroups、resources、verbsを組み合わせたルールをRole又はClusterRoleで設定します。

ルール設定に必要なapiGroups、resources、verbsは"kubectl api-resources”コマンドを使えば、簡単に確認できます。

  • コマンド例
kubectl api-resources --namespaced=true      # 名前空間付きのすべてのリソースを表示します
kubectl api-resources --namespaced=false     # 名前空間のないすべてのリソースを表示します
kubectl api-resources -o wide                # すべてのリソースを拡張された形(別名 "wide")で表示します
kubectl api-resources --api-group=apps       # "apps" APIグループのすべてのリソースを表示します
  • 実行例
tech-0222@MSI:~$ kubectl api-resources --namespaced=true
NAME                        SHORTNAMES   APIVERSION                     NAMESPACED   KIND
bindings                                 v1                             true         Binding
configmaps                  cm           v1                             true         ConfigMap
endpoints                   ep           v1                             true         Endpoints
events                      ev           v1                             true         Event
limitranges                 limits       v1                             true         LimitRange
persistentvolumeclaims      pvc          v1                             true         PersistentVolumeClaim

tech-0222@MSI:~$ kubectl api-resources --namespaced=false
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
componentstatuses                 cs           v1                                     false        ComponentStatus
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumes                 pv           v1                                     false        PersistentVolume
tech-0222@MSI:~$ kubectl api-resources -o wide
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND                             VERBS
     CATEGORIES
bindings                                       v1                                     true         Binding                          create

componentstatuses                 cs           v1                                     false        ComponentStatus                  get,list

configmaps                        cm           v1                                     true         ConfigMap                        create,delete,deletecollection,get,list,patch,update,watch
endpoints                         ep           v1                                     true         Endpoints                        create,delete,deletecollection,get,list,patch,update,watch
events                            ev           v1                                     true         Event                            create,delete,deletecollection,get,list,patch,update,watch
limitranges                       limits       v1                                     true         LimitRange                       create,delete,deletecollection,get,list,patch,update,watch
namespaces                        ns           v1                                     false        Namespace                        create,delete,get,list,patch,update,watch

tech-0222@MSI:~$ kubectl api-resources --api-group=apps
NAME                  SHORTNAMES   APIVERSION   NAMESPACED   KIND
controllerrevisions                apps/v1      true         ControllerRevision
daemonsets            ds           apps/v1      true         DaemonSet
deployments           deploy       apps/v1      true         Deployment
replicasets           rs           apps/v1      true         ReplicaSet
statefulsets          sts          apps/v1      true         StatefulSet
tech-0222@MSI:~$

詳しくは、以下を確認してください。

RBACをやってみる

事前準備

Role作成し設定するにはユーザが必要になりますので、試験用にサービスアカウントと
RoleとClusterRoleの違いを確認するためテスト用のnamespacesも用意します。

また、権限を確認する為にテスト用のPodを起動します。
※crulによるAPIの操作を試したい場合は、Podを作成してください。

  • namespace
tech-0222@MSI:~$ kubectl create ns test-ns
namespace/test-ns created

# 確認
tech-0222@MSI:~$ kubectl get ns test-ns
NAME      STATUS   AGE
test-ns   Active   7s
tech-0222@MSI:~$
  • service account
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl create sa test-sa-role -n test-ns
serviceaccount/test-sa-role created
tech-0222@MSI:~$ kubectl create sa test-sa-cluster-role
serviceaccount/test-sa-cluster-role created
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl create sa test-sa-cluster-role-mics
serviceaccount/test-sa-cluster-role-mics created
tech-0222@MSI:~$

#確認
tech-0222@MSI:~$ kubectl get sa
NAME                        SECRETS   AGE
default                     0         11d
test-sa-cluster-role        0         4d17h
test-sa-cluster-role-mics   0         1s
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl get sa -n test-ns test-sa-role
NAME           SECRETS   AGE
test-sa-role   0         60s
tech-0222@MSI:~$
  • pod
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl run test-pod-role --image=nginx -n test-ns
pod/test-pod-role created
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl run test-pod-cluster-role --image=nginx
pod/test-pod-cluster-role created
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl get po -n test-ns
NAME            READY   STATUS    RESTARTS   AGE
test-pod-role   1/1     Running   0          29s
tech-0222@MSI:~$ kubectl get po
NAME                    READY   STATUS    RESTARTS   AGE
test-pod-cluster-role   1/1     Running   0          13s
tech-0222@MSI:~$

Kubernetesの RBACでRoleを作成してみる

テスト用で作成したリソースを使ってnamespace:test-nsのPodに対してGet、listだけを実行できるルールを作成してみます。

  • コマンド
#作成
tech-0222@MSI:~$ kubectl create role test-role --resource=pods --verb=get,list -n test-ns
role.rbac.authorization.k8s.io/test-role created
tech-0222@MSI:~$

#確認
tech-0222@MSI:~$ kubectl get role -n test-ns test-role -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: test-role
  namespace: test-ns
  resourceVersion: "314694"
  uid: 5e7ce931-4780-4d8f-b2f1-384b43200d85
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
tech-0222@MSI:~$
  • yaml 形式で作成したい際には、以下結果をファイルに書き出してから作成しましょう
tech-0222@MSI:~$ kubectl create role test-role --resource=pods --verb=get,list -n test-ns --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: test-role
  namespace: test-ns
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
tech-0222@MSI:~$

Roleの設定は以下と「kubectl create role --help」コマンドが参考になります。

Kubernetesの RBACでClusterRoleを作成してみる

Cluster全体でPODに対してだけ全ての権限があるルールを作成してみます。

  • コマンド
tech-0222@MSI:~$ kubectl create clusterrole test-cluster-role --resource=pods --verb=*
clusterrole.rbac.authorization.k8s.io/test-cluster-role created
tech-0222@MSI:~$

#あとでテストするようで同じルールで名前が違うClusterRoleを作成します
tech-0222@MSI:~$ kubectl create clusterrole test-cluster-role-mics --resource=pods --verb=*
clusterrole.rbac.authorization.k8s.io/test-cluster-role-mics created
tech-0222@MSI:~$

#確認
tech-0222@MSI:~$
tech-0222@MSI:~$ kubectl get clusterrole test-cluster-role -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: test-cluster-role
  resourceVersion: "315265"
  uid: 29677ae2-4183-47aa-9cc8-e60077728ec8
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - '*'
tech-0222@MSI:~$

tech-0222@MSI:~$ kubectl get clusterrole test-cluster-role-mics -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: test-cluster-role-mics
  resourceVersion: "315505"
  uid: 4ee69c3a-fdae-4f7b-8c70-e286c3df4b63
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - '*'
tech-0222@MSI:~$

ClusterRoleを設定する際には、以下と「kubectl create clusterrole --help」コマンドが参考になります。

Kubernetesの RBACでRoleBinding と ClusterRoleBindingを作成してみる

作成したRole とClusterRole を service account にセット(Binding)してみましょう。

  • コマンド(Role+RoleBindingの組み合わせ)
tech-0222@MSI:~$ kubectl create rolebinding test-role-binding --role=test-role --serviceaccount=test-ns:test-sa-role  -n test-ns
rolebinding.rbac.authorization.k8s.io/test-role-binding created

#確認
tech-0222@MSI:~$ kubectl get rolebindings.rbac.authorization.k8s.io -n test-ns test-role-binding -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-role-binding
  namespace: test-ns
  resourceVersion: "331922"
  uid: 5a5b074a-62a7-4473-b54a-bdc7d8fcdc2e
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: test-role
subjects:
- kind: ServiceAccount
  name: test-sa-role
  namespace: test-ns
tech-0222@MSI:~$
  • コマンド(ClusterRole+ClusterRoleBindingの組み合わせ)
tech-0222@MSI:~$ kubectl create clusterrolebinding test-cluster-role-binding --clusterrole=test-cluster-role --serviceaccount=default:test-sa-cluster-role
clusterrolebinding.rbac.authorization.k8s.io/test-cluster-role-binding created
tech-0222@MSI:~$

#確認
tech-0222@MSI:~$ kubectl get clusterrolebindings.rbac.authorization.k8s.io test-cluster-role-binding -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-cluster-role-binding
  resourceVersion: "332209"
  uid: d9762ca6-57ea-4a7b-af86-079d6cf8098a
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: test-cluster-role
subjects:
- kind: ServiceAccount
  name: test-sa-cluster-role
  namespace: default
tech-0222@MSI:~$
  • コマンド(ClusterRole+RoleBindingの組み合わせ)
tech-0222@MSI:~$ kubectl create rolebinding test-cluster-role-mics-role-binding --clusterrole=test-cluster-role-mics --serviceaccount=default:test-sa-cluster-role-mics
rolebinding.rbac.authorization.k8s.io/test-cluster-role-mics-role-binding created
tech-0222@MSI:~$

#確認
tech-0222@MSI:~$ kubectl get rolebindings.rbac.authorization.k8s.io test-cluster-role-mics-role-binding -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-cluster-role-mics-role-binding
  namespace: default
  resourceVersion: "332384"
  uid: 05c97a32-a754-4341-90b6-02a5e26a4857
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: test-cluster-role-mics
subjects:
- kind: ServiceAccount
  name: test-sa-cluster-role-mics
  namespace: default
tech-0222@MSI:~$

RoleBinding と ClusterRoleBindingを設定する際には、以下と「kubectl create rolebinding --help」「 kubectl create clusterrolebinding --help」コマンドが参考になります。

KubernetesのRole とClusterRole 設定を確認してみる

作成したRole設定の操作権限は、kubectl auth can-i コマンドで確認できます。
ただし、このコマンドはデフォルトでkubectlを実行中するユーザーの権限しか確認できません。

--as-uid オプションを使えば、別ユーザー(例えば、作成したサービスアカウント)の
権限で確認することができますので、今回はこれを使ってみます。

今回ロールを設定したユーザは、サービスアカウントなので形式は「system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)」で指定します。

  • コマンド(Role+RoleBindingの組み合わせ)
    • 想定
      • namespace:test-nsのPodに対してGet、listが実行できる
#Roleで許可したものだけ結果がYESになっているので成功!
tech-0222@MSI:~$ kubectl auth can-i list pods --as=system:serviceaccount:test-ns:test-sa-role -n test-ns
yes
tech-0222@MSI:~$ kubectl auth can-i get pods --as=system:serviceaccount:test-ns:test-sa-role -n test-ns
yes

#Roleで許可していない結果はがNOになっている
tech-0222@MSI:~$ kubectl auth can-i create pods --as=system:serviceaccount:test-ns:test-sa-role -n test-ns
no
tech-0222@MSI:~$ kubectl auth can-i patch pods --as=system:serviceaccount:test-ns:test-sa-role -n test-ns
no
tech-0222@MSI:~$ kubectl auth can-i delete pods --as=system:serviceaccount:test-ns:test-sa-role -n test-ns
no
tech-0222@MSI:~$

#NamespaceがないとPodでもエラーとなっているので想定通り
tech-0222@MSI:~$ kubectl auth can-i get pods --as=system:serviceaccount:test-ns:test-sa-role
no
tech-0222@MSI:~$
  • コマンド(ClusterRole+ClusterRoleBindingの組み合わせ)
    • 想定
      • PODにだけ全ての権限を実行できる
#ClusterRole で許可した通りPodに対して権限がOK+ネームスペースの指定なくても問題なし
tech-0222@MSI:~$ kubectl auth can-i list pods --as=system:serviceaccount:default:test-sa-cluster-role
yes
tech-0222@MSI:~$ kubectl auth can-i get pods --as=system:serviceaccount:default:test-sa-cluster-role
yes
tech-0222@MSI:~$ kubectl auth can-i create pods --as=system:serviceaccount:default:test-sa-cluster-role
yes
tech-0222@MSI:~$ kubectl auth can-i patch pods --as=system:serviceaccount:default:test-sa-cluster-role
yes
tech-0222@MSI:~$ 

#許可していないリソースだとNGになる
tech-0222@MSI:~$ kubectl auth can-i patch deploy --as=system:serviceaccount:default:test-sa-cluster-role
no
tech-0222@MSI:~$ kubectl auth can-i patch configmaps --as=system:serviceaccount:default:test-sa-cluster-role
no
tech-0222@MSI:~$
  • コマンド(ClusterRole+RoleBindingの組み合わせ)
    • 想定
      • PODに対してだけ全ての権限を実行できるが、対象はnamespace:defaultだけ
#許可しているリソース+指定ネームスペースだと正常 
tech-0222@MSI:~$ kubectl auth can-i create pods --as=system:serviceaccount:default:test-sa-cluster-role-mics -n default
yes
tech-0222@MSI:~$ kubectl auth can-i get pods --as=system:serviceaccount:default:test-sa-cluster-role-mics -n default
yes
tech-0222@MSI:~$ kubectl auth can-i list pods --as=system:serviceaccount:default:test-sa-cluster-role-mics -n default
yes
tech-0222@MSI:~$

#許可していないリソースやネームスペースだとNGの結果
tech-0222@MSI:~$ kubectl auth can-i list pods --as=system:serviceaccount:default:test-sa-cluster-role-mics  -n test-ns
no
tech-0222@MSI:~$ kubectl auth can-i list deploy --as=system:serviceaccount:default:test-sa-cluster-role-mics -n default
no
tech-0222@MSI:~$

詳細は以下ドキュメントや「kubectl auth can-i —help」コマンドが参考になります。

また、サービスアカウントのフォーマットはここが参考になります。

ちなみに、ServiceAccountはTokenを発行してcurlでAPIを呼び出すこともでき、
この方法を使えば、実際にリソースの作成や確認をAPIで行えます。

curlでAPIを呼び出して操作する詳細は過去の記事のここを参考にしてください。

https://0222-nnn.com/kubernetes%E3%81%AEapi%E3%82%92serviceaccount%E3%81%AEtoken%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6crul%E3%81%A7%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/

https://0222-nnn.com/kubernetes-api%E3%82%92kubectl%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Fcrul%E3%81%A7%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/

今回は考えなかったRBAC のベスト プラクティスについて

今回の記事では触れませんでしたが、権限設計はセキュリティに直結するため、ベストプラクティスを参考にしっかり設計を検討した方がいいですね。

人気記事

1

Kubernetes kubectl rollout コマンドでdeploymentをロールバックしてみる 概要 kubectl rollout コマンドでデプロイ履歴を確認してロールバックするやり方 ...

2

  terraformのバージョン管理どうすればいいのか? terraformの複数バージョンを簡単に動かしたい terraformのインストール方法が分からない と、疑問を抱えている人の疑 ...

3

本記事では どんな環境にterraformをインストールできるの? terraformのインストールどうしたらいいの? terraformのどのバージョンをインストールすればいいの? と、困っている人 ...

4

Kubernetes kubectl version コマンドでバージョンを調べてみる 概要 kubectl version は、Kubernetes の Client、Serverのバージョンを確認 ...

-Kubernetes