KubernetesのRBACを触って学ぶ

先日Kubernetesの特定のnamespaceでJobを実行しようとしたところ、権限がなかったため、まずClusterの管理者に権限を申請するところから始める必要があった。これを機会に、KubernetesのRBACについて学んでみた。

RBACとは

RBACとは、Role-based access controlの略。どのリソースに対するどんな操作を許可するかを、UserやServiceAccount単位で指定することができる。
他のリソース同様、RBACもyamlファイルで管理する。Role の設定ファイルでRoleを定義し、 RoleBinding の設定ファイルでそのRoleをどのUser, ServiceAccountに付与するかを指定する。 この他に ClusterRole, ClusterRoleBinding の設定ファイルも作ることができる。 Role, RoleBinding は特定のnamespaceにおける権限を指定するのに対し、 ClusterRole, ClusterRoleBinding はnamespaceによらない権限を指定するためにある。名前の通り、Cluster全体に適用される権限ということなのだろう。

新しいRoleを追加する

今回、既存のRoleファイルはnamespace内で全ての操作ができる事実上のmaster権限のものしかなかった。さすがにそこまでの権限は不要なので、新しくRoleファイルを作ることにした。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: running-job
rules:
  - apiGroups: [""]
    resources: ["pods","pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]

metadata.namespace には、そのRoleの対象となるnamespaceを指定する。 metadata.name はこのRoleの名前であり、これはRoleをbindする際にも使う。
権限の内容は rules に書いていく。apiGroupsは複数指定することができ、それぞれにおいて対象となるresourceと、許可する操作( verbs )を指定できる。上記のようにするとJobの実行権限の他に、podsの一覧の取得や、各podのログの確認も行うことができる。
なお、公式ドキュメントによると、Roleファイルは"purely additive"であるとのこと。すなわち、AWSのpolicyのように Deny の設定をすることはできない。

Roleを割り当てる

権限の割り当てはRoleBindingファイルで行う。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: running-job-binding
  namespace: development
subjects:
- kind: User
  name: udomomo
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: running-job
  apiGroup: rbac.authorization.k8s.io

重要なのは、 roleRef.name の名前をRoleファイルの metadata.name と一致させること。ここが間違っていると正しくbindすることができない。
Userの部分は、各Kubernetes Clusterのユーザ管理のやり方に従って指定する。今回の場合EKSを使っていたので、AWS IAMアカウントをそのまま指定するだけで良かった。EKSでは権限管理をpolicyではなく独自の方法で行っていると聞いたことがあるが、RBACがまさにその役割を果たしているということがようやく理解できた。