EKS Managed Node GroupでSpot Instancesを使う
Amazon EKSのManaged Node Groupsがスポットインスタンスに対応しました。
これまでManaged Node Groupsではオンデマンドしか利用できず、スポットを利用するには自分でAuto Scaling Groups(mixed instance types)を管理する必要がありました。今回のアップデートで簡単にスポットが利用できるようになりました。
設計で気にする点
元記事から重要と思われる点を挙げてみます。
Allocation strategy
まず、スポットインスタンスはなるべく複数のAZやインスタンスタイプに分散して配置されます。ASGでmixed instance typesを利用する場合は lowest-price と capacity-optimized が選べますが、MNGでは capacity-optimized に固定されています。両者の違いは以下です。
具体例は以下の記事が分かりやすいです。
なるべく多くのAZとインスタンスタイプを指定しておくことで、スポット価格が高騰してインスタンスが上がらない確率が低くなります。
Cluster Autoscalerとの併用
Cluster Autoscalerを利用する場合、Cluster Autoscalerが必要台数を正しく計算できるように、MNGには同じCPU数と同じメモリ量のインスタンスタイプを指定する必要があります。これはASGでmixed instance typesを利用する時と同じですね。
Cluster Autoscalerのドキュメントにも記載されています。
ノード停止時の振る舞い
ASGでスポットを利用する場合はaws-node-termination-handlerを入れる必要がありましたが、MNGでは不要です。もともとMNGではEC2インスタンスの停止時にdrainが実行されますが、スポットの停止通知にも対応したことになります。
また、ASGのcapacity rebalance機能でなるべく多くのAZやインスタンスタイプをカバーするように動的に再配置されます。 これはスポットの場合のみ有効になるようです。 詳しくは以下の記事が参考になります。
(2023-01-27 追記) ASG の rebalance 機能はスポットに限らずオンデマンドインスタンスでも有効のようです。ASG のイベントに以下が出ている場合は rebalance が原因です。MNG を AZ 単位に分割すると改善が期待できます。
instances were launched to balance instances in zones ap-northeast-1a with other zones resulting in more than desired number of instances in the group.
Launch Templateとの併用
10月のアップデートでMNGでLaunch Templateが利用できるようになりました。Launch Templateでは1種類のインスタンスタイプしか指定できませんが、MNGでは複数のインスタンスタイプを指定できます。スポットを利用する場合は複数のインスタンスタイプを指定することが望ましいので、基本的にMNGで定義することになると思います。以下のドキュメントに記載があります。
Terraformの実装例
Terraform AWS provider v3.19.0からMNGのスポットに対応しています。
ENHANCEMENTS
- resource/aws_eks_node_group: Add capacity_type argument and support multiple instance_types (Support Spot Node Groups) (#16510)
https://github.com/hashicorp/terraform-provider-aws/releases/tag/v3.19.0
aws_eks_node_group
リソースに capacity_type
という属性が増えています。デフォルトは ON_DEMAND
になっているので、 SPOT
を指定します。
resource "aws_eks_node_group" "default" { cluster_name = aws_eks_cluster.example.name node_group_name = "default" node_role_arn = aws_iam_role.example.arn subnet_ids = local.private_subnet_ids capacity_type = "SPOT" instance_types = [ # 4 vCPU and 32 GiB "r5.xlarge", "r5a.xlarge", "r5n.xlarge", "r5d.xlarge", "r5ad.xlarge", "r5dn.xlarge", ] }
なお、EKSクラスタがすでにあってTerraform AWS providerをv3.19.0にバージョンアップすると capacity_type
の差分が出てしまう場合があります。私の環境ではEKS 1.15のクラスタで差分が出てしまいました。その場合はignore changesに指定すれば差分が無視されるようになります。
resource "aws_eks_node_group" "default" { lifecycle { ignore_changes = [ # 既存クラスタでcapacity_typeの差分が出る場合 capacity_type, ] } }
既存のクラスタで capacity_type
を SPOT
に切り替える場合は、MNGが再作成されてしまうので注意が必要です。MNGが削除されるタイミングでMNG内の全ノードが停止します。
その他
12月のEKSアップデートでは、Management Consoleにノードやワークロードの一覧が確認できる画面が追加されていました。また、Management Consoleからアドオンをデプロイできるようです。この辺はGKEを意識した機能追加な感じがします。EKSはまだまだ伸び代があって継続的に進化しているので面白いですね。