
こんにちは、SCSKの石川です。
これまではOpenShiftにあらかじめ用意されているデフォルトロール(admin, cluster-admin等)を見てきました。しかし、実際の現場では「ログは見せたいが、Podに入ってコマンド実行(Exec)はさせたくない」「再起動だけさせたい」といった細かい要望が出てきます。
今回は、カスタムロールの作成方法と、運用上の注意事項を見ていきたいと思います。
シリーズ予定
-
第1回:作成直後のユーザの権限
-
第2回:Adminロールの権限
-
第3回:ClusterRoleBindingでAdminロールを付与したユーザの権限
-
第4回:Cluster-AdminロールをRoleBindingとClusterRoleBindingで付与した時の違い(本記事)
-
第5回:カスタムロール作成のコツと注意点(本記事)
-
第6回:各チームへの適切な権限付与
- 第7回:権限管理の継続的な見直し
目次
1.カスタムロールが必要になるシナリオ
以下のような要件はデフォルトロールでは満たせないことがあります。
- Configmap Reader: Configmapを見せたいが、Secret(機密情報)などそれ以外は見せたくない。
- Log Reader: Podのログは見せたいが、ソースコードやSecret(機密情報)は見せたくない。
- Restarter: アプリケーションの再起動は許可したいが、設定変更は禁止にしたい。
2.カスタムロールの作成と適用(YAML例)
例として、「ConfigMapの閲覧と更新のみ可能(作成・削除は不可)」なロールを作成してみます。
custom-cm-updater.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cm-updater
namespace: ocp-prj02
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "update", "patch"]# カスタムロールの作成
$ oc create -f custom-cm-updater.yaml
role.rbac.authorization.k8s.io/cm-updater created
# ユーザへの紐づけ
$ oc create rolebinding cm-updater-binding --role=cm-updater --user=devuser01 -n ocp-prj02
rolebinding.rbac.authorization.k8s.io/cm-updater-binding created
$ oc describe rolebinding cm-updater-binding
Name: cm-updater-binding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: cm-updater
Subjects:
Kind Name Namespace
---- ---- ---------
User devuser01これで、devuser01 ユーザはConfigMapの書き換えだけができるようになります。
シンプルな要件であればこのように記述すればよいのですが、実際のエンタープライズ運用では「Secret以外のすべての参照権限を付与したい」という要件が出てくることがよくあります。
しかし、KubernetesおよびOpenShiftのRBACを設計する上で、非常に重要な仕様上の制約が一つあります。それは、RBACの仕組みが 「完全なホワイトリスト方式(加点方式)」 であるということです。
「Deny(明示的な拒否)」という概念が存在しないため、「(すべて)を許可してSecretだけを除外する」という柔軟な書き方はシステム上できません。そのため、この要件を実現するには 「Secretを含まない、全リソースを明示的に羅列したカスタムClusterRoleを作成する」 というアプローチをとる必要があります。
具体的な実現方法としては、以下のいずれかのアプローチになります。
スクリプト等を用いて、稼働中のAPIサーバーからすべてのAPIとリソースを直接抽出してリスト化する。
OpenShiftに最初から用意されている cluster-reader ロールをエクスポートし、それをベースにカスタムロールを作成する。
なお、後者の cluster-reader をベースにする手法をとる場合、エクスポートしたYAMLファイルから secrets リソースの記述を削除するだけでなく、システムが自動で他の権限を吸い上げてしまう Aggregation Rule(集約ルール)のブロックも必ず削除する必要があります。
3.ClusterRole Aggregation(集約)とは
カスタムロールを作成する際、特に ClusterRole を作成する場合に注意すべき機能があります。それが AggregationRule(集約ルール) です。
OpenShiftのデフォルトロール(admin, edit, view)は、実は静的な定義ではありません。他のロールからルールを「集めて」構成されています。
4.aggregate-to-admin ラベルの注意点
試しに、以下のYAMLを使って新しいClusterRoleを作成してみます。
dangerous-scc-aggregation.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: my-scc-admin
labels:
rbac.authorization.k8s.io/aggregate-to-admin: "true" # ←ここが重要
rules:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
resourceNames: ["anyuid", "privileged"]
verbs: ["use"]この rbac.authorization.k8s.io/aggregate-to-admin: "true" というラベルを付けてClusterRoleを作成すると、クラスタ内のすべての「Admin」ロールを持つユーザに対し、自動的にこの権限(特権SCCの使用権限)が追加されます。
これは便利な反面、意図しない 「権限のばら撒き」 を引き起こす致命的なリスクがあります。
本来、OpenShiftの公式仕様において、この集約機能は「ユーザーが独自に追加したカスタムリソース(CRD)の権限を、既存のロールに組み込むための機能」として定義されています。
それを標準の強力なセキュリティリソース(SCC)に対して使用してしまうとどうなるでしょうか。これまで確認してきた通り、通常の admin ロールは自身のプロジェクト内であっても anyuid を ServiceAccount に付与することはできませんでした。しかし、この設定一つで、 全プロジェクトのAdmin管理者 が自分のプロジェクト内で自由に特権コンテナ(root権限やホストOSへのアクセス権限を持つコンテナ)を起動できてしまいます。
更に、もし上記の verbs に create を含めていた場合、ClusterRoleBinding 経由で admin を付与されたユーザー(第3回参照)が、強力な権限を持つ独自のセキュリティルール(カスタムSCC)をシステム全体へ登録できてしまう状態に陥ります。なお、SCCはクラスタスコープのリソースであるため、RoleBinding 経由で admin を付与されたユーザーにはこの影響は及びません。このように、集約機能を用いた標準リソースの権限変更は、設計・運用において極めて慎重な取り扱い(原則として回避すること)が求められます。
5.アップグレード時のメンテナンスリスク
カスタムロール、特にデフォルトロールを直接編集してしまった場合、OpenShiftのバージョンアップ時にリセットされる可能性があります。
OpenShiftはアップグレード時にデフォルトロール(adminなど)を「あるべき姿」に戻そうとするため、手動で追加したルールが消えてしまうことがあります。
ベストプラクティス:
- デフォルトロールは編集しない。
- カスタムロールは別名で作成する。
- Aggregation(集約)機能を使う場合は、影響範囲を十分に理解した上でラベルを設定する。
6.まとめ
カスタムロールは柔軟な権限管理を可能にしますが、設計と管理のコストが増加します。「本当にその細かい制御が必要か?」を常に問いかけ、可能な限りデフォルトロール(admin, edit, view)の組み合わせで対応するのが、長期的には運用負荷を下げるコツです。
次回は、各チームへの適切な権限付与について確認します。












