12
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【本気で学ぶKubernetes】RBAC入門!Pod権限の正しい分け方

Last updated at Posted at 2025-12-07

はじめに

こんにちは!

本記事は「本気で学ぶKubernetes」シリーズの第7回です。このシリーズでは、Kubernetesの基礎から実践まで、段階的に学んでいきます。

このシリーズは、第1回から順に読むことで体系的に学べる構成にしています。
まだご覧になっていない方は、ぜひ最初からご覧ください!

Kubernetesとは?クラスタ構成の全体像をつかむ

今回は、KubernetesのRBAC(Role-Based Access Control)という権限管理の仕組みについて触れていきたいと思います。

この記事は人間がKubernetesの公式ドキュメントを読み漁りながら、人間の手で書いていますのでご安心ください!

Kubernetesのアカウント体系

Kubernetesには2種類のアカウントがあります。

ユーザーアカウント(Users)

こちらはKubernetesを使用するユーザーのアカウントです。
LDAPやGoogle AccountsなどKubernetesの外部で管理でき、kubectlコマンドを実行するときこのユーザーアカウントとして認証することもできます。

サービスアカウント(ServiceAccount)

サービスアカウントはPod内のプロセスが利用するアカウントです。
Kubernetes APIにて管理されており、namespace単位で作成することができます。

kubectl create serviceaccount my-app

Podにサービスアカウントを割り当てると、そのPodはKubernetes APIにアクセスできるようになります。

今回の記事では、主にこのサービスアカウントに対する権限管理について触れていこうと思います。

出典: Kubernetes公式ドキュメント - Authenticating

なぜRBACが必要なのか

デフォルトでは、すべてのPodが同じdefaultサービスアカウントを使います。もしdefaultに広い権限を与えてしまうと、すべてのPodが同じ権限を持ってしまい、権限の分離ができません。

例えば、あるアプリケーションがConfigMapを読み取るだけでいいのに、Secretやその他のリソースも操作できてしまう状態は望ましくありません。

RBACを使うことでサービスアカウントごとに細かく権限を設定できます。

RBACの基本概念

RBACは簡単にいうと「誰が」「何に対して」「何をできるか」をロールを割り当てることで制御していく仕組みです。
AWSやGoogle Cloudクラウドなどのクラウドサービスをすでに利用されている方にはおなじみの概念かと思います。

ServiceAccount

PodがKubernetes APIにアクセスする際のアカウントの実態です。デフォルトではdefault ServiceAccountが使われますが、カスタムServiceAccountを作成して権限を個別に設定することも可能です。

Role と ClusterRole

権限のセットを定義するリソースです。

  • Roleは特定のnamespace内での権限を定義します。
  • ClusterRoleはクラスタ全体での権限を定義します。

どちらも「どのリソースに対して、どんな操作ができるか」をrulesで指定します。

そして作成した権限のセットは実際にnamespaceやクラスタなどの範囲で、ServiceAccountに結びつけていく必要があります。
namespace内でのバインディングを行う場合はRoleBinding、クラスタ全体でのバインディングを行う場合はClusterRoleBindingを利用します。

指定可能な権限例

権限で指定できる主な操作には以下のようなものが用意されています。
こちらもクラウドを利用されている方はイメージがしやすいかと多います。

  • get, list, watch: 読み取り系
  • create: 新規作成
  • update, patch: 更新
  • delete: 削除
  • *: すべての操作(管理者向け、通常は避けるべき)

出典: Kubernetes公式ドキュメント - Using RBAC Authorization

出典: Kubernetes公式ドキュメント - Configure Service Accounts for Pods

RBACで権限制御を試してみる

ここからは実際にRBACを使ってPodに最小限の権限だけを与える方法を確認していきます。

今回は、default namespaceのPod情報を読み取る権限だけを与えて、Secretなど他のリソースは操作させないようにしてみます。

まず、必要なリソースを一つのマニフェストファイルにまとめます。

rbac-pod-reader.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "my-service-account" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: ServiceAccount
  name: my-service-account # "name" is case sensitive
  namespace: default
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role # this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
  name: rbac-test-pod
  namespace: default
spec:
  serviceAccountName: my-service-account
  containers:
  - name: kubectl-container
    image: bitnami/kubectl
    command: ["sleep", "3600"]

このマニフェストには4つのリソースを含めています。

簡単に説明すると、ServiceAccountのmy-service-accountを作成し、そこにPodの読み取り権限(get, watch, list)だけを与えるpod-readerというRoleを定義しています。

そしてRoleBindingのread-podsでこの2つを結びつけて、最後にテスト用のPodを作成します。

デプロイと動作確認

kubectl apply -f rbac-pod-reader.yaml

# serviceaccount/my-service-account created
# role.rbac.authorization.k8s.io/pod-reader created
# rolebinding.rbac.authorization.k8s.io/read-pods created
# pod/rbac-test-pod created

Pod内からPodの情報を取得してみます。

kubectl exec rbac-test-pod -- kubectl get pods

# NAME            READY   STATUS    RESTARTS   AGE
# rbac-test-pod   1/1     Running   0          30s

成功しましたので、次に権限のないSecretを取得してみます。

kubectl exec rbac-test-pod -- kubectl get secrets

# Error from server (Forbidden): secrets is forbidden: User "system:serviceaccount:default:my-service-account" cannot list resource "secrets" in API group "" in the namespace "default"

こちらは権限エラーになりました。これでPodの読み取り権限だけが付与されていることが確認できました。

権限の確認コマンド

kubectl auth can-iコマンドを使うと、特定のServiceAccountがどんな操作を許可されているか確認できます。

kubectl auth can-i get pods --as=system:serviceaccount:default:my-service-account
# yes

kubectl auth can-i get secrets --as=system:serviceaccount:default:my-service-account
# no

ちなみに、ユーザーアカウント(自分自身)の権限を確認したい場合は--asオプションを付けずに実行します。

# 自分の権限を確認
kubectl auth can-i get pods
# yes

kubectl auth can-i create deployments
# yes

# 自分が持っている全権限の一覧
kubectl auth can-i --list
# Resources                                       # Non-Resource URLs   Resource Names   Verbs
# *.*                                             # []                  []               [*]
#                                                 [*]       #           # []        #        [*]
# selfsubjectreviews.authentication.k8s.io        # []                  []               [create]
# selfsubjectaccessreviews.authorization.k8s.io   # []                  []               [create]
# selfsubjectrulesreviews.authorization.k8s.io    # []                  []               [create]
#                                                 [/api/# *]        #     # []        #        # [get]

RoleBindingの確認

さらに今回作成したRoleBindingの設定内容も確認してみます。

kubectl get rolebinding read-pods -o yaml

出力結果は以下の通りになりました。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"read-pods","namespace":"default"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"Role","name":"pod-reader"},"subjects":[{"kind":"ServiceAccount","name":"my-service-account","namespace":"default"}]}
  creationTimestamp: "2025-12-07T12:19:17Z"
  name: read-pods
  namespace: default
  resourceVersion: "32792"
  uid: 762103ec-253a-4bbd-838f-212757207b94
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- kind: ServiceAccount
  name: my-service-account
  namespace: default

出力を見ると、subjectsでServiceAccountを指定し、roleRefでRoleを参照していることが分かりますね。

もし権限が効いていない場合は、RoleやRoleBindingが同じnamespaceにあるかどうか、またsubjectsnamenamespaceが合っているかを確認してみてください!

ClusterRoleの例

ここまではnamespace内での権限管理(Role/RoleBinding)を見てきましたが、クラスタ全体での権限が必要な場合はClusterRoleを使う必要があります。

ユースケースとしては以下の場合が挙げられます。

  • 複数namespaceにまたがる権限が必要な場合
  • クラスタ全体のリソース(Node、PersistentVolumeなど)を扱う場合

Kubernetesには、よく使われる権限セットが組み込みのClusterRoleとして用意されています。

kubectl get clusterrole | grep -E "^(view|edit|admin|cluster-admin)"

# admin           2024-12-01T00:00:00Z
# cluster-admin   2024-12-01T00:00:00Z
# edit            2024-12-01T00:00:00Z
# view            2024-12-01T00:00:00Z
  • view: 読み取り専用
  • edit: リソースの編集可能(SecretやRoleは除く)
  • admin: namespace内のほぼすべての権限
  • cluster-admin: クラスタ全体の全権限

これらを使うことで、一から権限を定義する手間を省けます。

ベストプラクティス

RBACの権限管理のベストプラクティスは、AWSやGoogle Cloudなどのクラウドサービスと基本的に同じ考え方になると思います。
以下のような内容は必ず押さえておいた方が良いでしょう。

  • 最小権限の原則:必要最低限の権限だけを付与。*(すべての権限)は避け、具体的なverbsを指定
  • ServiceAccountの分離:アプリケーションごとに専用のServiceAccountを作成。default ServiceAccountは使わない
  • 定期的な権限の見直し:不要になった権限は削除し、定期的に見直す
  • 明示的な指定:PodのマニフェストでserviceAccountNameを明示的に指定する

まとめと次回予告

今回は、KubernetesのRBACを使って、Podやユーザーの権限を細かく制御する方法を確認しました。

RBACは、ServiceAccount、Role/ClusterRole、RoleBinding/ClusterRoleBindingの3つの要素を最低限押さえておけば良いと思います。その上で最小権限の原則に従って、セキュリティを向上させていきましょう!

次回はサービスの健康状態を監視するための仕組みであるProbeのLiveness/Readiness/Startupについて触れていきたいと思います!

それでは、また明日!

12
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?