AWSのスイッチロールを使っている際に、KubernetesのRBAC認証設定について

# 初めに
またアドベントカレンダーの記事を書く時期、
アドベントカレンダー以外でも、記事を書く習慣を身につけたいですねｗ

今回は `KubernetesのRBAC認証設定について` 書きました

# 概要
Kubernetesは独自の[RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)認証があるので、IAMの権限があっても、RBACの設定を更新しない限り、EKSのクラスターに対して、 `kubectl` を叩くことができない

https://aws.amazon.com/jp/premiumsupport/knowledge-center/amazon-eks-cluster-access/

> AWS Identity and Access Management (IAM) エンティティが Amazon EKS クラスターのロールベースアクセス制御 (RBAC) 設定によって承認されていない場合、承認エラーが発生します


複数のAWSアカウントを管理するために、スイッチロールを利用しているのは一般的ですが、
スイッチロール先に個人ユーザーが存在しないため、ユーザー単位でKubernetesのRBACに登録することは出来ないので、
スイッチロール元のユーザーを登録する（別のAWSアカウントユーザーを登録する）方法を紹介します

# Requirement
## eksctlをインストールする
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html

- mac
    - [Homebrewのインストールが必要](https://brew.sh/)


```bash
$ brew tap weaveworks/tap
$ brew install weaveworks/tap/eksctl
$ eksctl version
```

- windows
    - [Chocolateyのインストールが必要](https://chocolatey.org/install)


```bash
$ chocolatey install -y eksctl aws-iam-authenticator
$ chocolatey upgrade -y eksctl aws-iam-authenticator
$ eksctl version
```

## Amazon EKS提供のkubectlをインストールする
- [kubectl のインストール](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)

# RBAC認証設定
ロール登録やユーザー登録の方法も記載する
## ロールを登録する手順

### kubeconfigをAmazon EKS用に作成する
- ユーザーごとに各自作成する

#### aws-cliで自動作成
`aws eks update-kubeconfig` を使って、kubeconfigを自動作成することができる

```console
$ aws eks update-kubeconfig --name ${クラスター名} --profile ${プロファイル名}
Added new context arn:aws:eks:ap-northeast-1:xxxxxxxxxxxx:cluster/ClusterName to ~/.kube/config
```

- 以下のように、クラスター情報やユーザー情報を `~/.kube/config` に追加される

```yaml
(省略）
users:
- name: {cluster-arn}
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - ap-northeast-1
      - eks
      - get-token
      - --cluster-name
      - {クラスター名}
      command: aws
      env:
      - name: AWS_PROFILE
        value: {プロファイル名}

```

### 現在のconfigmapを確認する
- `kubectl` 実行できる環境で実施してください
    - 新規作成の場合は `configmap` 存在しない

```console
$ kubectl describe configmap -n kube-system aws-auth
```
### configmapの修正

`mapRoles` を追加する

```aws-auth-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws:iam::{スイッチロール先のアカウントID}:role/{ロール名}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
    - rolearn: arn:aws:iam::{スイッチロール先のアカウントID}:role/{スイッチロール時に使用するロール名}
      username: {ユーザー名 / スイッチロール時に使用するロール名}
      groups:
        - system:masters
```

### 設定を反映する
- `kubectl` 実行できる環境で実施してください
    - 新規作成の場合は、最初の一回だけ誰でも反映できるらしい

```bash
$ kubectl apply -f aws-auth-cm.yaml
```

## ユーザを追加する手順
- 参考
    - [クラスターのユーザーまたは IAM ロールの管理](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html)

### kubeconfigをAmazon EKS用に作成する
- ユーザーごとに各自作成する

#### aws-cliで自動作成
`aws eks update-kubeconfig` を使って、kubeconfigを自動作成することができる

```console
$ aws eks update-kubeconfig --name ${クラスター名} --profile ${プロファイル名}
Added new context arn:aws:eks:ap-northeast-1:xxxxxxxxxxxx:cluster/ClusterName to ~/.kube/config
```

- `env` 部分の `AWS_PROFILE` は、自分のAWSクレディンシャル設定により`変更 / コメントアウト` する必要がある

#### 手動で作成
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/create-kubeconfig.html#create-kubeconfig-manually


```yaml
apiVersion: v1
clusters:
- cluster:
    server: {endpoint-url}
    certificate-authority-data: {base64-encoded-ca-cert}
  name: {cluster-arn}
contexts:
- context:
    cluster: {cluster-arn}
    user: {cluster-arn}
  name: {cluster-arn}
current-context: {cluster-arn}
kind: Config
preferences: {}
users:
- name: {cluster-arn}
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - ap-northeast-1
      - eks
      - get-token
      - --cluster-name
      - {クラスター名}
      command: aws
      # スイッチロール元のクレディンシャルの設定profile、defaultの場合は記入なしで大丈夫
      #env:
      #- name: AWS_PROFILE
      #  value: {プロファイル名}

```
endpoint-url, base64-encoded-ca-cert, cluster-arn はコンソール画面で確認できる

### 現在のconfigmapを確認する
- `kubectl` 実行できる環境で実施してください
    - 新規作成の場合は `configmap` 存在しない

```console
$ kubectl describe configmap -n kube-system aws-auth
```
### configmapの修正

`mapUsers` を追加する

```aws-auth-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws:iam::{スイッチロール先のアカウントID}:role/{ロール名}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
  mapUsers: |
    - userarn: arn:aws:iam::{スイッチロール元のアカウントID}:user/{ユーザー名}
      username: {ユーザー名}
      groups:
        - system:masters
    - userarn: arn:aws:iam::{スイッチロール元のアカウントID}:user/{ユーザー名}
      username: {ユーザー名}
      groups:
        - iam:base-users
```


### 設定を反映する
- `kubectl` 実行できる環境で実施してください
    - 新規作成の場合は、最初の一回だけ誰でも反映できるらしい

```bash
$ kubectl apply -f aws-auth-cm.yaml
```

# 確認
- `kubectl get svc` 叩けるなら成功です

```bash
# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   42m
```

# 最後
ロールで認証するのが一般的だと思いますが、諸事情でロール認証を利用できない場合は、
ユーザーで認証する事もできます