この記事は Kubernetes Advent Calendar 2018 21日目の記事です。
TL;DR;
eksctlとは
Weaveworksが開発しているOSSで、AWS EKSクラスタおよびその実行環境(VPC, Subnet, Security Group, IAMロール等)とノードグループを作成、スケール、削除することができるgolang製のCLIツールです。
EKSクラスタやその他のリソースは内部的にはCloudFormationスタックによって作成・管理されています。クラスタ(=マスタとVPCなどのインフラ)に1スタック、そしてノードグループ用に1スタックが作られます。
ノードグループとは
英語だとNode groupまたはNodegroupと書きます。正式な定義は見つけられなかった、というか、ツールやサービスによって呼び名が異なる(例えばGKEやkube-awsではnode poolと呼んでいる)のですが、「同じnode labels, taints, マシンスペック(machine-type, instance type)を持つノードの集まり」を意味します。
AWSの場合、例えばバッチジョブ用にCPUリソースの潤沢なC4系インスタンスタイプから構成されるノードグループと、Webアプリケーション用にメモリの潤沢なM4系インスタンスタイプから構成するノードグループを分けて、Node LabelsやTaint/TolerationでPodを希望のノードグループに振り分けたりして使います。
eksctlのノードグループは1個で固定だった
実はeksctlのノードグループは1つで固定でした。これだと、例えばマルチテナントにして、Kubernetes上で稼働っせるサービス毎にマシンスペックを変える、セキュリティ上の都合であるサービス2つを同じノードに同居させないようにする、などの要件が件並み満たせなくなります。
技術的には、CloudFormationなどでノードグループをeksctlが作成したクラスタに追加するようなことは可能なはずですが、手順が煩雑になります。
これまでの経験上も、ノードグループが1個で済むケースはそんなになかったので、必要になる前に追加してみたいと思い、早速コントリビュートしてみました。
それが下記PRです。
複数Nodegroup対応のeksctlを試す
この記事を公開した時点ではまだマージされていないため、以下の手順で自分でeksctlをビルドする必要があります。
$ git clone git@github.com:mumoshu/eksctl.git ~/go/src/github.com/weaveworks/eksctl
$ cd $_
$ git checkout -b nodegroup-resource origin/nodegroup-resource
$ make build
ビルドが無事成功したら、プロジェクトルート直下に eksctl
という実行可能ファイルが生成されているので、それを実行してください。
クラスタの作成
まず、クラスタ及び最初のノードグループの作成の手順はいままでどおり、create cluster
コマンドで行うことができます。
$ ./eksctl create cluster --name testcluster
get cluster
でクラスタ一覧、 get nodegroup --cluster クラスタ名
でノードグループ一覧を見ることができます。
$ ./eksctl get cluster
NAME REGION
test-cluster us-west-2
$ ./eksctl get nodegroup --cluster testcluster
CLUSTER NODEGROUP CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID
testcluster ng-0 2018-12-21T00:26:40Z 2 2 2 m5.large ami-094fa4044a2a3cf52
ノードグループの作成
$ ./eksctl create nodegroup --cluster testcluster --node-labels foo=bar ng-1
これで初期ノードグループ ng-0
に追加で、 ng-1
という名前のノードグループが作成されます。
作成されたノードグループに所属するnodeは、普段どおり kubectl get no
で確認することができます。
get no
がエラーになる場合、kubeconfigの内容が何らかの理由で正しくないことが考えられるため、以下のようにして現在選択されているkubeconfig(KUBECONFIG環境変数の指す先)を更新してください。
$ ./eksctl utils write-kubeconfig --cluster testcluster
※今回作成したノードグループに所属するノードには foo=bar
というラベルが付与されるように、 --node-labels
フラグを使用しました。ノードグループのデフォルトサイズは 2 なので、以下のように kubectl get no
を実行すると、全4台のうち今回作成したノードグループに所属する2つのノードのみ、指定したラベル foo=bar
がついています。
$ kubectl get no --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ip-192-168-31-112.ap-northeast-1.compute.internal Ready <none> 8m v1.11.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.large,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-northeast-1,failure-domain.beta.kubernetes.io/zone=ap-northeast-1c,foo=bar,kubernetes.io/hostname=ip-192-168-31-112.ap-northeast-1.compute.internal
ip-192-168-5-50.ap-northeast-1.compute.internal Ready <none> 31s v1.11.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.large,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-northeast-1,failure-domain.beta.kubernetes.io/zone=ap-northeast-1c,kubernetes.io/hostname=ip-192-168-5-50.ap-northeast-1.compute.internal
ip-192-168-58-165.ap-northeast-1.compute.internal Ready <none> 8m v1.11.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.large,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-northeast-1,failure-domain.beta.kubernetes.io/zone=ap-northeast-1d,foo=bar,kubernetes.io/hostname=ip-192-168-58-165.ap-northeast-1.compute.internal
ip-192-168-74-189.ap-northeast-1.compute.internal Ready <none> 34s v1.11.5 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.large,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-northeast-1,failure-domain.beta.kubernetes.io/zone=ap-northeast-1a,kubernetes.io/hostname=ip-192-168-74-189.ap-northeast-1.compute.internal
get nodegroup
を実行すると、今回追加したものも含めて、すべてのノードグループの情報を得ることができます。
$ ./eksctl get nodegroup --cluster testcluster
CLUSTER NODEGROUP CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID
testcluster ng-0 2018-12-21T00:26:40Z 2 2 2 m5.large ami-094fa4044a2a3cf52
testcluster ng-1 2018-12-21T00:38:40Z 2 2 2 m5.large ami-094fa4044a2a3cf52
ノードグループのスケール
ノードグループのサイズ変更(ノード追加、削除)には scale
コマンドを利用します。
--cluster クラスタ名
のようにフラグでクラスタ名を指定し、--nodes
でノードサイズを指定します。
$ ./eksctl scale nodegroup --cluster testcluster --nodes 1 ng-1`
ノードグループの削除
スケールと同様、ノードグループの削除には scale nodegroup --cluster クラスタ名 ノードグループ名
のようにクラスタ名をフラグで、ノードグループ名を第一引数で指定します。
$ ./eksctl delete nodegroup --cluster testcluster ng-1
まとめ
eksctlを使うと、長大なterraform tfファイル、CloudFormationスタックテンプレートを記述しなくても本番運用に耐えうるEKSクラスタを構築することができます。
今回送ったPRで、マルチテナンシーには特に必須と思われるノードグループを複数持てるような機能が追加されます(首尾よくマージされれば)
ノードグループを複数持つという機能は、kops、kube-aws、GKEなど既存のKubernetesクラスタプロビジョニングツールや、AWS以外のマネージド・サービスでは以前よりサポートされている定番機能です。
eksctlに同様の機能を追加することで、EKSでもこれまでのようなマルチテナントに適したノード構成をとることができそうです。
ぜひ試してフィードバックをいただけるとうれしいです!