KubernetesのRBACについて

# RBACとは

RBAC(Role-based access control)とは、役割ベースのアクセス制御機能。

RBACリソースは4つのリソースがある。`Role`リソースと`ClusterRole`リソースと`RoleBinding`リソースと`ClusterRoleBinding`リソース。

* `Role`と`ClusterRole`は、どの`リソース`にどんな`操作`を許可するかを定義するためのリソース
* `RoleBinding`と`ClusterRoleBinding`はどの`Role`/`ClusterRole`をどの`User`や`ServiceAcctount`に紐付けるかを定義するためのリソース。
    * ユーザは以下のように`kubectl config set-credentials`を使って作成できる
        * `kubectl config set-credentials alice --username=alice --password=password`
        * 参考： [kubernetesがサポートする認証方法の全パターンを動かす](https://qiita.com/hiyosi/items/43465d4fc501c2044d01)


# リソース、操作とは

* リソースとは
    * Kubernetesのリソースを指す。例えばPod, Deployment, Service, Secret etc..
* 操作とは
    * get, create, update, delete, list, watch, deletecollection などがある。

## 操作の一覧

| 種別 | 内容 |
|:-:|:-:|
| *  | 全ての処理 |
| create | 作成 |
| delete | 削除 |
| get | 取得 |
| list | 一覧取得 |
| update | 更新 |
| patch | 一部変更 |
| watch | 変更の追従 |



# RoleとClusterRoleの違い、そしてRoleBindingとClusterRoleBindingの違い

RoleとClusterRoleの違い、そしてRoleBindingとClusterRoleBindingの違いは、Role/RoleBindingは特定のnamespaceに属するが、ClusterRole/ClusterRoleBindingはnamespaceに属さない(cluster-level resource)

|  | namespaceに属する | namespaceに属さない |
|:-:|:-:|:-:|
| Role  |  ◯ |   |
| Cluster Role  |   | ◯  |
| RoleBinding  | ◯  |   |
| ClusterRoleBinding  |   | ◯  |

# デフォルトで用意されているClusterRole

ClusterRoleにはいくつかデフォルトClusterRoleが用意されている。そのためざっくりとした権限でいい場合は新規でRoleやClusterRoleを作成せずにデフォルトClusterRoleを使うことができる。([参考](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles))

| デフォルトClusterRole名 | 内容 |
|:-:|:-:|
| cluster-admin | 全てのリソースに対しどんなアクションでも可能。<br>ClusterRoleBindingを使うと、clusterの全てのリソースにたいしてどんなアクションでも可能になる。 <br>RoleBindingを使うとそのnamespaceの全てのリソースにたいしてどんなアクションでも可能になる(namespaceリソース含む)。 |
| admin | RoleBindingを使ってbindingがされることを期待されているClusterRole。<br>namespace内のほとのどのリソースに対してread/writeができる。<br>またそのnamespace内のRole/RoleBindingリソースのwrite権限も有する。<br>しかしResourceQuotaとnamespace自身にはwriteできない。  |
| edit  | ほとんどのリソースのread writeができるが、Role/RoleBindingのreadやwriteはできない  |
| view | ほとんどのリソースのread ができるが、Role/RoleBinding、そしてSecretのreadはできない    |


# ClusterRole Aggregation

Kubernetes1.9以降、ClusterRoleに限り複数のClusterRoleの定義を読みこむAggregationの機能が使えます。
AggregationはClusterRoleに設定されているラベルを元に行われ、集約する側のClusterRoleに書かれているルールには反映されません。
[詳しくはこちら](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles)

# RoleとRoleBindingの作成例

#### Roleを作成

以下はServiceリソースをget, listできる権限を表したRole


```yaml:my-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: hoge-ns
  name: service-reader-role
rules:
- apiGroups:
  - apps
  - extensions
  resources:
  - deployments
  - services
  verbs:
  - "get"
  - "list"
```

`$ kubectl create -f my-reader-role.yaml` でRoleを作成


#### RoleBindingを作成

Role: my-reader-roleをServiceAccount: my-app-saに紐付けるためのRoleBinding


```yaml:my-reader-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: service-reader-rolebinding
  namespace: hoge-ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: my-reader-role
subjects:
- kind: ServiceAccount
  name: my-app-sa
  namespace: hoge-ns
```

`$ kubectl create -f my-reader-rolebinding.yaml` で RoleBinding を作成

# ServiceAccountについて


* ServiceAccount は Kubernetes 内で Pod の認証認可のために使用されるもの
* podは作成時になにかしらのServiceAccountに紐付けられる
* ServiceAccountに対してRoleを紐付ける(bindする)ことができる
* ServiceAccountはどのnamespaceに属するかの情報、及びAPIへ接続するための認証情報をもっている。`namespace`、`ca.crt`、`token`の3つ。
* `namespace`を1つ作ると`default`という名前のServiceAccountが自動的に作成される。
* Kubernetesクラスタを作ると`default`というnamespaceが自動で作成されるが、そのnamespaceに属する`default`という名前のServiceAccountも自動で作成される。podを作成すると紐付けるServiceAccountに指定がなければ`default`のServiceAccountが紐付けられる。
* `default`のServiceAccount以外にも新しくServiceAccountを手動で作成することができ、podに紐付けることができる
  * たとえばWebアプリケーション用のServiceAccountを作成し、そのWebアプリケーション用Podに作成したServiceAccountを紐付け、そのServiceAccountにKubernetesリソースの参照のみを許可することができる。
  

# その他Tips

* どんな時にRole/RoleBindingとClusterRole/ClusterRoleBindingを使えばいいかは以下を参考にすればよい

| アクセス制限対象 | Role種類 | Binding種類 |
|:-:|:-:|:-:|
| Cluster-level resources (Nodes, PersistentVolumes, ...)  |  ClusterRole | ClusterRoleBinding  |
| Non-resource URLs (/api, /healthz, ...)  | ClusterRole  | ClusterRoleBinding  |
| いくつかのnamespace、もしくは全てのnamespaceに存在するNamespaced resources | ClusterRole  | ClusterRoleBinding  |
| 特定のnamespaceに存在するNamespaced resources。(共通のRoleを使いたい場合) |  ClusterRole | RoleBinding  |
| 特定のnamespaceに存在するNamespaced resources。(namespaceごとにRoleを定義する場合) | Role  |  RoleBinding |



* `kubectl auth can-i`を使うと権限が設定されているか、操作が許可されているかを確認することができる。
例えばhoge-nsというnamespaceにあるdefaultという名前のservice accountがserviceのcreateすることを許可されているかどうかは以下のコマンドで確認できる。
`$ kubectl auth can-i create services --as=system:serviceaccount:hoge-ns:default -n=hoge-ns`

* namespace: kube-systemのRole一覧
`$ kubectl get roles -n=kube-system`
* namespace: kube-systemのClusterRole一覧
`$ kubectl get clusterroles -n=kube-system`


* もしminikube上でRBACを有効にしたい場合は、minikube起動時に、`--extra-config=apiserver.Authorization.Mode=RBAC`を指定する必要がある。
 
参考:

* [Kubernetes in Action](http://amzn.asia/80rSDOx) (最高に分かりやすく書かれているのでぜひ買いましょう)
* [Using RBAC Authorization](https://kubernetes.io/docs/admin/authorization/rbac/)
* [Kubernetes Engine: 役割ベースのアクセス制御](https://cloud.google.com/kubernetes-engine/docs/role-based-access-control?hl=ja)
* [Kubernetes in Action](http://amzn.asia/3WMljwL)
* [Kubernetes Cookbook](http://amzn.asia/b8vyunj)
* [Configure RBAC In Your Kubernetes Cluster
](https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/)