「しくみがわかるKubernetes」をEKSで学ぶ

「しくみがわかるKubernetes」をAzureではなくAWSで動かしながら学ぶための環境構築メモ。

https://www.seshop.com/product/detail/22624

# 前提条件
- macOS 11.4 (Apple Silicon) 
- AWS CLIの実行環境が準備できていること
- docker環境が準備できていること

以降は、書籍の章立てに合わせて、AzureとAWSで差分が出る部分について記載していく。

# 2.2 開発環境の準備
## Azure CLIコマンドのインストール
Azure CLIコマンドをインストールする代わりに、eksctlコマンドをインストールする。

```
% brew tap weaveworks/tap
% brew install weaveworks/tap/eksctl
% eksctl version
0.60.0
```

# 2.3 コンテナイメージのビルドと公開
## ACRを使ったコンテナーイメージビルドと共有
ACRの代わりに、ECRを使ってコンテナイメージの作成とレジストリへの登録を行う。

### ECRレジストリの作成

```
% aws ecr create-repository --repository-name photo-view --image-scanning-configuration scanOnPush=true --region ap-southeast-2
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:ap-southeast-2:xxxxxxxxxxxx:repository/photo-view",
        "registryId": "xxxxxxxxxxxx",
        "repositoryName": "photo-view",
        "repositoryUri": "xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/yyyyyyyy",
        "createdAt": "2021-08-12T09:33:46+09:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": true
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}
```

### ECRレジストリへのログイン
```
aws ecr get-login-password --region ap-southeast-2 | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com
```

### Dockerイメージのビルド
ACRでビルドする代わりに、ローカルでビルドしたものをECRにPUSHする。
まずはローカルでビルド。

```
% git clone https://github.com/ToruMakabe/Understanding-K8s
% cd Understanding-K8s/chap02/v1.0
% docker build -t photo-view:v1.0 .
```

次にローカルで動作確認。ブラウザで http://localhost にアクセスして写真が表示されればOK。

```
% docker run --rm -p 80:80 photo-view:v1.0
```


### DockerイメージのECRへのPUSH
ECRにPUSHするためのtagを追加

```
docker tag photo-view:v1.0 xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/photo-view:v1.0
```

ECRにpush

```
docker push xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/photo-view:v1.0 
```

ECRに登録されたことを確認

```
aws ecr list-images --repository-name photo-view --region ap-southeast-2
```

### Apple Silicon環境の場合
ローカルがApple Silicon環境の場合は、docker buildでビルドされるのはaarm64向け。これから作成するAWS上のEKSのノードはamd64環境のため、このイメージは実行できない。そのため、マルチプラットフォーム版のDockerイメージを作ってECRに登録しておく必要がある。

まずはDocker Desktop for macOS (Apple Silicon)で、マルチプラットフォームビルドができるように設定する。

https://dev.classmethod.jp/articles/docker-multi-architecture-image-build/

```
% docker buildx ls
NAME/NODE       DRIVER/ENDPOINT STATUS  PLATFORMS
desktop-linux   docker                  
  desktop-linux desktop-linux   running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default *       docker                  
  default       default         running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
% docker buildx create --name mybuilder
mybuilder
% docker buildx ls                     
NAME/NODE       DRIVER/ENDPOINT             STATUS   PLATFORMS
mybuilder       docker-container                     
  mybuilder0    unix:///var/run/docker.sock inactive 
desktop-linux   docker                               
  desktop-linux desktop-linux               running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default *       docker                               
  default       default                     running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
% docker buildx use mybuilder
% docker buildx ls
NAME/NODE       DRIVER/ENDPOINT             STATUS   PLATFORMS
mybuilder *     docker-container                     
  mybuilder0    unix:///var/run/docker.sock inactive 
desktop-linux   docker                               
  desktop-linux desktop-linux               running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default         docker                               
  default       default                     running  linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
% docker buildx inspect --bootstrap
% docker buildx ls
NAME/NODE       DRIVER/ENDPOINT             STATUS  PLATFORMS
mybuilder *     docker-container                    
  mybuilder0    unix:///var/run/docker.sock running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
desktop-linux   docker                              
  desktop-linux desktop-linux               running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
default         docker                              
  default       default                     running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
% docker image ls
REPOSITORY                                                              TAG               IMAGE ID       CREATED        SIZE
moby/buildkit                                                           buildx-stable-1   febfa34ea4a7   3 weeks ago    134MB
% docker buildx build --platform linux/amd64,linux/arm64 -t xxxxxxxxxxxx.dkr.ecr.ap-southeast-2.amazonaws.com/photo-view-mp:v1.0 --push .
```

# 2.4 Azureを使ったKubernetesクラスター作成
AKSを使う代わりにEKSでKubernetesクラスターを作成する。

## AKSを使ったクラスター構築
eksctlを使ってEKS上にクラスタを構築する。

### クラスターとノードグループの作成
ノードとして動作するEC2インスタンスに接続するためのSSHキーペアを作っておく。

```
% aws ec2 create-key-pair --key-name eks_key --query 'KeyMaterial' --output text --region ap-southeast-2 > eks_key.pem
``` 

eksctlコマンドでクラスタとノードグループを同時に生成する。
コマンドを実行するとCloudFormationのスタックが登録され、クラスタに必要なリソースが生成される。
生成完了までは20分程度かかるので待つ。

```
% eksctl create cluster --name TestEKSCluster --region ap-southeast-2 --with-oidc --ssh-access --ssh-public-key eks_key --managed --nodes 1 --nodes-min 0 --nodes-max 3 --node-type t3.small
```

生成されていることを確認する。

```
% eksctl get cluster --region ap-southeast-2
2021-08-13 12:26:37 [ℹ]  eksctl version 0.60.0
2021-08-13 12:26:37 [ℹ]  using region ap-southeast-2
NAME		REGION		EKSCTL CREATED
TestEKSCluster	ap-southeast-2	True
```

```
% eksctl get nodegroup --region ap-southeast-2 --cluster TestEKSCluster
2021-08-13 12:30:05 [ℹ]  eksctl version 0.60.0
2021-08-13 12:30:05 [ℹ]  using region ap-southeast-2
CLUSTER		NODEGROUP	STATUS	CREATED			MIN SIZE	MAX SIZE	DESIRED CAPACITY	INSTANCE TYPE	IMAGE ID	ASG NAME
TestEKSCluster	ng-545be9b5	ACTIVE	2021-08-13T03:18:41Z	0		3		1			t3.small	AL2_x86_64	eks-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

eksctlが.kube/configの編集も自動で行ってくれるため、kubectlでのアクセスもこの時点で可能になる。
kubectlでkubernetesのレベルでもノードが認識されていることを確認する。

```
% kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-46-103.ap-southeast-2.compute.internal   Ready    <none>   10m   v1.20.4-eks-6b7464
```

ノードグループの実体はEC2のオートスケーリンググループなので、AWSコンソールや、AWS CLIでオートスケーリンググループの情報も確認してみる。

```
% aws autoscaling describe-auto-scaling-groups --region ap-southeast-2
```

ノードとして動作しているEC2インスタンスにSSHで接続してみる。ノードのアドレスはAWSコンソールで確認。

```
% ssh -i eks_key.pem ec2-user@<IPアドレス>
```

ノード数をスケールアウトしてみる。

```
% eksctl scale nodegroup --region ap-southeast-2 --cluster TestEKSCluster --name ng-545be9b5 --nodes 2
```

```
% kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-46-103.ap-southeast-2.compute.internal   Ready    <none>   40m   v1.20.4-eks-6b7464
ip-192-168-90-158.ap-southeast-2.compute.internal   Ready    <none>   42s   v1.20.4-eks-6b7464
```

ノード数をスケールインしてみる。

```
% eksctl scale nodegroup --region ap-southeast-2 --cluster TestEKSCluster --name ng-545be9b5 --nodes 0
```

```
% kubectl get node                    
No resources found
```

### a1インスタンス
a1インスタンスのノードグループも作ってみた。
addonをアップデートするように警告メッセージが出るが、--skip-outdated-addons-check=trueをつけてスキップ。
警告メッセージ通りにアップデートするとノードグループをクラスタにJOINさせるところで失敗した。

```
eksctl create nodegroup --region ap-southeast-2 --cluster TestEKSCluster --name a1NodeGroup --ssh-access --ssh-public-key eks_key --nodes 1 --nodes-min 0 --nodes-max 3 --node-type a1.medium --node-zones ap-southeast-2c --managed --skip-outdated-addons-check=true
```