エラーの内容
Error from server (Forbidden): pods "my-pod" is forbidden: User "system:serviceaccount:default:default" cannot create resource "pods" in API group "" in the namespace "default"
このエラーは、Pod・CI/CDパイプライン・kubectlコマンドが、現在のIDに許可されていない操作を実行しようとしたときに発生します。User "system:serviceaccount:default:default" に注目してください — これは人間のユーザーではなく、default ネームスペース内の default という名前のServiceAccountです。解決策は、適切な権限を持つRole(またはClusterRole)を作成し、そのIDにバインドすることです。
何が起きているのか
Kubernetes RBACはデフォルトですべてを拒否します。Roleのバインディングがなければアクセスも一切なし、以上です。バインドされていないServiceAccountで動作するPodやパイプラインは、APIに触れた瞬間にこの壁にぶつかります。
エラーメッセージは自己説明的で、付与すべき内容を正確に教えてくれています:
- 誰が:
system:serviceaccount:default:default— ネームスペースdefault内のServiceAccountdefault - 何を:リソース
podsに対するcreate操作 - どこで:APIグループ
""(コアAPIグループ)、ネームスペースdefault
ステップごとの修正手順
Step 1 — 既存の権限を確認する
まず確認する価値があります — バインディングがすでに存在しているがスコープが間違っている可能性があります。重複した設定を避けるために先に確認しましょう:
# ネームスペース内のRoleBindingを確認
kubectl get rolebindings -n default -o wide
# ClusterRoleBindingを確認
kubectl get clusterrolebindings -o wide | grep default
# エラーに記載された権限を直接テスト
kubectl auth can-i create pods --as=system:serviceaccount:default:default -n default
最後のコマンドが no を返した場合は、次の手順に進んでください。
Step 2 — 必要な権限を持つRoleを作成する
ネームスペーススコープのアクセスには Role を使用します。これはエラーに記載された内容 — default ネームスペースの pods に対する create — に直接対応しています:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-manager
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "create", "delete", "watch"]
kubectl apply -f role-pod-manager.yaml
Step 3 — RoleをServiceAccountにバインドする
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-manager-binding
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: pod-manager
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebinding-pod-manager.yaml
Step 4 — クラスター全体のアクセスにはClusterRole + ClusterRoleBindingを使用する
コントローラー・オペレーター・監視エージェントは通常、複数のネームスペースにまたがるアクセスが必要です。その場合は、Role の代わりに ClusterRole を使用してください:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-manager-global
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/status"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pod-manager-global-binding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: pod-manager-global
apiGroup: rbac.authorization.k8s.io
kubectl apply -f clusterrole-binding.yaml
Step 5 — kubectlをローカルで実行している場合(ServiceAccountではない場合)
エラーにServiceAccountではなく User "john@example.com" のような通常のユーザーが表示されている場合は、そのユーザーに直接ロールをバインドします:
kubectl create clusterrolebinding john-admin \
--clusterrole=cluster-admin \
--user=john@example.com
本番環境では cluster-admin を使用しないでください。クラスター内のすべてのリソースに対する完全な読み書き権限を付与するため — 設定ミスが一つあるだけで深刻な影響範囲になります。必要な権限のみを持つスコープを絞ったClusterRoleを作成してください。
修正の確認
# 権限が付与されたことを確認
kubectl auth can-i create pods --as=system:serviceaccount:default:default -n default
# 期待される結果: yes
# ServiceAccountがpodsに対して持つすべての動詞を確認
kubectl auth can-i --list --as=system:serviceaccount:default:default -n default | grep pods
# 失敗したコマンドを再実行
kubectl run my-pod --image=nginx -n default
補足Tips
defaultではなく専用のServiceAccountを使用する
serviceAccountName を指定していないすべてのPodは default として実行されます。そのSAに権限を付与すると、後から他のチームがデプロイしたものも含め、ネームスペース内のすべてのPodにその権限が与えられます。ワークロードごとに専用のSAを作成してください:
kubectl create serviceaccount my-app -n default
# その後、PodのspecでServiceAccountを参照する:
# spec:
# serviceAccountName: my-app
エラーメッセージをよく読む — 修正すべき内容が正確にわかる
フォーマットは常に: User "X" cannot VERB resource "Y" in API group "Z" in namespace "N" です。これをRoleの rules に直接変換してください:
VERB→verbsに記述resource "Y"→resourcesに記述API group "Z"→apiGroupsに記述(空文字列""= コアグループ)
よく使うAPIグループ一覧
""— コア: pods, services, configmaps, secrets, persistentvolumeclaimsapps— deployments, replicasets, statefulsets, daemonsetsbatch— jobs, cronjobsnetworking.k8s.io— ingresses, networkpoliciesrbac.authorization.k8s.io— roles, rolebindings
RBACを修正してもスクリプトが失敗する場合
RBACを修正することで別の問題が明らかになることがあります:Pod内のバイナリやスクリプトが、Unixファイルパーミッションの設定ミスにより実行できない場合です。そのような場合は、ToolCraftのUnix Permissions Calculator が chmod の数値とシンボル表記の変換における手間を省いてくれます — 完全にブラウザ上で動作し、データは外部に送信されません。

