【EKS】AWS Load Balancer Controller導入手順

### 導入

業務で扱っているアプリケーションの動作環境がEKSで、Ingress Controllerとして「AWS Load Balancer Controller」を導入する機会があった。仕組みを理解するのに少し時間かかったので、備忘録として残す。

---
### 参考

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/enable-iam-roles-for-service-accounts.html

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html

---
### 全体像
![スクリーンショット 2021-12-21 11.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/0c53b81e-322e-df37-1c0d-fee7f39ddd33.png)

作るもの
・IAM OIDCプロバイダ
・IAMロール/IAMポリシー
・k8s内のServiceAccount
・k8s内のPod(AWS Load Balancer Controller)

---
### 導入手順

#### 手順1：IAM OIDCプロバイダ作成

IAM OIDCプロバイダはIAMのコンソール画面より作成可能だが、eksctl utilsの1コマンドで作成できる。

```
eksctl utils associate-iam-oidc-provider --cluster <cluster_name> --approve
```
コマンド実行結果

```
hoge@hogehogenoMacBook-Air k8s practice % eksctl utils associate-iam-oidc-provider --cluster test-cluster --approve
2021-12-21 09:45:15 [ℹ]  eksctl version 0.76.0
2021-12-21 09:45:15 [ℹ]  using region ap-northeast-1
2021-12-21 09:45:16 [ℹ]  will create IAM Open ID Connect provider for cluster "test-cluster" in "ap-northeast-1"
2021-12-21 09:45:16 [✔]  created IAM Open ID Connect provider for cluster "test-cluster" in "ap-northeast-1"
```

手順1実施後の状態
![スクリーンショット 2021-12-21 11.31.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/e969ec90-6d0a-4ec4-b6da-e38cc3363a1d.png)

※ IAM OIDCプロバイダとは？
・IAMロール、IAMポリシー等に並んで存在するもの
・**IAM OIDCプロバイダが提供するIDトークン ＝ AWS STSが発行するトークン**
・EKSクラスタ内のPodが他のAWSリソースに対して操作したい時に、
　IDトークンとして「対象AWSリソースの操作権限を持つSTSトークン」を提供してあげる。

https://qiita.com/crml1206/items/2d47af92e8ffc63bf2a6

---
#### 手順2：IAMポリシー作成（ALBを作成する権限）

IAMポリシー用のJSON取得

```
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/iam_policy.json
```

IAMポリシー作成コマンド

```
aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json
```

コマンド実行結果

```json
{
    "Policy": {
        "PolicyName": "AWSLoadBalancerControllerIAMPolicy",
        "PolicyId": "ANPAVWWCJ6364SU2N2RSN",
        "Arn": "arn:aws:iam::392323266301:policy/AWSLoadBalancerControllerIAMPolicy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2021-12-21T00:47:53+00:00",
        "UpdateDate": "2021-12-21T00:47:53+00:00"
    }
}
```

手順2実施後の状態
![スクリーンショット 2021-12-21 12.13.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/1e732aa2-66a9-0d2c-5ec3-80720ae02e59.png)

---
#### 手順3：k8s内のServiceAccount＆IAMロール作成

・「eksctl create iamserviceaccount」で
　　①k8s内のServiceAccount
　　②ServiceAccountに紐づかせるIAMロール
　の両方を作成できる

```
eksctl create iamserviceaccount \
  --cluster= <cluster-name> \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --attach-policy-arn=arn:aws:iam::<手順2で作成したIAMポリシーのARN>:policy/AWSLoadBalancerControllerIAMPolicy \
  --override-existing-serviceaccounts \
  --approve
```

コマンド実行結果

```
2021-12-21 09:49:14 [ℹ]  eksctl version 0.76.0
2021-12-21 09:49:14 [ℹ]  using region ap-northeast-1
2021-12-21 09:49:15 [ℹ]  1 iamserviceaccount (kube-system/aws-load-balancer-controller) was included (based on the include/exclude rules)
2021-12-21 09:49:15 [!]  metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set
2021-12-21 09:49:15 [ℹ]  1 task: { 
    2 sequential sub-tasks: { 
        create IAM role for serviceaccount "kube-system/aws-load-balancer-controller",
        create serviceaccount "kube-system/aws-load-balancer-controller",
    } }2021-12-21 09:49:15 [ℹ]  building iamserviceaccount stack "eksctl-test-cluster-addon-iamserviceaccount-kube-system-aws-load-balancer-controller"
2021-12-21 09:49:16 [ℹ]  deploying stack "eksctl-test-cluster-addon-iamserviceaccount-kube-system-aws-load-balancer-controller"
2021-12-21 09:49:16 [ℹ]  waiting for CloudFormation stack "eksctl-test-cluster-addon-iamserviceaccount-kube-system-aws-load-balancer-controller"
2021-12-21 09:49:32 [ℹ]  waiting for CloudFormation stack "eksctl-test-cluster-addon-iamserviceaccount-kube-system-aws-load-balancer-controller"
2021-12-21 09:49:49 [ℹ]  waiting for CloudFormation stack "eksctl-test-cluster-addon-iamserviceaccount-kube-system-aws-load-balancer-controller"
2021-12-21 09:49:51 [ℹ]  created serviceaccount "kube-system/aws-load-balancer-controller"

# kube-system名前空間にServiceAccount「aws-load-balancer-controller」が作成されていることを確認
hoge@hogehogenoMacBook-Air k8s practice % kubectl get sa -n kube-system
NAME                                 SECRETS   AGE
attachdetach-controller              1         30m
aws-cloud-provider                   1         30m
aws-load-balancer-controller         1         2m7s ←作成されている
aws-node                             1         31m
certificate-controller               1         30m
```

手順3実施後の状態
![スクリーンショット 2021-12-21 11.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/9813ae7f-d450-170e-13a2-60c1d2da9e9b.png)

※ ServiceAccountとは？
・Pod内から**Pod外のリソース**にアクセスするためのロール
・k8s内で管理されるもの

---
#### 手順4：AWS Load Balancer Controller(Pod)の作成

・helm chartsを利用する

実行コマンド

```
a. TargetGroupBinding のカスタムリソース定義をインストール【ALB作成時に利用する情報】
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"

b. eks-charts リポジトリを追加
helm repo add eks https://aws.github.io/eks-charts

c. ローカルリポジトリを更新して、最新のグラフがあることを確認
helm repo update

d. AWS Load Balancer Controllerをインストール
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
  --set clusterName=test-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  -n kube-system

e. Controllerがinstallされていることの確認
kubectl get deployment -n kube-system aws-load-balancer-controller
```

e. Controllerがinstallされていることの確認

```
hoge@hogehogenoMacBook-Air k8s practice % kubectl get deployment -n kube-system aws-load-balancer-controller
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           58s
hoge@hogehogenoMacBook-Air k8s practice % kubectl get pod -n kube-system                                    
NAME                                            READY   STATUS    RESTARTS   AGE
aws-load-balancer-controller-7684b8d694-gj6z5   1/1     Running   0          61s ★作成されている★
aws-load-balancer-controller-7684b8d694-px5m7   1/1     Running   0          61s ★作成されている★
aws-node-lq79l                                  1/1     Running   0          20m
aws-node-wb7l5                                  1/1     Running   0          25m
coredns-76f4967988-6cg68                        1/1     Running   0          34m
coredns-76f4967988-bq9g2                        1/1     Running   0          34m
kube-proxy-8bcmx                                1/1     Running   0          25m
kube-proxy-lc86n                                1/1     Running   0          20m
```

手順4実施後の状態
![スクリーンショット 2021-12-21 12.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/18aa93db-8051-a0fe-6c49-efe4c94347e5.png)


※ helm chartsとは？
・誰かが用意してくれたYAML一式でPod構築できちゃうやつ
　（めちゃめちゃ説明雑だがあってるはず笑）
・自分で0からAWS Load Balancer ControllerのYAMLを組むのはめっちゃだるい
　 → 既に用意されているYAML一式をhelm chartsで利用する

---
### Ingressリソースを検知してALBが作成される

![スクリーンショット 2021-12-21 12.18.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653955/17c28021-ccf6-42dc-77af-a038c23b4aee.png)