EKSのIAMとRBACの認証・認可を試してみる

> これはひどい記事だと思いますが、たまに見ている人がいるみたいなので追記です。
> 現在はAWSの以下記事のほうが参考になると思います。
> https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-iam-permissions-namespaces/


Qiitaさん初投稿です。仙台でインフラエンジニアをしている@abe-maです。  
インフラエンジニアなので将来的に[EKS](https://aws.amazon.com/jp/eks/)を使うようになったら
たぶんクラスタアドミン的なものが担当になるなぁと思い
そのときのために事前に認証と認可について簡単に試してみることにしました。  
Kubernetesは少しだけ触ったことがありますが、EKSを触るのは今回が初めてです。

#期待するところ
AWSにはIAMによる認証があるので、それがKubernetesのRBACとうまく統合されて
`任意のIAMユーザ・グループ・ロールに対し、Kubernetes上でやらせたいこと・やらせたくないこと`が
いい感じに制御できればよいなと思いました。  

#試してみた結果
以降は試してみた経緯をつらつらと書いているだけなので、結論から先に。

- 確認できたこと  
  - EKSではaws-authと呼ばれるConfigmapを編集して認証・認可の設定を行う
  - IAMグループを対象にはできない
  - IAMユーザおよびロールはRoleBinding/ClusterRoleBindingでターゲットになる`Group`と紐付けることが出来る
  - cluster-adminロールに紐づくsystem:mastersグループをIAMユーザに関連付けてkubectlを実行
- わかっていないこと
  - (上記のK8s上のリソースとしての)Groupの作り方

EKSにおけるIAMユーザとK8sのRBACの関係
![Untitled Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/262765/a97a519f-c499-1f8e-05b5-24852bda5028.png)



#試してみます
以下、Tutorialをもとに試した結果です。

## aws-auth
EKSでは`aws-auth`と呼ばれるConfigmapでIAMユーザとRBACの紐づけを行うようです。

```
$ kubectl get configmap --all-namespaces
NAMESPACE     NAME                                 DATA   AGE
kube-system   aws-auth                             2      4d
kube-system   extension-apiserver-authentication   5      6d
kube-system   kube-dns                             0      6d
kube-system   kube-proxy                           1      6d
```

[AWS EKSユーザガイド](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html)では、任意のユーザを追加する手順について以下のように記載されています。
> IAM ユーザーまたはロールを Amazon EKS クラスターに追加するには

`IAM グループ`は対象になっていません。
つまりEKSクラスタの利用者が多数になっても`一つ一つのIAMユーザをaws-authに追加していく必要がある`みたいです。
(あまり大規模なクラスタを組むように設計されていない香りがします)

aws-authにIAMユーザを紐付けるさいは以下のように`mapUsers`にIAMユーザのARNとGroupsを記載するようです。

```yaml

apiVersion: v1
data:
  mapRoles: |
    - rolearn: arn:aws:iam::11111111111:role/xxxxxxxxx
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
  mapUsers: |
    - userarn: arn:aws:iam::11111111111:user/admin
      username: admin
      groups:
        - system:masters
```

リストになっているので`単一のユーザが複数のgroupに所属する`事はできそうですが
さて、`groups`とは一体何でしょうか。以下のように説明されています。
> groups: A list of groups within Kubernetes to which the role is mapped.

私はここで完全にkubernetesの`Role`または`ClusterRole`を記載するものだと思っていました。
(間違いです)

## Roleを指定してaws-authで認証認可を設定する(失敗)

開発者のIAMユーザに対し、開発用のNameSpaceとRoleを渡すシナリオを想定しました。
aws-authにRoleを指定して紐付けようとしました(もちろん失敗します)

### NameSpaceとroleの作成

```
$ kubectl create namespace develop-ns
namespace/develop-ns created
```
yamlファイル`develop-role.yaml`作成

```
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: develop-ns
  name: develop-role
rules:
- apiGroups: [""]
  verbs: ["*"]
  resources: ["services", "pods", "configmaps", "endpoints", "persistentvolumeclaims", "replicasets"]
```

```
$ kubectl create -f develop-role.yaml
role.rbac.authorization.k8s.io/develop-role created
```
できました。

```
$ kubectl get role --all-namespaces
NAMESPACE     NAME                                             AGE
develop-ns    develop-role                                     2m7s
kube-public   system:controller:bootstrap-signer               6d5h
kube-system   extension-apiserver-authentication-reader        6d5h
kube-system   system::leader-locking-kube-controller-manager   6d5h
kube-system   system::leader-locking-kube-scheduler            6d5h
kube-system   system:controller:bootstrap-signer               6d5h
kube-system   system:controller:cloud-provider                 6d5h
kube-system   system:controller:token-cleaner                  6d5h
```

### aws-authに追加する

```
$ kubectl edit configmap aws-auth
```

```yaml
apiVersion: v1
data:
  mapUsers: |
    - userarn: arn:aws:iam::111111111:user/develop-user
      username: develop
      groups:
        - develop-role
kind: ConfigMap
```

### aws cliとaws-iam-authenticatorで認証

[aws-iam-authenticator](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/configure-kubectl.html)をインストール後aws cliでkube configを更新する

```
aws eks update-kubeconfig --name <Cluster Name> --region us-east-1
Added new context arn:aws:eks:us-east-1:114514:cluster/<Cluster Name> to /Users/xxx/.kube/config
```

### 認証・認可できたか確かめる
```
$ kubectl get svc -n develop-ns
Error from server (Forbidden): services is forbidden: User "develop" cannot list services in the namespace "develop-ns"
```

一応developユーザとして認証はできているようですが、Roleによる認可ができていないみたいです。


## GroupsはほんとうにKubernetes的な意味でのGroups

ここで、KubernetesのRolebindingに指定する対象として
User/ServiceAccount/`Group`の３種がありますが、
aws-authに使用するGroupとはまさにこのGroupを指していると気づきました。

Groupを扱ったことはなかったため、Groupとは何か、作成方法、一覧の取得方法など調査しましたが
いまだググっても有力な記事を見つけられておらず・・・
(まともに情報あるのServiceAccountくらいなのでは)

確認できているのはcluster-adminロールに紐付けられた`system:masters`と呼ばれるグループだけです。


```
$ kubectl describe clusterrolebinding cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name            Namespace
  ----   ----            ----
```

### system:masterをaws-authに追加

```yaml
apiVersion: v1
data:
  mapRoles: |
    - rolearn: arn:aws:iam::111111111111:role/Test-EKS-Cluster-NodeInstanceRole-1IYPTP58375UR
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
  mapUsers: |
    - userarn: arn:aws:iam::111111111111:user/member.test
      username: develop
      groups:
        - system:masters
```

開発用ユーザでkubectlを実行

```
$ kubectl get svc -n develop-ns
No resources found.
$ kubectl auth can-i get svc -n develop-ns
yes
```
認証され、動作するようになりました。

```
$ kubectl auth can-i delete clusterrole
yes
$ kubectl auth can-i delete node
yes
$ kubectl auth can-i delete pv
yes
```
cluster-adminなのでなんでもできます。


#所感
兎にも角にも`system:masters`のようなGroupの作成方法がわからないと
任意の権限をIAMユーザに紐づけできないので
EKSのユーザガイドにはこのあたりの情報を充実させてほしいと思っています
(内容的にはK8sの領域なのかもしれませんが)。　　

また詳しい方おりましたら情報お待ちしております...


以上。