Juju-62q's blog

参加記録やメモ書き、思考のまとめをしています

eksctlとソフトウェアライフサイクル

f:id:Juju_62q:20200711212543p:plain

TL;DR

  • eksctlを使うときはライフサイクルを意識しましょう

eksctlとは

eksctlはWeaveworksとAWSが共同で開発を進めているEKSを管理するための公式ツールである。

リポジトリ github.com

ドキュメント eksctl.io

ここでは詳しく解説しないが、とても便利でコマンド一発でなんとなくK8sクラスタが立ち上がる。 また、公式ツールであるがゆえにEKSのアップデートに対する追従も早く、EKSのほとんどの機能に対応している。 EKSを触ったことがある人なら一度は触ったことはあると思うし、聞いたことはあると思う。

eksctlは難しいという話(前置き)

eksctlでは config.yaml というファイルでEKSに必要な設定を管理することができる。 ざっとあげつらねるだけでこのくらいは同一ファイルと同一実行での管理対象とできる。

↑多分不足はあるが少なくとも管理可能である。 ここで問題になることとして、上記の管理対象は明らかにライフサイクルや適用したいタイミングが異なるということが挙げられる。 これのせいでeksctlの責任範囲にいろいろ思考を巡らせる必要があるし、これが原因でeksctlの利用を避ける人の話もよく耳にする。

さらにいえばeksctlはEKSの周辺リソースの管理を目的としたツールなのでまともにIaCするとTerraformやCloudFormationを併用することになるのでこの守備範囲の兼ね合いも難しさに拍車をかける要因だろう。

Infrastructure as Codeとソフトウェアライフサイクル

僕はInfrastructure as Codeがかなりソフトウェアライフサイクルと密接な関係にあると考えており、リソースの種類よりも更新ライフサイクルをかなり強く意識して実行単位を切り分けることが多い2。 その時に得たいメリットの性質がかなり異なるためである。 また、依存関係としてはライフサイクルの短いものが長いものに依存するようにしている。

個人的に強く意識しているライフサイクルは大きく分けると以下である。

  • 1回作ったらほぼ変更しないもの
  • 変更は行うが、それがnヶ月という類のもの
  • ほぼ毎日変わりうるもの

1回作ったらほぼ変更しないもの

VPCやSubnet、RDS、場合によりIAM(eksctlを実行する権限など)がこれに該当する。 これについてのIaCは手順書とかバックアップに近いものとして扱っている。 何かが発生した場合に手作業が伴うことを厭わないどころか、必要に応じてコンソールからの操作も容認していいものだと思っている。 なんなら、場合によってはコード化されていなくてもいいんじゃないかとさえ思っている。

変更は行うが、それがnヶ月という類のもの

EKSクラスタ、IAM(ノードとかが使うもの、OIDC Federationとか)、EKSのDataPlaneとしてのEC2、ALB(本体)、k8sのnamespaceあたりはこれに該当すると考えている。 ここについてはきちんとコードで管理するが、必要に応じて手作業が紛れ込んでも良いと思っている。 コンソールでいじってIaCがそれに追従していないと、複雑な気持ちになる。

ほぼ毎日変わりうるもの

アプリケーション、ALB(TargetGroup)、IAM(アプリケーションが使うもの)、serviceaccountあたりがここに該当する。 ここについては基本的に手作業が伴わないように管理してほしいと思っているし、IaCは実態を示してほしいと考えている。 IaCが追従していないと、辛くなる。

eksctlが難しいという話(本編)

さて、先ほど話たことを見ていただけるとわかるが、eksctlは明らかにこの3つのライフサイクルのものを同一ファイル、同一実行で扱うことができる。 これは個人的に非常に難しいと思う。

eksctlでEKSを管理している人は多くの場合

  • TerraformやCloudFormationあるいはその他AWSを管理するためのツール
  • eksctlのconfig.yaml
  • k8sのmanifestファイル群

を管理していると思う。 ここでeksctlの守備範囲が明らかによく分からないことになって管理の仕方がなんやよく分からんことになる。

個人的結論

個人的な結論から話すと

  • VPCなど -> Terraform -> 1回作ったらほぼ変更しないもの
  • クラスタ(ControlPlane, DataPlane)-> eksctl -> 変更は行うが、それがnヶ月という類のもの
  • manifestが使うIAM -> Terraform -> ほぼ毎日変わりうるもの
  • manifest -> ほぼ毎日変わりうるもの

として扱うのが良いかなと思っている。

Terraformが2回出現していて

形式としてはeksctlはTerraformに依存され、依存していることになるが、これについては十分解決可能なのと、VPCに関しては個人的には全力でIaCのソフトウェアエンジニアリングのプラクティスを取ろうとしているわけではないのでこれを許容することにしている。

config.yamlの守備範囲の話

eksctlのconfig.yamlはかなりいろいろなことができ、便利且つ難しい。 例えば再三言っているがIAM Role for Serviceaccountの場合ServiceaccountとServiceaccountが読むことができるIAM Roleをいい感じに作ってくれる。 k8sのmanifestのGitOpsを前提としている場合、manifestは全部applyしたくなるわけだが自動生成でよしなに対応漬けが作られているものとなるとそうは問屋が下さない(実際はそんなにIAM Roleの名称を変えないかもしれないけどそれでも怖いものは怖い)。

これを考えるとeksctlのアプリケーションライフサイクルの部分は全て剥がした方がコントロールが容易になるんじゃないか、あるいはeksctlを実行することに対する恐怖感をなくせるのではないかと思う。よって僕はeksctlにアプリケーションとともに変更を加えうるものは一切持たせない。

VPCをなぜTerraformで管理したいかというのは単純で、他のAWSリソースでも使うからである。

ここまでシンプルにしてしまうとeksctlのconfig.yamlクラスタを管理することに集中でき、それが含むライフサイクルも単一となる。割と管理しやすくて嬉しい。

全部TerraformやらCFnでやればいいじゃんという話

前提として、僕は全てTerraformとかに寄せてもいいんじゃないかと思っている。 eksctlの責任範囲を狭くした結果、メリットが薄くなっているからだ。その上でeksctlをなぜ使おうと思ったのかを記述する。

正直言ってEKS周辺に限って言えば上記のツールよりも、eksctlは便利である。 また、公式ツールなので対応も早い。さらに利用者が多く、開発も盛んなのでプラクティスがeksctlに集約されていくのではないかという期待も込めてeksctlでクラスタを管理する方がいいのではないかと現状は考えている。

少なくともTerraformだとOIDC Providerあたりの管理は非常に難しいのでTerraformのみでいく場合注意した方がいいと思っている。 また、Terraform, CFn一本で行くにしてもeksctlが出力するCFnは知見の塊なので見ておいて損はないと思う。

終わりに

EKSを触っているとかなり頻繁にライフサイクルを意識させられる場面がある。 eksctlもそうだし、ALBを制御するALB Ingress Controllerなんかもそうである。 これはAWSの設計思想とK8sの設計思想の差をツールで吸収しようとしてるからだと思うが、その辺りの管理方法はかなり人によって意見が分かれると思うし技術者的には面白い部分かなと思う。 ツールもAWSもこれからどんどん便利になっていくと思うので頑張ってキャッチアップして行ってもっと良い感じに管理できるようになれば良いな〜と思っています。


  1. eksctlからいじることができるがconfig.yamlでの管理対象かと言われると違うかもしれない。

  2. k8sマニフェストについてはやらない。