権限を追加設定することで、コンテナ内でkubectl
を実行してクラスタ操作できます。
コンテナの権限を管理するkubernetes標準の方法はRole
リソースを用います。
RBMACの保証と拡張性のため、Role
を直接Pod
に割りあてることはできず、RoleBinding
とServiceAccount
がセットで必要となり、次のような参照関係になります。
Role <- RoleBinding -> ServiceAccount <- Pod
また、GKEなどの各ホスティングがこのk8s標準のアカウンティングとは別の認証を提供している場合もあります。
後述のとおり、Role
を用いた認可では個別リソース単位の少ない権限割りあてが可能で、操作対象が明確な場合に適しています。
gkeの認証などは、クラスタの広範囲なリソースを制御する場合や、クラスタ外のGCP機能をAPI制御する場合に適しています。
なお、kubernetesのバージョンがとても古いクラスタではRBAC認可機能じたいが有効になっていない場合があります。その場合、バージョンアップや設定変更が必要です。
コンテナ用kubectl
最終的に動作させるkubectlはあらかじめコンテナイメージに追加しておきます。
ディストリビューションが提供するパッケージ追加、または
公式配布のバイナリのいずれでも動作するでしょう。
Role
によるセットアップではk8sの標準APIを使用するため、追加の認証プラグインは不要です。
Role
Role
のリソース定義は
公式ガイドにひと通り解説があります。
既述のとおり、認可権限を定義するのはRole
です。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
この権限セットを付与したコンテナ内では、kubectl get pods
が意図どおり動作します。
rules
に利用できる権限を定義するのですが、指定すべきキーワードを手軽に知る方法がないという難点があります。
rules.[].apiGroups
はリソース分類を指定する。各リソースのapiVersion
からversionを除去したURI。- Pod操作などを含むコアAPIは
""
の省略記法で指定できる。文字列としては簡素だが概念は自明ではない。たとえばnetworking.k8s.io
はコアAPIではないためURIを明示しないと動作しない、という点に気づきづらい
- Pod操作などを含むコアAPIは
rules.[].resources
は具体的な操作対象。この例のとおり、とくにサブリソースが自明ではない- k8sのHTTP APIのパスを指定する項目のため、HTTP APIリファレンスがあれば特定できるだろう
rules.[].verbs
はHTTPメソッド風の操作カテゴリー。kubectl
のサブコマンドに対応するが完全に同じラベルではなく、自明でないkubectl apply
に対応するリソース更新操作は、update
またはpatch
権限が必要だがいずれであかを知る手段はない
RoleとClusterRole
Role
で指定した権限はmetadata.namespace
内のリソースに限られます。
より広いリソースの権限を一括で付与するにはClusterRole
とそれに対応するClusterBinding
を用います。
操作対象を特定できる場合、スコープの狭いRole
を使用した方がセキュアです。
ServiceAccount
ServiceAccountは、無人ユーザーです。基本的には目的を表すラベルを定義します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
namespace: default
DeploymentなどのpodSpecにserviceAccountName
を指定することにより、指定のServiceAccountでPodが動作します。
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
serviceAccountName: my-serviceaccount
containers:
- name: nginx
image: nginx:latest
RoleBinding
RoleBinding
はこの例ではServiceAccount
とRole
を関連づけるリソースで、これらの名前が決まったら適切に参照するだけのものです。
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-serviceaccount
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-and-pod-logs-reader
apiGroup: rbac.authorization.k8s.io
この例ではServiceAccount
が1つずつしかないため単に手間が増えたように見えますが、subjects
リストを任意のタイミングで変更したり、reoleRef
が固定されているなど、想定外のセキュリティホールが生じにくくなるように設計されています。
Chuma Takahiro