権限を追加設定することで、コンテナ内で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が固定されているなど、想定外のセキュリティホールが生じにくくなるように設計されています。