Fargate for EKS を早速使ってみた

[前の記事](https://qiita.com/itti1021/items/da8166539167c347c1a5) を書いた次の週に 「AWS re:Invent 2019」 で発表された
期間が空かないうちに試用

# Fargate を利用すると
- 利用する CPU とメモリを指定するだけでリソースの管理が不要
- スケーリングが自動
- ホストマシンのセキュリティ管理等が不要

# 作成
下記の手順で作成
今回は以前使わなかった [eksctl](https://eksctl.io/) を使ってみる

[Getting Started with AWS Fargate on Amazon EKS - AWS](https://docs.aws.amazon.com/en_us/eks/latest/userguide/fargate-getting-started.html)

## 環境
Windows 10

AWS CLI 1.16.191
[AWS CLI のインストール - AWS](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html)

kubectl 1.14.8
[kubectl のインストール - AWS](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)

eksctl 0.11.1
[eksctl のインストールまたはアップグレード - AWS](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eksctl.html#installing-eksctl)

## 手順
これだけ

```
$ eksctl create cluster --name [cluster-name] --fargate
```
あとは kubeconfig に作成したクラスターを設定すれば使える

```
$ aws eks --region ap-northeast-1 update-kubeconfig --name [cluster-name]
```

## 確認
```
$ kubectl get node
NAME                                                         STATUS   ROLES    AGE     VERSION
fargate-ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal   Ready    <none>   3m32s   v1.14.8-eks
fargate-ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal   Ready    <none>   3m12s   v1.14.8-eks
```

```
$ kubectl get pod -n kube-system
NAME                       READY   STATUS    RESTARTS   AGE
coredns-6d75bbbf58-c8nnz   1/1     Running   0          4m39s
coredns-6d75bbbf58-vnw4l   1/1     Running   0          4m39s
```

## Nginx をデプロイしてみる

```
$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-65f88748fd-2wwn2   1/1     Running   0          49s
```
ちゃんと Fargate Node も増えている

```
$ kubectl get node
NAME                                                         STATUS   ROLES    AGE     VERSION
fargate-ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal   Ready    <none>   103s    v1.14.8-eks
fargate-ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal   Ready    <none>   9m32s   v1.14.8-eks
fargate-ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal   Ready    <none>   9m12s   v1.14.8-eks
```

## 削除
--wait オプションでスタックのエラーによる削除漏れを回避できる
[Creating a cluster - eksctl](https://eksctl.io/usage/creating-and-managing-clusters/)

```
$ eksctl delete cluster --name [cluster-name] --wait
```
作成も削除も手軽すぎる・・・

# 実は
12/4 GA → 12/6 作業 → 12/12 記事作成
12/6 での作業時は --fargate オプションを付けずに作成していたため割と手間取った
せっかくなので残しておいたメモだけ記述

# 作成 (--fargate 無し)
参考元は同様

[Getting Started with AWS Fargate on Amazon EKS - AWS](https://docs.aws.amazon.com/en_us/eks/latest/userguide/fargate-getting-started.html)

## 流れ
1. [クラスター](#クラスター)
2. [ポッド実行ロール](#ポッド実行ロール)
3. [Fargate Profile](#fargate-profile)
4. [kubeconfig 設定](#kubeconfig-設定)
5. [CoreDNS](#coredns)

### クラスター
```
$ eksctl create cluster --name [cluster-name]
```

### ポッド実行ロール
下記 json でロールの作成

```trust-relationship.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "eks-fargate-pods.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

```
$ aws iam create-role --role-name AmazonEKSFargatePodExecutionRole --assume-role-policy-document file://trust-relationship.json
```
ポリシーのアタッチ

```
$ aws iam attach-role-policy --role-name AmazonEKSFargatePodExecutionRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy
```
### Fargate Profile
コンソールパネルから作成
ロールは先ほど作成した AmazonEKSFargatePodExecutionRole
サブネットには Private のみを指定
Pod Selectors はFargate で実行させたい namespace を入力 (とりあえず default と kube-system)

### kubeconfig 設定
```
$ aws eks --region ap-northeast-1 update-kubeconfig --name [cluster-name]
```

### CoreDNS
デフォルトだと EC2 でポッドが実行されるようになっているため
Fargate のみを使用するように設定した CoreDNS をデプロイ

```coredns.json
{
    "fargateProfileName": "coredns",
    "clusterName": "xxx,
    "podExecutionRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/AmazonEKSFargatePodExecutionRole",
    "subnets": [
        "subnet-xxxxxxxxxxxxxxxxx",
        "subnet-xxxxxxxxxxxxxxxxx",
        "subnet-xxxxxxxxxxxxxxxxx"
    ],
    "selectors": [
        {
            "namespace": "kube-system",
            "labels": {
                "k8s-app": "kube-dns"
            }
        }
    ]
}
```
[clusterName] [podExecutionRoleArn] [subnets] を埋めて

```
$ aws eks create-fargate-profile --cli-input-json file://coredns.json
```
> ここで公式の手順だと

> ```
$ kubectl patch deployment coredns -n kube-system --type json \
-p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
```
とあるが parse error が出たので直接編集

デプロイされている CoreDNS から yaml を生成

```
$ kubectl get pods -o yaml -n kube-system > coredns.yaml
```
'eks.amazonaws.com/compute-type: ec2' を削除し更新

```
$ kubectl apply -f coredns.yaml
```
Fargate Node が出力されれば完了

```
$ kubectl get node
```

## 削除
1. Fargate Profile を削除
2. スタックを削除
3. クラスターを削除

--fargate のオプションがないため Node のスタックも作られてしまっているので注意

# 総括
やはりリリースしたてのサービスを触るのは楽しい
--fargate を見逃して無駄な作業を増やしてしまったのは反省点ではあるが勉強にもなった
EKS だけの構成を触った経験を生かせたと思う

eksctl は強かった