EKSでIAMユーザをアクセスコントロール (RBAC)

`Kubernetes3 Advent Calendar 2018` に空きがあったのでぶっこんでみました。

EKSでIAMユーザ or ロールによるRBACについて、AWSのドキュメントでは分かりにくかったので、まとめときます。

# 概要
EKSでは、IAMユーザー、もしくはIAMロールにRBACによる制限を適用できます。(IAMグループにはできないっぽい)
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html

ここにあるとおり、`aws-auth`というConfigMap を編集して、IAMユーザorロールを`groups`に紐付けるという手順で行うようです。
この `groups` については、上のドキュメントでは `system:master`しか書かれていないので分かりにくいですが、k8sの方でロールを紐づけた`groups`を作成するようです。


上のドキュメントにもある、管理者に適用される`system:master`というgroupsはk8sの中で、`cluster-admin` に紐付けるられているようです。

```bash:
$ kubectl describe clusterrolebinding cluster-admin                                                           [14:52:54]
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
  ----   ----            ---------
  Group  system:masters
```

要は**IAMのポリシーではなく、k8sのロールで管理する**と。

# 手順

EKSクラスタ、kubectl、aws-cli、aws-iam-authenticatorとかのセットアップはできてることを前提としています。

## 管理者側設定
### IAMユーザをつくる

まず、制限を適用したいIAMユーザをつくります。(割愛)

### IAMユーザにポリシーを適用

`aws eks update-kubeconfig`が実行できればいいみたいです。
とりあえず最低限これでいけそうです。

```json:policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "eks:UpdateClusterVersion",
                "eks:DescribeCluster",
                "eks:ListClusters"
            ],
            "Resource": "*"
        }
    ]
}
```
これのポリシーをつくってユーザに適用します。

### IAMユーザのキーを発行

このへんも割愛。


### k8s RBAC設定

`stg` というnamespece上のPodの確認だけできる `stg-user-group` という名前のグループを作る場合はこんな感じになります。

```yaml:stg-user-group.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: stg
  name: stg-user-role
rules:
- apiGroups: [""]
  verbs: ["get", "list"]
  resources: ["pods"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: stg-user-group
  namespace: stg
subjects:
- kind: Group
  name: stg-user-group
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: stg-user-role
```

これを適用します。

```bash:
$ kubectl apply -f stg-user-group.yaml
```

### configmap/aws-authの編集

`kubectl edit`で`configmap/aws-auth`を編集します。
```bash:
$EDITOR=vim kubectl edit -n kube-system configmap/aws-auth
```

IAMロールにグループを紐付けるときは、

```yaml:
  mapRoles: |
    - rolearn: arn:aws:iam::xxxxxxxxxxx:role/admin
      username: admin
      groups:
        - グループ名
```

IAMユーザにグループを紐付けるときは、

```yaml:
  mapUsers: |
    - rolearn: arn:aws:iam::xxxxxxxxxxx:role/user
      username: user
      groups:
        - グループ名
```

のように追記します。

自分の環境ではこんな感じです。
`admin`というIAMロールに管理者権限の`system:masters`を割り当て、`develop-user`というIAMユーザに制限を適用した`stg-user-group`を割り当てています。

```yaml:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::xxxxxxxxxxx:role/testcluster-nodegroup-0-NodeInstanceRole-xxxxxxxxxxx
      username: system:node:{{EC2PrivateDNSName}}
    - rolearn: arn:aws:iam::xxxxxxxxxxx:role/admin
      username: admin
      groups:
        - system:masters
  mapUsers: |
    - userarn: arn:aws:iam::xxxxxxxxxxx:user/develop-user
      username: develop
      groups:
        - stg-user-group
kind: ConfigMap
metadata:
  creationTimestamp: 2018-12-21T02:52:20Z
  name: aws-auth
  namespace: kube-system
  resourceVersion: "613101"
  selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
  uid: 6f79ec33-04cb-11e9-9c8e-xxxxxxxxxxx
```




## 制限ユーザのセットアップ
### 発行したIAMキーをセットアップ
キーですが、EKSでkubectl使うときは`$AWS_ACCESS_KEY_ID`とかの変数ではうまく動かないかもしれないので、 `~/.aws/credentials`で指定したほうがよさそうです。
https://stackoverflow.com/questions/53266960/how-do-you-get-kubectl-to-log-in-to-an-aws-eks-cluster

```bash:
$ aws configure
```


## kubeconfigを取得

```
$ aws eks update-kubeconfig --name (クラスタ名) --region ap-northeast-1
```

## 動作確認

namespece stgではPODの情報が見れます。

```
$ kubectl get pod -n stg
NAME                     READY     STATUS    RESTARTS   AGE
nginx-64f497f8fd-d5ltm   1/1       Running   0          10s
```

stg以外のnamespaceでは失敗します。

```
$ kubectl get pod -n prod
Error from server (Forbidden): pods is forbidden: User "develop" cannot list pods in the namespace "prod"
```

stgでもcreateは失敗します。

```
$ kubectl apply -f test-pod.yaml -n stg
Error from server (Forbidden): error when creating "test-pod.yaml": pods is forbidden: User "develop" cannot create pods in the namespace "stg"
```

## まとめ
EKSでのRBACによる制限のポリシーはIAMポリシーではなく、k8sのロールで管理します。
そのうちEKSのドキュメントにちゃんと書かれるのではないかと・・・