こんにちは!スタディサプリ小中高SREの@_a0iです。 この記事はスタディサプリProduct Team Advent Calendar 2024一日目の記事です!
私たちはここ数年KubernetesのNode管理を楽に・効率的に行おうとKarpenterの導入に励んできました。
Karpenter導入時のトラブルに関するブログを書いてから1年、
私たちは「Amazon EKS on AWS Fargate(以降EKS on Fargate)」の導入を試みることでさらにNode管理を楽にすることをめざしました。 ようやく本番環境で安定稼働してきましたが、これまでに色々と試行錯誤したのでその知見を共有したいと思います。
なぜEKS on Fargate?
Karpenterは自動でNodeを管理してくれる非常に便利なツールです。私たちはNode管理の大部分をKarpenterに任せています。
しかし、一部のNodeはKarpenter管理ではなくAWSのManaged Node Groupという仕組みを使っています。
なぜなら、新規クラスタを作成する際「Karpenterを起動するためのNode」が必要になるからです。
Managed Node Group自体非常に便利で、Karpenterを導入する前は全てManaged Node Groupに任せていました。
しかし今や状況が変わり、Karpenterの起動のためだけにManaged Node Groupをメンテナンスし続けることが徐々に手間になってきました。
そこでAWSから新たに機能追加となった「EKS on Fargate」が私たちの用途に合うのではということでKarpenterをEKS on Fargateに載せ替えることになりました。
また、より安定的なNodeとしてManaged Node Groupに載せていたCoreDNSもあわせてEKS on Fargateに載せ替える計画でした。
EKS on Fargateとは?
試行錯誤したハマりポイントを説明する前に、まずはEKS on Fargateについて簡単に紹介します。
AWS公式ページにはAWS Fargateについて以下のように書かれています。
AWS Fargate は、サーバーレスで従量制料金のコンピューティングエンジンであり、サーバーを管理することなくアプリケーションの構築に集中することができます。サーバー管理、リソース割り当て、スケーリングなどのタスクを AWS に移行すると、運用態勢が改善されるだけでなく、アイデアからクラウドでの本番環境までの移行プロセスが加速され、総保有コストが削減されます。 AWS FargateはもともとECSで利用可能だったものが、2019年にEKSでも利用可能になりました。
EKS on Fargateとは簡単にいうとKubernetesのWorker Nodeをサーバーレスにすることができるというものです。
Fargateにはいくつかの考慮事項があるためどんな状況でもおすすめというわけではないですが、私たちの要件に合致したためEKS on Fargateへの移行を進めることにしました。
いくつかの落とし穴
ではいくつかハマったポイントを説明します。
CloudWatchでログが見れるようになるにはFluent Bitの設定が必要
ドキュメントにきちんと書かれているので、これは「ドキュメントに書かれていることができていなかった」というハマりポイントになります。
具体的には以下でハマりました
逆にいうと「aws-observability Namespaceにaws-loggingという名前のConfigMapを作り、そこにFluent Bitの設定を書けばCloudWatchでログが見れるようになる」と便利ではあります。Fluent BitのAgentのインストールなどは必要ありません。
リソースの使われ方が変わる
これもドキュメントに書かれています
Amazon EKS Fargate はノードごとに 1 つの Pod しか実行しないため、リソースが少ない場合に Pods を削除するシナリオは発生しません。すべての Amazon EKS Fargate Pods は保証された優先度で実行されるため、リクエストされた CPU とメモリは、すべてのコンテナの制限に等しくなければなりません。詳細については、Kubernetes ドキュメントの「Pods にサービスの品質を設定する」を参照してください。 Fargate Pod 設定の詳細を理解する - Amazon EKS
KubernetesではCPUやメモリのrequests/limitsをそれぞれ別の値に指定したり、そもそもlimitを指定しないことができます。
私たちの環境ではこれまでCPU limitsを指定していませんでしたが、結果としてFargateでは予期していない値になってしまっていました。
ちなみにFargateでは以下のようにAnnotationを参照することでどのようなリソースが割り当てられるか決まります。
apiVersion: v1 kind: Pod metadata: annotations: CapacityProvisioned: 4vCPU 8GB
Fargate Profileの変更で動かなくなる
これもドキュメントに記載されてはいたのですが、エラーメッセージなどからすぐこれが原因だと特定できたわけではないのでハマりました。
Fargate プロファイルは変更できません。ただし、新しい更新されたプロファイルを作成して既存のプロファイルを置き換え、その後元のプロファイルを削除することはできます。 docs.aws.amazon.com
私たちはFargate Profileに紐づくIAM Roleの名前変更を行ったところ、Fargate Profileが動かなくなってしまいハマりました。
Fargate Profileに関連する変更は関連するリソースを新規作成して切り替えるのがよさそうです。
CoreDNSでは使えなかった
CoreDNSをFargateに載せようとしていたのですが、最終的にFargateに載せない決定を行いました。
CoreDNSはネットワークを担う重要なコンポーネントですが、あるとき私たちの環境で「セキュリティグループの接続の追跡の上限」に達してしまいました。
セキュリティグループの接続の追跡の上限については詳しくは以下の公式ドキュメントを参照してください。これはEC2インスタンス含めて発生する制約で、接続の追跡の上限に達すると、パケットドロップが発生してしまいます。
上限はインスタンス数によって値が異なり、例えばCoreDNSのPodを複数のインスタンスに分散させることで1インスタンスあたりの接続数を減らすという対策を取ることができます。
接続の追跡の上限に達したかどうか、あるいは上限に達するまでにどれくらい余裕があるかはconntrack_allowance_availableやconntrack_allowance_exceededといったメトリクスでモニタリング可能なのですが、Fargateではこのメトリクスを取得できないとのことでした。
パケットロスはサービスに大きな影響を与える上にメトリクスが取得できないのでは私たち側で原因を特定することも困難です。
この件はAWSのサポートの方に調査を依頼してようやく原因が判明するくらいハマりました。そして今後の運用に支障が出ると判断し、CoreDNSはFargate にのせるのをやめました。
DaemonSetが使えないので、Datadog Agentの利用方法を変える必要がある
これはDatadogを利用している方にだけあてはまる話ですが、ご紹介します。
私たちはDatadog AgentをDaemonSetとしてNodeにインストールしているのですが、EKS FargateではDaemonSetが使えないため設定を変更する必要がありました。
公式ドキュメントに方法が書いてあるので、基本的にドキュメントに書かれている通りにやれば問題ありません。
と言っても権限周りでハマりました...。
問題にはなっていないけれど少し気になっていること
今の私たちの使い方であれば問題になっていませんが、今後他の用途で使う場合には問題になるかもと思ったことをいくつかあげておきます。
- 起動が少し遅い
- EKS Fargateでは1Podに対して仮想的に1つのNodeを割り当てる都合上、コンテナよりも割と起動が遅いです
- EBSが使えない
- コスト
- 単価がEC2よりも高いので、常時起動するコンテナは費用がかなり増える可能性があります
- 1Podに仮想的に1Nodeを割り当てる都合上、自由にCPUやメモリを決められるわけではなく組み合わせが決まっています。そして決まったスペックに応じて利用料が決まるため、スペックよりも少なく使う場合はコストが多めにかかる可能性があります
おわりに
以上、いくつかのハマりポイントでした!
近々EKS Upgradeを行う予定なので、思う存分EKS Fargateの便利さを享受したいと思います
(うまくいかなかったらまたブログ書きます...)