Amazon EKSが一般公開(GA)されたので使ってみた


EKSは、AWSによるKubernetesのマネージドサービスです。待っていた人も多いのではないでしょうか。

![eks.png](https://qiita-image-store.s3.amazonaws.com/0/54274/014ed839-c076-e38c-70ef-f8178b440c8b.png "eks.png")


基本的に公式の[Getting Started](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)に従って進めます。 ~~こんな記事より、公式を読んだ方が良いです。~~

## 事前準備

事前に以下の準備が必要です。

1. IAM roleの作成
  - KubernetesからELBなどのAWSのリソースを操作するため
  - 一度だけ作れば、複数のクラスターで利用可能
2. VPCの作成
  - クラスターごとにVPCを作成して、ネットワークを分離させます
3. **kubectl** と **Heptio Authenticator** のインストール
4. AWS CLIのインストール

### 準備1. IAM roleの作成

[IAM console](https://console.aws.amazon.com/iam/)にログインして、 **Roles** ページから **Create role** ボタンを押します。

サービス一覧から **EKS** を選んで、手続きを進めます。 **Role name** のところには **eksServiceRole** など適当な名前を入力して、Roleを作成します。

### 準備2. VPCの作成

[AWS CloudFormation console](https://console.aws.amazon.com/cloudformation)を開きます。

現在EKSをサポートしているリージョンは以下2つになります。

* US West (Oregon)(us-west-2)
* US East (N. Virginia)(us-east-1)

東京リージョンは残念ながらまだないので、ナビゲーションバーから **US West** を選んで、 **Create new stack** ボタンを押します。 **Specify an Amazon S3 template URL** を選んで、以下のURLを入力します。

```
https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-vpc-sample.yaml
```

次のページでは、 **Stack name** にVPCの名前を入力します。ここでは **（サービス名）-eks-vpc** にします。その他パラメータを調整する場合は調整をして、次へ。

次のページでは必要に応じてTagsを追加して、次へ。

Stackの作成が終わったら、作成したStackの **Outputs** タブを見て、 **SecurityGroups** , **VpcId**, **SubnetIds** ３つそれぞれの **Value** を控えておきます。

### 準備3. **kubectl** のインストールとEKSのための設定

[こちら](https://kubernetes.io/docs/tasks/tools/install-kubectl/)に従って **kubectl** をインストールします。

mac OSの人はBrewを使って `brew install kubectl` でインストールできます。以下のコマンドで正しくインストールされてるか確認しましょう。

```zsh
$ kubectl version --short --client
Client Version: v1.10.3
```

続いて、Kubernetesのクラスターに対してIAMによる認証を許可するために、 [Heptio Authenticator](https://github.com/heptio/authenticator) をインストールします。
Go言語がインストールされている環境であれば、``go get``によるインストールが可能です。（そうでない方は[Getting Started](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)に従ってください）

```zsh
$ go get -u -v github.com/heptio/authenticator/cmd/heptio-authenticator-aws
```

きちんとインストールされ、正しくパスが通っていれば、以下のコマンドが機能します。

```zsh
$ heptio-authenticator-aws help
```

### 準備4. AWS CLIのインストール

[公式](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)の手順に沿って最新版（執筆時点では `1.15.32`）のAWS CLIをインストールします。
または、mac OSであればBrewでのインストールも可能です。

```zsh
$ brew install awscli
```

例によってきちんとインストールされているか確認します。

```zsh
$ aws --version
aws-cli/1.15.30 Python/3.6.5 Darwin/17.5.0 botocore/1.10.30
```

（brewでインストールできるバージョンは少し遅れているようで最新版の`1.15.32`ではないですが、特に問題はありませんでした）

## EKSを使い始める

ようやく準備が終わったので、早速EKSを使い始めます。次のように進めていきます。

1. クラスターの作成
2. kubectlをAmazon EKS用に設定
3. ノードの作成と設定
4. サンプルアプリの作成
5. サンプルアプリの削除

### STEP1. クラスターの作成

まず、クラスターを作成します。ここで注意するべきは、クラスターを作成したIAM userが、KubernetesのRBAC(Role-based access control) 認証テーブルに管理者として追加されるということです。必ずルートユーザーではなく、IAM userとしてログインしてください。

Amazon EKS API operationsを実行可能なIAMユーザーで[こちら](https://console.aws.amazon.com/eks/home#/clusters)からクラスターを作成します。

事前準備で作成したIAM roleやVPCの情報を使って項目を入力し、 **Create** で作成します。作成が完了したら、 **API server endpoint** と **Certificate authority** の値を控えておきます。

### STEP2. kubectlをAmazon EKS用に設定

STEP 1で取得した情報を元に、 **kubeconfig** ファイルを作成します。

```
$ mkdir ~/.kube
```

ここでは、ホームディレクトリ以下に`.kube`というディレクトリを作成し、その中に、`config-<クラスター名>`という名前で以下のようなファイルを作成します。（内容は、STEP1で取得した情報で置き換えてください）

```yaml
apiVersion: v1
clusters:
- cluster:
    server: <endpoint-url>
    certificate-authority-data: <base64-encoded-ca-cert>
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: aws
  name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: heptio-authenticator-aws
      args:
        - "token"
        - "-i"
        - "<cluster-name>"
        # - "-r"
        # - "<role-arn>"
```

**kubectl**がconfigファイルを見つけられるように環境変数をセットします。

```
export KUBECONFIG=$KUBECONFIG:~/.kube/config-<クラスター名>
```

以下のコマンドを実行することで、きちんと設定が完了してることを確認できます。

```
$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   1m
```

### STEP3. ノードの作成と設定

さぁ、ワーカーノードを作成しましょう。ワーカーノードはEC2インスタンスとして起動するため、料金がかかることに注意してください。

[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)から **Create stack** を押して、 **Amazon S3 template URL** に以下のURLを入力して、次へ進みます。

```
https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/amazon-eks-nodegroup.yaml
```

**Stack name** は`<クラスター名>-worker-nodes`とかにしておきます。
**Cluster name** にはクラスター名（必ず一致している必要があります）をいれます。
**ClusterControlPlaneSecurityGroup** は事前準備で作成したセキュリティグループを入れます。
**NodeGroupName** にはAuto Scalingされるノードグループの名前を入れます。
**NodeImageId** には、リージョンごとに用意されたAmazon EKS worker node AMI IDを入力します。

|Region|Amazon EKS-optimized AMI ID|
|:--|:--|
|US West (Oregon) (us-west-2) | ami-73a6e20b
|US East (N. Virginia) (us-east-1) | ami-dea4d5a1

ここでは、US Westリージョン用の `ami-73a6e20b` を入力します。（東京リージョン早く・・・）

**KeyName** にはSSHでワーカーノードのインスタンスにアクセスするためのSSH keyの名前を入力します。

**VpcId** 、 **Subnets** はクラスター作成時に作成したものを利用します。

次のページではTagの設定をしたら（必要に応じて、Nameなど）、作成を完了します。

クラスターを作成した際と同様、 **Outputs** のタブを開き、 **NodeInstanceRole** の値を控えておきます。

続いて、作成したワーカーノードをクラスターに参加させます。

以下のコマンドから、設定用のファイルをダウンロードします。

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

このファイル中の`<ARN of instance role (not instance profile)>`の部分を先ほど控えた **NodeInstanceRole* の値で置き換え、以下のコマンドを実行します。

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

以下のコマンドでノードのステータスを確認してみましょう！

```
$ kubectl get nodes --watch
```

### STEP4. サンプルアプリの作成

STEP4では、サンプルアプリとして、 **Guestbook** というアプリを作ってみます。

1. Redis master用のレプリケーションコントローラの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-master-controller.json
  replicationcontroller "redis-master" created
  ```

2. Redis master用のサービスの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-master-service.json
  service "redis-master" created
  ```

3. Redis slave用のレプリケーションコントローラの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-slave-controller.json
  replicationcontroller "redis-slave" created
  ```

4. Redis slave用のサービスの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/redis-slave-service.json
  service "redis-slave" created
  ```

5. Guestbookアプリのレプリケーションコントローラの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/guestbook-controller.json
  replicationcontroller "guestbook" created
  ```
  
6. Guestbookアプリのサービスの作成

  ```
  $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/v1.10.3/examples/guestbook-go/guestbook-service.json
  service "guestbook" created
  ```
  
7. Guestbookサービスの **External IP** を取得

  ```
  $ kubectl get services -o wide
  ```

8. 取得した **External IP** の3000番ポートにブラウザでアクセスして、無事にアクセスできることを確認する

![](https://docs.aws.amazon.com/eks/latest/userguide/images/guestbook.png)

### STEP5. サンプルアプリの削除

以下のコマンドで、STEP 4で作成した全てのリソースの削除ができます。

```
$ kubectl delete rc/redis-master rc/redis-slave rc/guestbook svc/redis-master svc/redis-slave svc/guestbook
```

---

## 感想

かなり柔軟にユーザーがコントロール可能なマネージドサービスという印象で、第一印象はとても良い感じです。弊社ScovilleでのインフラとしてEKSを使っていく可能性も十分に感じさせられました。

OSSを積極的に利用しており、AWS自体への信頼感も上がりますね。

もう少しEKSで遊んでみようと思います。