備忘録：kubernetes/EKS基礎③(認証関連)

# 備忘録

下記認証の際にk8sの仕組みとAWS IAMの仕組みを使用するため複雑
仕組みと各マニフェスト間の設定の紐付けをまとめておく

* kubectlでEKSに接続する時
* IAM Roles for Service Accounts(IRSA)

# kubectlでの認証

## 概要

```shell
aws eks update-kubeconfig --name eks-clu
kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-92-154.ap-northeast-1.compute.internal   Ready    <none>   25m   v1.23.13-eks-fb123a0
```
```~/.kube/config```が作成される。```clusters```にクラスタ情報、```users```にユーザー情報、 ```contexts```にクラスターとユーザーの関連付けが記載される。

```yml:~/.kube/config
users: # users以下を記載
- name: arn:aws:eks:ap-northeast-1:xxxxxxxxxxx:cluster/eks-clu
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - --region
      - ap-northeast-1
      - eks
      - get-token
      - --cluster-name
      - eks-clu
      command: aws
```
```aws --region ap-northeast-1 eks get-token --cluster-name eks-clu```でトークンを取得してEKSのコントロールプレーンに送信。EKS側でIAMを参照して登録されているユーザ情報を確認。

eksctlでクラスタを作成したユーザはデフォルトで管理者権限がある。
下記からeks-opeという新しいユーザを作成して検証する。

```shell
aws configure # eks-opeユーザの情報入力
kubectl get node
error: You must be logged in to the server (Unauthorized)
```

## 仕組み

下記のように```aws-auth```,```RoleBinding```,```Role```の３つのリソース作成が必要。
Roleで許可する操作を定義して、RoleBindingでk8sのグループを作成してRoleに紐づける。aws-authでIAMユーザとk8sのグループを紐づける。

![スクリーンショット 2022-12-22 8.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/157bcff1-e556-5371-9a45-0b93e2fb610b.png)

## 手順

クラスタを作成した権限のユーザで下記マニフェストを作成して実行

```yml:ClusterRole.yml
clusterrolebinding.rbac.authorization.k8s.io/test-clu-rolebinding created
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: test-clu-role
rules:
- apiGroups: [""]
  resources: ["pods","nodes"]
  verbs: ["get", "watch", "list"]
```

```yml:ClusterRoleBinding.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-clu-rolebinding
subjects:
- kind: Group
  name: operators
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: test-clu-role
  apiGroup: rbac.authorization.k8s.io
```

```shell
eksctl create iamidentitymapping \
    --cluster eks-clu \
    --region=ap-northeast-1 \
    --arn arn:aws:iam::{AWS_ACCOUNT_ID}:user/eks-ope \
    --group operators \
    --no-duplicate-arns
```

```shell
eksctl get iamidentitymapping --cluster eks-clu --region=ap-northeast-1
```
eks-opeユーザのIAM認証情報でEKSクラスタに接続出来ることを確認

## 参考

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html

# サービスアカウントのIAMロール

IAM Roles for Service Accounts(IRSA)と呼ばれる。IAMロールをPodに紐づけてAWSリソースへのアクセス制御をする仕組み

## 仕組み

![スクリーンショット 2022-12-22 10.27.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/edbd8c15-4f8c-d2b8-b17a-8a099a1c0200.png)

ServiceAccoutを作成するとトークン情報を含んだSecretが作成される。このSecret情報がPodの所定のディレクトリにマウントされる。Podはこの情報を使用してOICD Provider経由で認証。Service Accountに関連付けられたロールが利用出来るようになる。認証情報は環境変数としてPod内に格納。（多分）

## 手順

全体的に設定の紐付けは下記のようになっています。

![スクリーンショット 2022-12-22 10.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/f0dc8641-b4b0-f17c-d546-ee0198e1d20a.png)


クラスター用の IAM OIDC プロバイダーの作成

```shell
eksctl utils associate-iam-oidc-provider --cluster eks-clu --approve
```
IAMロール作成
```shell
aws iam create-role --role-name sa-role --assume-role-policy-document \
'{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::{AWS_ACCOUNT_ID}:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/{OIDC-Provider-ID}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.ap-northeast-1.amazonaws.com/id/{OIDC-Provider-ID}:sub":"system:serviceaccount:default:test-sa"
        }
      }
    }
  ]
}'
```

IAMロールにIAMポリシー紐付け（テストでS3ReadOnlyAccessを追加）

```shell
aws iam attach-role-policy --role-name sa-role --policy-arn 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess'
```

サービスアカウント作成

```yml:ServiceAccount.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: default
  name: test-sa
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::{AWS_ACCOUNT_ID}:role/sa-role
```

テスト用Pod作成

```yml:test-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: default
spec:
  containers:
  - name: test-pod
    image: amazon/aws-cli
    command: ["aws"]
    args: ["s3", "ls"]
  serviceAccountName: test-sa
```

S3にアクセス出来ていることを確認

```shell
kubectl logs test-pod
2022-11-30 22:47:14 cf-templates-xxxxxxxxx-ap-northeast-1
```

# 関連記事

https://qiita.com/tkubota/items/021b775e4b8b3fad9bab

https://qiita.com/tkubota/items/349d7529667870439e41

https://qiita.com/tkubota/items/f84468e2d65f1b27fd51