この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
みなさん、こんにちは!
AWS事業本部の青柳@福岡オフィスです。
今回は「Amazon EKS (Elastic Kubernetes Service)」の入門記事をお送りします。
EKSの入門記事と言うと、当ブログ(Developers.IO)でも何度か紹介されましたし、巷にはKubernetesの入門書や初心者向けWeb記事が多く出版・公開されています。
それらの入門記事・書籍では、EKS(あるいはGKEやMinikubeなど)を使ったKubernetes環境構築から、構築したKubernetes環境の上で「Pod」や「Service」等のリソースを起動するところまでを一通りやってみる、という流れが多いようです。
一方、今回の記事では「EKSによるKubernetes環境の構築」の部分にフォーカスを当てました。
EKS専用のコマンドラインツール「eksctl」の使い方や、EKS環境の構築によってどのようなAWSリソースが作成・設定されるのか、という点を説明していきたいと思います。
EKS環境構築手順の「過去」と「現在」
本題に入る前に、まずお伝えしたいことは・・・
EKS環境構築の手順は「過去」と「現在」で大きく変わった、ということです!
「過去」
Amazon EKSが正式リリースされたのは2018年6月のことで、当時はバージニア北部リージョンとオレゴンリージョンのみで利用できました。
リリース当初のEKS環境の構築手順は以下の通りでした。
- 1. EKSサービス用のIAMロールを作成する
- マネジメントコンソールまたはAWS CLIを使って作成する
- 2. EKS環境を配置するVPCネットワーク環境を作成する
- CloudFormationのサンプルテンプレートをダウンロードして手で修正を行い、実行する
- 3. EKSコントロールプレーンを作成する
- マネジメントコンソールまたはAWS CLIを使って作成する
- 4. 作成したEKSコントロールプレーンへkubectlコマンドで接続する
heptio-authenticator-aws
(*1)をダウンロードしてインストールする~/.kube/config
ファイルを手で編集して認証情報を書き込むkubectl
コマンドでEKSコントロールプレーンへ接続できることを確認する
- 5. EKSワーカーノードとなるEC2インスタンスをプロビジョニングする
- CloudFormationのサンプルテンプレートをダウンロードして手で修正を行い、実行する
- 6. 作成したEC2インスタンスを「EKSワーカーノード」としてEKSコントロールプレーンから認識させる
- Kubernetesコンフィグマップ(*2)の定義ファイルを手で編集する
kubectl apply
コマンドでコンフィグマップを適用する
- 7. EC2インスタンスがEKSワーカーノードとして組み込まれたことを確認する
kubectl get nodes
コマンドで確認する
(*1) IAM経由でKubernetesのログイン認証を行うためのヘルパープログラム。
heptio-authenticator-aws
→ aws-iam-authenticator
と名前が変わり、その後AWS CLIに機能が組み込まれたため不要となりました。
(*2) Kubernetes上で様々な設定情報を格納するためのリソースであり、定義ファイルはYAMLで記述します。
う~ん、箇条書きで流れを列挙するだけでも、かなり煩雑そうな手順ですね。
実際に行うとハマりポイントも多く、リリース当初からEKSを触っていた人は苦労したのではないかと思います。(苦労しました!)
「現在」
一方、現在のEKS環境の構築手順は、以下の通りです。
$ eksctl create cluster
「過去」の構築手順と比べるとあまりにも簡潔ですが、本当にコレでEKS環境が構築できてしまいます。
もちろん、上記の構築手順はパラメータを最大限に省略したものであり、実際に構築する際はいくつかオプションパラメータを指定するのが普通です。
ここからは「eksctl」コマンドを使ったEKS環境の構築手順について説明していきます。
「eksctl」コマンドの使い方 (基本編)
eksctl
コマンドは、以下のような文法となっています。
$ eksctl <機能> <対象>
機能と対象の組み合わせで、以下のコマンド群が用意されています。
(執筆時のeksctl
最新バージョン0.7.0
の場合)
eksctl
├── create
│ ├── cluster
│ ├── nodegroup
│ ├── iamserviceaccount
│ └── iamidentitymapping
├── get
│ ├── cluster
│ ├── nodegroup
│ ├── iamserviceaccount
│ └── iamidentitymapping
├── update
│ └── cluster
├── delete
│ ├── cluster
│ ├── nodegroup
│ ├── iamserviceaccount
│ └── iamidentitymapping
├── scale
│ └── nodegroup
├── drain
│ └── nodegroup
├── utils
│ ├── wait-nodes
│ ├── write-kubeconfig
│ ├── describe-stacks
│ ├── update-cluster-stack
│ ├── update-kube-proxy
│ ├── update-aws-node
│ ├── update-coredns
│ ├── update-cluster-logging
│ ├── associate-iam-oidc-provider
│ └── install-vpc-controllers
├── completion
│ ├── bash
│ └── zsh
├── version
└── help
いきなりこれだけの数を見せられると困りますよね?
大丈夫、今回はこれらの中から最も基本となるeksctl create cluster
コマンドについて説明します。
「eks create cluster」コマンドで作成されるもの
eksctl create cluster
コマンドは字句通り「EKSクラスターを作成する」コマンドです。
ここで言う「EKSクラスター」は、Kubernetesインフラ基盤を構成するコンポーネントの集まりを指します。(ここまで「EKS環境」と呼んできたものとほぼ同義です)
EKSクラスターは、大まかに以下の要素で構成されます。
- VPCネットワーク環境
- EKSコントロールプレーン
- EKSワーカーノード
「VPCネットワーク環境」は、EKSクラスターが動作するために必要なVPC/サブネット等のネットワーク環境を指します。
「EKSコントロールプレーン」は、Kubernetesの様々な管理を行うコンポーネントの集まりを指します。
なお、コントロールプレーンを構成するサーバーを意味する「マスターノード」という用語が登場する場合がありますが、EKSではコントロールプレーン機能はマネージドサービス化されているため、総称としての「コントロールプレーン」という呼び方をすることがほとんどです。
「EKSワーカーノード」は、Kubernetesでコンテナが動作するコンピューティングリソースとしてのEC2インスタンスを指します。
ワーカーノードの集まりの単位を「ノードグループ」と呼び、EKS上でワーカーノードを取り扱う際は「ノードグループ」という呼び方をする場合の方が多いかもしれません。
また、Kubernetesにおいて「コントロールプレーン」と対になる概念として「データプレーン」という用語があり、ワーカーノードやノードグループの全体を総称して呼ぶ場合があります。(EKSのドキュメント等にはあまり出てこないので、頭の片隅にでも留めておいてください)
「クラスター」がEKS環境全体を指しているのか、コントロールプレーンのみを指しているのかは、文脈から適宜解釈する必要があります。
eksctlコマンドとCloudFormationスタックの関係
eksctl create cluster
コマンドを実行すると、内部ではCloudFormationのスタックが自動的に生成され、CloudFormationスタックによって各種AWSリソースが作成されます。
自動生成されるCloudFormationスタックは2つあり、それぞれのスタックによって作成されるAWSリソースは以下の通りです。
eksctl-XXXXXXXX-cluster
→「1. VPCネットワーク環境」および「2. EKSコントロールプレーン」を構成するリソースを作成eksctl-XXXXXXXX-nodegroup-XXXXXXXX
→「3. EKSワーカーノード」を構成するリソースを作成
これらのCloudFormationスタックのテンプレートの内容を参照すると、eksctl create cluster
コマンドの実行によって、どのようなAWSリソースが作成されるのかが見えてきます。
(興味がある方は、マネジメントコンソールでCloudFormationスタックの「テンプレート」タブを参照したり、aws cloudformation describe-stacks
コマンドで確認したりしてみてください)
各カテゴリそれぞれで「どのようなAWSリソースが作成されるのか」、また「各カテゴリで指定可能なeksctl create cluster
コマンドオプションにはどのようなものがあるのか」について、順に解説していきます。
1. VPCネットワーク環境
VPCネットワーク環境の構成要素として作成されるAWSリソースは以下の通りです。
- VPC
- サブネット (パブリック×3、プライベート×3)
- インターネットゲートウェイ
- NATゲートウェイ
これらは、EKSワーカーノード(EC2インスタンス)の配置先となるVPC/サブネットとなります。
VPCネットワーク環境に関するeksctl create cluster
コマンドのオプションは以下の通りです。
オプション | 説明 |
---|---|
--vpc-cidr |
VPCに指定するCIDR (省略時のデフォルト値: 192.168.0.0/16 ) |
--vpc-nat-mode |
NATゲートウェイの構成をHighlyAvailable , Single , Disable から選択(省略時のデフォルト値: Single ) |
サブネットのCIDRや、サブネット数・アベイラビリティゾーン数などを指定することはできません。
(これらを変更したい場合については、後ほど「『eksctl』コマンドの使い方 (応用編)」で説明します)
2. EKSコントロールプレーン
EKSコントロールプレーンの構成要素として作成されるAWSリソースは以下の通りです。
- コントロールプレーン (または、狭義の「クラスター」)
- コントロールプレーン用セキュリティグループ
- コントロールプレーン用IAMロール
コントロールプレーンはKubernetesの様々な管理を行うコンポーネントの集まりです。
(EKSではコントロールプレーン機能はマネージドサービス化されています)
また、コントロールプレーンに対するアクセスを制御するための「セキュリティグループ」と「IAMロール」も作成されます。
これらのリソースは、EKSドキュメントの該当ページに記載されている内容に沿って作成されますので、基本的に変更する必要はありません。
クラスターセキュリティグループの考慮事項 - Amazon EKS
Amazon EKS サービス IAM ロール - Amazon EKS
EKSコントロールプレーンに関するeksctl create cluster
コマンドのオプションは以下の通りです。
オプション | 説明 |
---|---|
--name |
クラスターの名前 (省略時のデフォルト値:ランダムな単語の組み合わせで命名) |
--version |
Kubernetesバージョン (現在指定可能なのは 1.14 , 1.13 , 1.12 , 1.11 )(省略時のデフォルト値: 1.13 ) |
3. EKSワーカーノード
EKSワーカーノードの構成要素として作成されるAWSリソースは以下の通りです。
- EC2起動テンプレート
- EC2 Auto Scalingグループ
- ワーカーノード用セキュリティグループ
- ワーカーノード用IAMロール
ワーカーノードの集まりの単位を「ノードグループ」と言います。
ノードグループの構成要素は「EC2起動テンプレート」と「EC2 Auto Scalingグループ」であり、これらにより必要台数のEC2インスタンスが起動されます。
そして、起動されたEC2インスタンス群はコントロールプレーンから自動的に認識されて、EKSのワーカーノードとして動作します。
また、コントロールプレーンと同様に、ワーカーノードに対するアクセスを制御するための「セキュリティグループ」と「IAMロール」も作成されます。
これらのリソースも、EKSドキュメントの該当ページに記載されている内容に沿って作成されますので、基本的に変更する必要はありません。
クラスターセキュリティグループの考慮事項 - Amazon EKS (前出のリンク先と同じです)
Amazon EKS ワーカーノード IAM ロール - Amazon EKS
EKSワーカーノードに関するeksctl create cluster
コマンドのオプションは以下の通りです。
オプション | 説明 |
---|---|
--nodegroup-name |
ノードグループの名前 (省略時のデフォルト値:ランダムな文字列) |
--node-type |
ワーカーノードのEC2インスタンスタイプ (省略時のデフォルト値:m5.large ) |
--nodes |
ワーカーノードのノード数 (省略時のデフォルト値:2 ) |
--nodes-min |
ワーカーノードのスケーリング最小サイズ (省略時のデフォルト値:2 ) |
--nodes-max |
ワーカーノードのスケーリング最大サイズ (省略時のデフォルト値:2 ) |
--node-volume-size |
ワーカーノードのボリュームサイズ (単位:GB) |
--node-volume-type |
ワーカーノードのボリュームタイプ (省略時のデフォルト値:gp2 ) |
--ssh-public-key |
ワーカーノードへの接続時のSSH公開鍵 (EC2キーペアなどを指定) |
--node-ami |
ワーカーノードの起動に用いるAMI (標準のAMI以外を使用したい場合は明示的に指定) |
--node-ami-family |
ワーカーノードの起動に用いるAMIの種別 (省略時のデフォルト値: AmazonLinux2 、他にGPU対応インスタンスやUbuntu等の指定が可能) |
実際にeksctlコマンドを使ってEKSクラスターを作成してみる
それでは、実際にeksctl
コマンドを使ってEKSクラスターを作成してみましょう。
まず準備として、eksctl
コマンドラインツールをインストールします。
インストール手順は下記リンク先を参照してください。
eksctl のインストールまたはアップグレード
Installation | eksctl
また、AWS CLIとkubectlコマンドもインストールされている必要があります。
念のために最新バージョンへアップデートしておきましょう。
準備ができましたら、eksctl create cluster
コマンドを実行します。
ここまでで説明した各種オプションをいくつか指定してみます。
$ eksctl create cluster \
--vpc-cidr 10.0.0.0/16 \
--vpc-nat-mode HighlyAvailable \
--name eks-sample \
--version 1.14 \
--nodegroup-name ng-sample \
--node-type t3.large \
--nodes 3 \
--nodes-min 2 \
--nodes-max 4
コマンドを実行すると、以下のようなメッセージが順次出力されます。
VPCネットワーク環境、EKSコントロールプレーン、EKSワーカーノードのパラメータが設定され、2つのCloudFormationスタックが生成されていることが読み取れると思います。
[ℹ] eksctl version 0.7.0
[ℹ] using region ap-northeast-1
[ℹ] setting availability zones to [ap-northeast-1c ap-northeast-1d ap-northeast-1a]
[ℹ] subnets for ap-northeast-1c - public:10.0.0.0/19 private:10.0.96.0/19
[ℹ] subnets for ap-northeast-1d - public:10.0.32.0/19 private:10.0.128.0/19
[ℹ] subnets for ap-northeast-1a - public:10.0.64.0/19 private:10.0.160.0/19
[ℹ] nodegroup "ng-sample" will use "ami-02e124a380df41614" [AmazonLinux2/1.14]
[ℹ] using Kubernetes version 1.14
[ℹ] creating EKS cluster "eks-sample" in "ap-northeast-1" region
[ℹ] will create 2 separate CloudFormation stacks for cluster itself and the initial nodegroup
[ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --name=eks-sample'
[ℹ] CloudWatch logging will not be enabled for cluster "eks-sample" in "ap-northeast-1"
[ℹ] you can enable it with 'eksctl utils update-cluster-logging --region=ap-northeast-1 --name=eks-sample'
[ℹ] 2 sequential tasks: { create cluster control plane "eks-sample", create nodegroup "ng-sample" }
[ℹ] building cluster stack "eksctl-eks-sample-cluster"
[ℹ] deploying stack "eksctl-eks-sample-cluster"
[ℹ] building nodegroup stack "eksctl-eks-sample-nodegroup-ng-sample"
[ℹ] deploying stack "eksctl-eks-sample-nodegroup-ng-sample"
[✔] all EKS cluster resources for "eks-sample" have been created
[✔] saved kubeconfig as "/home/ubuntu/.kube/config"
[ℹ] adding identity "arn:aws:iam::123456789012:role/eksctl-eks-sample-nodegroup-ng-sa-NodeInstanceRole-1902SEAFAQNV1" to auth ConfigMap
[ℹ] nodegroup "ng-sample" has 0 node(s)
[ℹ] waiting for at least 2 node(s) to become ready in "ng-sample"
[ℹ] nodegroup "ng-sample" has 3 node(s)
[ℹ] node "ip-10-0-17-77.ap-northeast-1.compute.internal" is ready
[ℹ] node "ip-10-0-63-243.ap-northeast-1.compute.internal" is not ready
[ℹ] node "ip-10-0-71-167.ap-northeast-1.compute.internal" is ready
[ℹ] kubectl command should work with "/home/ubuntu/.kube/config", try 'kubectl get nodes'
[✔] EKS cluster "eks-sample" in "ap-northeast-1" region is ready
EKSクラスターの構築が完了するまで、10~20分程度の時間がかかります。
コマンドの処理が完了して、正常終了のメッセージが表示されたことを確認します。
構築が完了しましたら、kubectl
コマンドでEKSクラスターへ接続します。
eks create cluster
コマンドは~/.kube/config
ファイルの編集も自動で行ってくれるため、接続のための設定を特に行う必要はありません。
したがって、以下のようにkubectl
コマンドを実行することで、EKSクラスターへ接続できることが確認できると思います。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-17-77.ap-northeast-1.compute.internal Ready <none> 75s v1.14.7-eks-1861c5
ip-10-0-63-243.ap-northeast-1.compute.internal Ready <none> 75s v1.14.7-eks-1861c5
ip-10-0-71-167.ap-northeast-1.compute.internal Ready <none> 75s v1.14.7-eks-1861c5
EKSクラスターへ接続できましたので、この後は、各種Kubernetes入門コンテンツを参考に「Pod」や「Service」等のリソースの起動を試してみるのもよいでしょう。
最後に、EKSクラスターを削除する手順です。
以下の通り、削除するEKSクラスターの名前を指定してeksctl delete cluster
コマンドを実行します。
$ eksctl delete cluster \
--name eks-sample \
--wait
削除コマンドを実行すると、内部ではCloudFormationスタックの削除が呼び出され、作成されたAWSリソースが順次削除されていきます。
--wait
オプションは必須ではないですが、付けるとCloudFormationスタックの削除完了を待ち合わせてからコマンドが終了します。
確実に削除が完了したことが分かるため、特に理由が無ければ付けるのをお勧めします。
(--wait
オプションを付けなかった場合は、コマンドが終了した後もバックグラウンドでCloudFormationスタックの削除処理が行われます)
以下は--wait
オプションを付けた時の出力メッセージ例です。
2つのCloudFormationスタックの削除が行われ、それぞれのスタックの削除完了を待ち合わせているのが分かります。
[ℹ] eksctl version 0.7.0
[ℹ] using region ap-northeast-1
[ℹ] deleting EKS cluster "eks-sample"
[✔] kubeconfig has been updated
[ℹ] cleaning up LoadBalancer services
[ℹ] 2 sequential tasks: { delete nodegroup "ng-sample", delete cluster control plane "eks-sample" }
[ℹ] will delete stack "eksctl-eks-sample-nodegroup-ng-sample"
[ℹ] waiting for stack "eksctl-eks-sample-nodegroup-ng-sample" to get deleted
[ℹ] will delete stack "eksctl-eks-sample-cluster"
[ℹ] waiting for stack "eksctl-eks-sample-cluster" to get deleted
[✔] all cluster resources were deleted
CloudFormationスタックの削除が完了してAWSリソースが完全に削除されたことが確認できれば、一連の作業は完了です。
「eksctl」コマンドの使い方 (応用編)
さて、一つのコマンドで「VPCネットワーク環境」「EKSコントロールプレーン」「EKSワーカーノード」を作成してくれるeksctl create cluster
コマンドですが、使い方により、それぞれを独立して別々に作成することもできます。
各カテゴリを別々に作成する理由はいろいろありますが、例えば以下のような場合です。
- サブネットのCIDRやサブネット数・アベイラビリティゾーン数をデフォルトから変更したい
- 複数のノードグループから成るEKSクラスターを構築する際、コントロールプレーンの管理とノードグループの管理を独立させたい
それぞれのパターンについて、構築手順を説明していきます。
パターン1の構築手順
STEP 1: VPCネットワーク環境の作成
まず、VPCネットワーク環境をCloudFormationやTerraform等を使って作成します。
例えば以下のようなCloudFormationテンプレートを用意します。
サンプルCloudFormationテンプレート (クリックして展開できます)
vpc-public-and-private-subnets.yaml
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "VPC network environment (each three public and private subnets with a NAT gateway)"
Parameters:
CidrBlockVPC:
Type: String
Default: 192.168.0.0/16
CidrBlockSubnetPublic1:
Type: String
Default: 192.168.0.0/19
CidrBlockSubnetPublic2:
Type: String
Default: 192.168.32.0/19
CidrBlockSubnetPublic3:
Type: String
Default: 192.168.64.0/19
CidrBlockSubnetPrivate1:
Type: String
Default: 192.168.96.0/19
CidrBlockSubnetPrivate2:
Type: String
Default: 192.168.128.0/19
CidrBlockSubnetPrivate3:
Type: String
Default: 192.168.160.0/19
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Network Configuration"
Parameters:
- CidrBlockVPC
- CidrBlockSubnetPublic1
- CidrBlockSubnetPublic2
- CidrBlockSubnetPublic3
- CidrBlockSubnetPrivate1
- CidrBlockSubnetPrivate2
- CidrBlockSubnetPrivate3
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref CidrBlockVPC
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/VPC"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/InternetGateway"
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
SubnetPublic1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPublic1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPublic1"
- Key: kubernetes.io/role/elb
Value: 1
SubnetPublic2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPublic2
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPublic2"
- Key: kubernetes.io/role/elb
Value: 1
SubnetPublic3:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 2
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPublic3
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPublic3"
- Key: kubernetes.io/role/elb
Value: 1
SubnetPrivate1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPrivate1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPrivate1"
- Key: kubernetes.io/role/internal-elb
Value: 1
SubnetPrivate2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPrivate2
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPrivate2"
- Key: kubernetes.io/role/internal-elb
Value: 1
SubnetPrivate3:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select
- 2
- Fn::GetAZs: !Ref AWS::Region
CidrBlock: !Ref CidrBlockSubnetPrivate3
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/SubnetPrivate3"
- Key: kubernetes.io/role/internal-elb
Value: 1
NATGatewayEIP1:
DependsOn:
- VPCGatewayAttachment
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NATGateway1:
DependsOn:
- NATGatewayEIP1
- SubnetPublic1
- VPCGatewayAttachment
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGatewayEIP1.AllocationId
SubnetId: !Ref SubnetPublic1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/NATGateway1"
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/PublicRouteTable"
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/PrivateRouteTable1"
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/PrivateRouteTable2"
PrivateRouteTable3:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}/PrivateRouteTable3"
PublicSubnetRoute:
DependsOn:
- VPCGatewayAttachment
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
NATPrivateSubnetRoute1:
DependsOn:
- VPCGatewayAttachment
- NATGateway1
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway1
NATPrivateSubnetRoute2:
DependsOn:
- VPCGatewayAttachment
- NATGateway1
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway1
NATPrivateSubnetRoute3:
DependsOn:
- VPCGatewayAttachment
- NATGateway1
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable3
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway1
RouteTableAssociationPublic1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPublic1
RouteTableId: !Ref PublicRouteTable
RouteTableAssociationPublic2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPublic2
RouteTableId: !Ref PublicRouteTable
RouteTableAssociationPublic3:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPublic3
RouteTableId: !Ref PublicRouteTable
RouteTableAssociationPrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPrivate1
RouteTableId: !Ref PrivateRouteTable1
RouteTableAssociationPrivate2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPrivate2
RouteTableId: !Ref PrivateRouteTable2
RouteTableAssociationPrivate3:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SubnetPrivate3
RouteTableId: !Ref PrivateRouteTable3
Outputs:
VPC:
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}::VPC"
SubnetsPublic:
Value: !Join [ ",", [ !Ref SubnetPublic1, !Ref SubnetPublic2, !Ref SubnetPublic3 ] ]
Export:
Name: !Sub "${AWS::StackName}::SubnetsPublic"
SubnetsPrivate:
Value: !Join [ ",", [ !Ref SubnetPrivate1, !Ref SubnetPrivate2, !Ref SubnetPrivate3 ] ]
Export:
Name: !Sub "${AWS::StackName}::SubnetsPrivate"
特別な記述内容はほとんどありませんが、1点だけ留意事項があります。
サブネットのリソースを記述する際、そのサブネットが「パブリック」なのか「プライベート」なのかをEKSコントロールプレーンに識別させるためにタグを付与する必要があります。
パブリックサブネットに付与するタグ:
Tags:
- Key: kubernetes.io/role/elb
Value: 1
プライベートサブネットに付与するタグ:
Tags:
- Key: kubernetes.io/role/internal-elb
Value: 1
※ これらのタグにより、Kubernetesの「LoadBalancer」リソースを作成する際に、ELBのスキームをinternet-faced
とinternel
のどちらにすべきかが判断されます。(この点についての詳細な説明は割愛します)
STEP 2: EKSコントロールプレーン+EKSワーカーノードの作成
VPCネットワーク環境が作成されましたら、eksctl create cluster
コマンドを以下のようなオプションを指定して実行します。
(説明のため、その他のオプションは省略しています)
$ eksctl create cluster \
--vpc-public-subnets <パブリックサブネットのリソースIDをカンマ区切りで指定> \
--vpc-private-subnets <プライベートサブネットのリソースIDをカンマ区切りで指定>
これにより、eksctl create cluster
コマンドはVPCネットワーク環境の新規作成をスキップし、指定したVPCネットワーク環境の上にEKSコントロールプレーンとEKSワーカーノードを作成します。
パターン2の構築手順
STEP 1: VPCネットワーク環境+EKSコントロールプレーンの作成
まず、eksctl create cluster
コマンドを以下のようなオプションを指定して実行します。
(説明のため、その他のオプションは省略しています)
$ eksctl create cluster \
--name <コントロールプレーンに付ける名前> \
--without-nodegroup
--without-nodegroup
オプションを指定することにより、eksctl create cluster
コマンドはEKSワーカーノードを作成せず、VPCネットワーク環境とEKSコントロールプレーンのみを作成します。
STEP 2: EKSワーカーノードの作成
VPCネットワーク環境とEKSコントロールプレーンが作成されたら、eksctl create nodegroup
コマンドを以下のように実行します。
$ eksctl create nodegroup \
--cluster <作成済みのコントロールプレーンの名前> \
--name <ノードグループに付ける名前> \
--node-type m5.large \
--nodes 2
これにより、作成済みのコントロールプレーンに対して、ノードグループを追加作成して組み込むことができます。
(説明のため、その他のオプションは省略しています)
なお、eksctl create nodegroup
コマンドのオプションは、eksctl create cluster
コマンドのEKSワーカーノード関連のオプションとほとんど同じです。
(詳細はeksctl create nodegroup --help
を実行して確認してください)
パターン3の構築手順
パターン3は、これまで説明した「パターン1」と「パターン2」の組み合わせで実現できます。
すなわち、以下の3ステップとなります。
- STEP 1: CloudFormationやTerraform等でVPCネットワーク環境を作成する
- STEP 2:
eksctl create cluster
コマンドに--without-nodegroup
オプションを付けて実行する - STEP 3:
eksctl create nodegroup
コマンドを実行する
おわりに
今回は、eksctl
コマンドを使用したEKSクラスター環境の構築手順について、オプションの使い方や作成されるAWSリソースの解説を交えて説明しました。
これで基本的なEKSクラスター環境は構築できるようになるのではないかと思います。
是非、いろいろなオプションを指定したり、構築パターンを変えたりして、EKSクラスター環境を作成してみてください。
また、最初の方で説明したようにeksctl
コマンドには今回紹介したもの以外にも様々な機能が含まれています。
それらについては、また別の機会にご紹介できればと思います。