EKSでMattermostを構築した話：2. EKSクラスター作成編

## 今回、作成するもの
- EKSクラスター
- 前回作成したVPCの各値を利用してEKSクラスターを作成していきます。
    - [EKSでMattermostを構築した話：1. VPC作成編 - Qiita](https://qiita.com/tnagano1981/items/75408d509c0660408c97)

## イメージしている構成
- 赤枠で囲んだEC2、2台で構成するEKSを作っていきます。
![vpc01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/f39db2c7-a97f-f6e9-7669-b06b8b538793.png)

## 構築方法
- 踏み台サーバから`eksctl`を使って以下のyamlを適用します。
    - create-eks-cluster.yaml 

```yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: ver-Mattermost-eks
  region: ap-northeast-1

vpc:
  id: "vpc-xxxxxxxxxxxxxx" # 前段階で作成したVPCのIDを入力
  cidr: "10.0.0.0/16"
  clusterEndpoints:
    privateAccess: true
    publicAccess: true
  publicAccessCIDRs:
    - "xx.xx.xx.xx/32" # ここは踏み台サーバのグローバルIPを指定する(と良いと思われる、今回はそれをしなくて後で設定追加をした)
  subnets:
    public:
      ap-northeast-1a:
        id: "subnet-xxxxxxxxxxxxxx" # 前段階で作成したsubnetのIDを入力
        cidr: "10.0.10.0/24"
      ap-northeast-1c:
        id: "subnet-xxxxxxxxxxxxxx"
        cidr: "10.0.11.0/24"
      ap-northeast-1d:
        id: "subnet-xxxxxxxxxxxxxx"
        cidr: "10.0.12.0/24"
    private:
      ap-northeast-1a: 
        id: "subnet-xxxxxxxxxxxxxx"
        cidr: "10.0.20.0/24"
      ap-northeast-1c: 
        id: "subnet-xxxxxxxxxxxxxx"
        cidr: "10.0.21.0/24"
      ap-northeast-1d: 
        id: "subnet-xxxxxxxxxxxxxx"
        cidr: "10.0.22.0/24"

nodeGroups:
  - name: Mattermost-eks-node
    instanceType: t3.medium
    volumeSize: 50
    desiredCapacity: 2
    privateNetworking: true # ここをtrueにするとプライベートサブネットにEKSクラスターが作成される
    minSize: 2
    maxSize: 4
    iam:
      withAddonPolicies:
        autoScaler: true
```

- これでプライベートサブネットにEC2が2台作られてEKSクラスターとして設定されます。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/d71eaf42-ab2b-6553-0576-46a564bf268e.png)
  ![eks001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/30ec94d0-8301-0c69-104d-858d2d87f95a.png)

- 今回の`create-eks-cluster.yaml`では`vpc`と`nodegroup`を同時に定義していますが、`nodegroup`は随時更新がかかる可能性が高いので別のテンプレートにすることも考慮した方がいいかもしれません。
- あとはEC2にsshするためのキーペアの設定も今回はしていないですが、その辺りも考慮が必要な点かと思っています。


## 確認：作成したEKSクラスターに接続できるか
- では確認ということで、踏み台サーバにアクセスして、`kubectl`が利用できるかを確認してみます。
    - ここで、つまづきました、、、kubectlコマンドを打っても反応がないのです、、、  
    
```shell:
$ kubectl get svc
Unable to connect to the server: dial tcp 10.0.20.12:443: i/o timeout
```

- 上記の現象は`create-eks-cluster.yaml`の中でもコメントに書いたのですが、`publicAccessCIDRs`の値を踏み台サーバのグローバルIPに指定しなかったことから来る通信不通の状況かと思われます。
- ということで、手作業でセキュリティグループに踏み台サーバからのアクセスを許可する設定を入れて解決しました。
    - 具体的には以下にまとめたセキュリティグループの`項番：4`に、踏み台サーバのセキュリティグループからのhttpsのインバウンド通信を許可することで対応を行いました。

### 補足：eksctlで作られたセキュリティグループ

| 項番 | セキュリティグループ名 | 説明  |
|---|---|---|
|1  | eks-cluster-sg-ver-Mattermost-eks-xxxxxxx |管理されていないノードがコントロールプレーン（全ポート）と通信できるようにする  |
|2  | eksctl-ver-Mattermost-eks-cluster/ClusterSharedNodeSecurityGroup  | 管理ノードと非管理ノードが相互に通信できるようにする（すべてのポート)    ノード同士の通信を許可する（すべてのポート）  |
|3  |eksctl-ver-Mattermost-eks-nodegroup-Mattermost-eks-node/SG   |ワーカーノードがコントロールプレーン（kubeletとワークロードのTCPポート）と通信できるようにします。ワーカーノードがコントロールプレーンと通信することを許可します(HTTPSポートを使用するワークロード、拡張APIサーバで一般的に使用されます) |
|4  |eksctl-ver-Mattermost-eks-cluster/ControlPlaneSecurityGroup  |コントロールプレーンがワーカーノードからAPIリクエストを受信できるようにします。 |

- このセキュリティグループの1つずつがどことどこを接続しているかを考察してみましたが、まだ`項番：1`がどこの接続が理解できていません。(誰か教えてください:sob:)
    - 現時点で分かる範囲で言うと、以下のような接続になっているのかなと考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/f84a91de-1bb2-86bf-fd6a-8c46602afa9d.png)

- 解決後のアクセス
    - kubectlでsvcが見えました。

```shell:
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   6d2h
```


### Nodeの確認
- つづけてNodeの確認をしようとすると、次はNodeが見えません。

```shell:
$ kubectl get nodes
No resources found.
```

- 実はここに行き着くまでパブリックサブネットにワーカーノードを建てていた時期があり、そのときはこの時点で問題なくNodeが見えていました。
    - プライベートサブネットにNodeを配置したことによってなにか変わった？でも解決方法はサブネットとは関係のないIAM関連の設定でした。
- 解決方法
    - AWS authenticator configuration mapファイルをダウンロードし、そのファイル内に`NodeInstanceRole`を入れ込みます。

```shell:
$ curl -O https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/aws-auth-cm.yaml
```

```yaml:
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: ★NodeInstanceRole★
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
```

`kubectl`でConfigMapを適用します。

```shell:
$ kubectl apply -f aws-auth-cm.yaml
configmap "aws-auth" created
```

- 参考：[AWS EKSをGitLabデプロイ環境として使う - Qiita](https://qiita.com/jb-vasseur/items/ae325957aeb36c00cc52#%E3%83%8E%E3%83%BC%E3%83%89%E3%82%92%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%95%E3%81%9B%E3%82%8B)
    - `NodeInstanceRole`の取得方法は上記参考URLに記載されています

- 解決後のアクセス
    - kubectlでnodeが見えました。

```shell:
$ kubectl get node
NAME                                             STATUS   ROLES    AGE    VERSION
ip-10-0-21-171.ap-northeast-1.compute.internal   Ready    <none>   6d1h   v1.16.13-eks-ec92d4
ip-10-0-22-50.ap-northeast-1.compute.internal    Ready    <none>   6d1h   v1.16.13-eks-ec92d4
```


## まとめ
- ということでようやくEKSクラスターが作成できました。ここからEKSクラスター上にMattermostを展開していくのですが、いきなり展開ではなく、`前準備`をしていこうと思います。

## 関連記事
- [EKSでMattermostを構築した話：0.概要編 - Qiita](https://qiita.com/tnagano1981/items/555301cecd3ed309fa43)
- [EKSでMattermostを構築した話：1. VPC作成編 - Qiita](https://qiita.com/tnagano1981/items/75408d509c0660408c97)
- [EKSでMattermostを構築した話：3-1. EKSクラスターでアプリケーションを稼働させる前にセットアップしておくべきツール編 - Qiita](https://qiita.com/tnagano1981/items/c91d27fa2e286a96b6ff)