EKSノードをセルフマネージド→マネージドへ移行する
今回は、とある理由からEKSノードタイプを「セルフマネージド」から「マネージド」へと移行したエピソードを紹介したいと思います。
自己紹介
パイオニア株式会社 SaaS Technology Center(STC) の阿久津です。
趣味は登山で、来年からは雪山でもテント泊したいな〜と考えたりしてます。
入社から約5年ハード設計部門で電気設計を担当し、1年ほど前、社内公募にてソフト部門に異動後、現在インフラエンジニアとして活動しています。
背景
パイオニアの一部のAWSワークロードではAmazon Elastic Kubernetes Service(以下、EKS)を採用しています。
EKSにおいては、ノード(コンテナアプリケーションを実行するマシン)が配置され、さらにノードの中にコンテナアプリケーション(以下、アプリ)がPodという単位で動的に配置され、動作します。"動的に"とは、CPUリソースに空きがあるノードをEKSがみつけて自動で配置するようなイメージです。
またCluster Auto Scalerというツールの実装により、PodによるCPUリソース要求に応じてノードの数が自動的に調整(スケール)される仕組みになっています。
そしてApplication Load Balancer(以下、ALB)を介し、さまざまなアプリへの通信を実現しています。
これらのAWSリソースはTerraformを用いてIaC(Infrastructure as Code)管理が行われています。
主なリソースの構成図は以下の通りです。(構成についての詳細情報は過去記事を参照)
EKSを基盤としたサービスを運用していく中で、少ない頻度で通信のタイムアウトが発生する、という事象が確認されました。
AWS外→ALBまではAPIリクエストが到達するものの、その先のEKSには届かないというケースでした。
調べてみると、ノードの数が調整され減少する(スケールイン)タイミングで発生する事象であることが判明しました。
結果としてわかったことは、
本来、Podは自身が配置されているノードの終了時には、別の(終了していない)ノードに退避されるべきだが、
ノードの終了とともにPodも一度終了し、終了後に別のノードで新しく起動していたということです。
(※Podは終了および再作成されるとそのIPアドレスも書き換えられる)
このため、終了処理中のノードに配置されているPodへのリクエストは、ALBに到達した時点で予定していた転送先を失い、タイムアウトとなっていたわけです。
対策の検討
EKSノードには、ノードタイプ(セルフマネージド/マネージド/AWS Fargate)という属性があります。
これまではノードタイプに「セルフマネージド」を採用していましたが、この場合、当サービスにおいてNode Termination Handlerというツールを導入する必要があることが判明しました。
セルフマネージドを採用していた背景は、パイオニアではEKSをサービスの黎明期から利用しており、当初の環境をそのまま踏襲し引き継いでいたためです。
まとめると、対策案としては以下の2通りの選択肢があります。
EKSノードのタイプをセルフマネージドから変更せず、Node Termination Handlerを導入する
EKSノードのタイプをマネージドに変更する
比較すると、案1は、 Kubernetesの細かい設定を駆使しないとできないことを実現したい場合に選択、そうでなければ案2でOKな印象。
特に従来やっていたことができなくなるなどの弊害はなかったため案2の方針を選択しました。
マネージドノードの構築作業
冒頭でも触れた通り、EKSを含むAWSリソースはTerraform(以下、tf)を用いて構築・管理しています。そのためセルフマネージドノードのリソースを定義するtfコードを流用することで、少ない作業量でマネージドノードの構築ができました。
やってみてわかったこと
EKSノードのタイプのどちらを選択するにしても、実態としてはEC2 Auto Scaling Group(以下、ASG)を構築し、その中でノードを動作させることになります。
セルフマネージドノードを構築することとは..
自分でASGを構築すること --- ①
マネージドノードを構築することとは..
自分でEKSノードグループを構築すること
EKSノードグループにより自動的にASGが作られる --- ②
わかったこととして2点あります。
②のASGの設定にはライフサイクルフックが標準設定されている
②のASGの設定はtfで(直接は)定義できない
1点目について、
②の方のASGでは下図のライフサイクルフックが標準設定されており、ノード起動/終了時にPodへの配慮(ノード終了時には別の起動中のノードに退避される)がされるようになっています。
①の方のASGにはこのような設定は標準ではされていません。
2点目について、
EKSノードグループが作成するASGについては、その設定でtfによる明示的な定義ができないため以下のようなASG特有の設定ができません。そのため今回は暫定対応として、tfでの作成後にAWSコンソールにて手動で設定しました。
ASGメトリクスの有効化
ロードバランサーターゲットグループの指定
今後の課題
前述のASGの設定についてヒントとなる情報があったので、実践してみようと考えています。
メトリクスの有効化
ロードバランサーターゲットグループ
最後に
以上、EKSの運用についてのエピソードを紹介しました。
SRE/インフラチームではサービスインフラの構築・改善およびSRE活動に日々取り組んでいます。
興味をお持ちいただけましたら、採用ページをぜひご覧ください。