YasuBlog

中年インフラエンジニアの備忘録です。

eksctl コマンドで EKS Cluster を作成する

1. 構成

以下の構成で EKS Cluster を作成します。 f:id:dunkshoot:20211031131158p:plain

2. 手順

2.1. VPC 作成 

Terraform(1.0.8)を使用します。イチからコードを書くのは面倒なので今回は terraform registry の VPC Module(Simple VPC)を使用します。

https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest

必要なファイルは 2 個です。 まずは provider.tf を作成します。

provider "aws" {
  region  = "ap-northeast-1"
  profile = "default"
}


二つ目は上記 Module のドキュメントに記載の通り main.tf を作成します。 なお、今回は検証環境のため private subnet は作成しません。(NAT Gateway にお金がかかるため)

module "ekstest_vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "ekstest-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = false
  enable_vpn_gateway = false

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}


あとは terraform init -> plan -> apply するだけです。

%terraform init
%terraform plan
%terraform apply


以下を参考に、Node に設定する SSH キーペア(名前:ekstest)も作成しておきます。(手順は割愛)

Amazon EC2 のキーペアと Linux インスタンス - Amazon Elastic Compute Cloud

2.2. EKS Cluster 作成

まずは以下を参考にして eksctl をインストールします。

eksctl コマンドラインユーティリティ - Amazon EKS

mac だとこんな感じです。

%/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
%brew tap weaveworks/tap
%brew install weaveworks/tap/eksctl
%eksctl version
0.71.0


次に eks cluster の yaml を作成します。

ドキュメントとサンプルコードは以下です。

https://eksctl.io/usage/creating-and-managing-clusters/

https://github.com/weaveworks/eksctl/tree/main/examples

今回は以下の要件で yaml を作成しました。

  • 手順 2.1. で作成した VPC,キーペアを使用
  • Node は Self ではなく Managed
  • Node のインスタントタイプは t3.micro
  • EBS は 30GB(指定しない場合のデフォルトは 80GB)
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: ekstest
  region: ap-northeast-1
  version: "1.21"

vpc:
  id: "vpc-063b58ff16344acfd"
  subnets:
    public:
      ap-northeast-1a:
          id: "subnet-06324dcadf5706acb"
      ap-northeast-1c:
          id: "subnet-048cad38a6c49de67"
      ap-northeast-1d:
          id: "subnet-0bb85370bb4b4528d"

managedNodeGroups:
  - name: managed-ng
    instanceType: t3.micro
    desiredCapacity: 3
    volumeSize: 30
    availabilityZones: ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
    ssh:
      allow: true
      publicKeyName: ekstest


作成した yaml を eksctl コマンドのオプションに指定して Cluster を作成します。 裏で CloudFormation が動き、作成完了までに 20 分ぐらいかかりました。

%eksctl create cluster -f ekstest.yaml

2.3. EKS アドオンのインストール

Kubernetes クラスタを運用する上で必要な VPC CNI, CoreDNS, kube-proxy といったソフトウェアを EKS で管理するために KES アドオンをインストールします。 (デフォルト状態ではセルフマネージド型アドオンとして動いているため、EKS で管理できるように EKS マネージド型アドオンで上書きするようなイメージです)

以下ドキュメントを参考にインストールします。

クラスターの IAM OIDC プロバイダーを作成するには - Amazon EKS

Amazon VPC CNI アドオンの管理 - Amazon EKS

CoreDNS アドオンの管理 - Amazon EKS

kube-proxy アドオンの管理 - Amazon EKS

# IAM OIDC プロバイダ作成
$ aws eks describe-cluster --name ekstest --query "cluster.identity.oidc.issuer" --output text
https://oidc.eks.ap-northeast-1.amazonaws.com/id/125AA275AD766DD181E535C5CFA5CF9D
$ eksctl utils associate-iam-oidc-provider --cluster ekstest --approve
2022-02-13 16:55:57 []  eksctl version 0.82.0
2022-02-13 16:55:57 []  using region ap-northeast-1
2022-02-13 16:55:58 []  will create IAM Open ID Connect provider for cluster "ekstest" in "ap-northeast-1"
2022-02-13 16:55:59 []  created IAM Open ID Connect provider for cluster "ekstest" in "ap-northeast-1"
$ aws iam list-open-id-connect-providers | grep 125AA275AD766DD181E535C5CFA5CF9D
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/125AA275AD766DD181E535C5CFA5CF9D"
# VPC CNI 用 IAM ロール作成
$ eksctl create iamserviceaccount --name aws-node --namespace kube-system --cluster ekstest --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy --approve --override-existing-serviceaccounts
2022-02-13 16:57:00 []  eksctl version 0.82.0
2022-02-13 16:57:00 []  using region ap-northeast-1
2022-02-13 16:57:01 []  1 iamserviceaccount (kube-system/aws-node) was included (based on the include/exclude rules)
2022-02-13 16:57:01 [!]  metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set
2022-02-13 16:57:01 []  1 task: {
    2 sequential sub-tasks: {
        create IAM role for serviceaccount "kube-system/aws-node",
        create serviceaccount "kube-system/aws-node",
    } }2022-02-13 16:57:01 []  building iamserviceaccount stack "eksctl-ekstest-addon-iamserviceaccount-kube-system-aws-node"
2022-02-13 16:57:01 []  deploying stack "eksctl-ekstest-addon-iamserviceaccount-kube-system-aws-node"
2022-02-13 16:57:01 []  waiting for CloudFormation stack "eksctl-ekstest-addon-iamserviceaccount-kube-system-aws-node"
2022-02-13 16:57:20 []  waiting for CloudFormation stack "eksctl-ekstest-addon-iamserviceaccount-kube-system-aws-node"
2022-02-13 16:57:36 []  waiting for CloudFormation stack "eksctl-ekstest-addon-iamserviceaccount-kube-system-aws-node"
2022-02-13 16:57:37 []  serviceaccount "kube-system/aws-node" already exists
2022-02-13 16:57:37 []  updated serviceaccount "kube-system/aws-node"
# 作成した IAM ロール確認
$ eksctl get iamserviceaccount --cluster ekstest
2022-02-13 16:58:06 []  eksctl version 0.82.0
2022-02-13 16:58:06 []  using region ap-northeast-1
NAMESPACE   NAME        ROLE ARN
kube-system aws-node    arn:aws:iam::XXXXXXXXXXXX:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E
# VPC CNI アドオン追加
$ eksctl create addon --name vpc-cni --version latest --cluster ekstest --service-account-role-arn arn:aws:iam::XXXXXXXXXXXX:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E --force
2022-02-13 16:58:56 []  Kubernetes version "1.20" in use by cluster "ekstest"
2022-02-13 16:58:56 []  using provided ServiceAccountRoleARN "arn:aws:iam::XXXXXXXXXXXX:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E"
2022-02-13 16:58:57 []  creating addon
2022-02-13 16:58:57 []  successfully created addon
# CoreDNS アドオン追加
$ eksctl create addon --name coredns --cluster ekstest --force
2022-02-13 16:59:35 []  Kubernetes version "1.20" in use by cluster "ekstest"
2022-02-13 16:59:35 []  no recommended policies found, proceeding without any IAM
2022-02-13 16:59:35 []  creating addon
2022-02-13 16:59:35 []  successfully created addon
# kube-proxy アドオン追加
$ eksctl create addon --name kube-proxy --cluster ekstest --force
2022-02-13 17:00:22 []  Kubernetes version "1.20" in use by cluster "ekstest"
2022-02-13 17:00:22 []  no recommended policies found, proceeding without any IAM
2022-02-13 17:00:22 []  creating addon
2022-02-13 17:00:22 []  successfully created addon
# アドオン確認
$ eksctl get addon --cluster ekstest
2022-02-13 17:01:22 []  eksctl version 0.82.0
2022-02-13 17:01:22 []  using region ap-northeast-1
2022-02-13 17:01:23 []  Kubernetes version "1.20" in use by cluster "ekstest"
2022-02-13 17:01:23 []  getting all addons
2022-02-13 17:01:24 []  to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME        VERSION         STATUS  ISSUES  IAMROLE                                             UPDATE AVAILABLE
coredns     v1.8.3-eksbuild.1 ACTIVE  0
kube-proxy  v1.20.7-eksbuild.1    ACTIVE  0
vpc-cni     v1.10.1-eksbuild.1    ACTIVE  0  arn:aws:iam::XXXXXXXXXXXX:role/eksctl-ekstest-addon-iamserviceaccount-kube-Role1-A4OVEJ0N035E

2.4. 動作確認

まずは kubectl をインストールします。

kubectl のインストール - Amazon EKS

%curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/darwin/amd64/kubectl
%chmod +x ./kubectl
%mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
%kubectl version --short --client
Client Version: v1.21.2-13+d2965f0db10712


次に aws CLI で、Cluster 用 kubeconfig ファイルをローカルに作成します。この作業により Cluster にアクセスできるようになります。

Amazon EKS の kubeconfig を作成する - Amazon EKS

%aws eks update-kubeconfig --name ekstest


Cluster の情報を取得できる事を確認します。

%kubectl get node
NAME                                              STATUS   ROLES    AGE     VERSION
ip-10-0-101-250.ap-northeast-1.compute.internal   Ready    <none>   5m22s   v1.21.4-eks-033ce7e
ip-10-0-102-235.ap-northeast-1.compute.internal   Ready    <none>   5m16s   v1.21.4-eks-033ce7e
ip-10-0-103-105.ap-northeast-1.compute.internal   Ready    <none>   5m19s   v1.21.4-eks-033ce7e

%kubectl get ns
NAME              STATUS   AGE
default           Active   13m
kube-node-lease   Active   13m
kube-public       Active   13m
kube-system       Active   13m


適当な deployment を作成して Pod が起動できる事を確認します。

Amazon Linux 2 のコンテナを 1 時間起動する deployment のマニフェスト(test-deployment.yaml)を作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
      - name: amazonlinux
        image: public.ecr.aws/amazonlinux/amazonlinux:latest
        command:
          - "bin/bash"
          - "-c"
          - "sleep 3600"

マニフェストをデプロイします。

%kubectl apply -f test-deployment.yaml
deployment.apps/test-deployment created

Amazon Linux 2 のコンテナ が起動している事を確認します。

% get pod
NAME                               READY   STATUS    RESTARTS   AGE
test-deployment-568d74bfdb-8hmjt   1/1     Running   0          5m3s
test-deployment-568d74bfdb-8trxr   1/1     Running   0          3m55s
test-deployment-568d74bfdb-k8mcj   1/1     Running   0          4m28s

%kubectl exec -it test-deployment-568d74bfdb-8hmjt -- /bin/bash
bash-4.2# uname -r
5.4.149-73.259.amzn2.x86_64

2.5. EKS Cluster 削除

delete cluster を実行します。

%eksctl delete cluster -f ekstest.yaml

2.6. VPC 削除

terraform destroy を実行します。

%terraform destroy

3. 料金

今回の構成にかかる費用は以下です。(NW 通信料とか細かいものは除外)

リソース 料金(USD/時) 料金(USD/月(30 日)) メモ
EKS 1 Cluster 0.1 72 料金 - Amazon EKS | AWS
EC2 t3.micro x 3 0.0408 29.376 オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS
EBS gp3 30GB x 3 0.012 8.64 ハイパフォーマンスブロックストレージの料金 – Amazon EBS の料金 – Amazon Web Services
合計 - 0.1528 110.016

今回は Ondemand Instance 使いましたが Spot Instance を使えばもっと安くなります。

Amazon EKS が、マネージド型ノードグループでの EC2 スポットインスタンスのプロビジョニングと管理をサポート | Amazon Web Services ブログ

4. 所管

terraform module を使えばサクッと VPC を構築できますし、EKS Cluster の yaml もシンプルなので簡単に EKS 検証環境を構築できました。

なお、Cluster 作成の eksctl コマンドを Ctrl-C で kill しても CloudFormation Stack は削除されないため手動で Stack を削除するか eks delete cluster を実行する必要があるので注意が必要です。(CloudFormation と連携してるサービスあるあるかもですが)