AWS Cluster AutoscalerをTerraformとHelmfileでデプロイする
Cluster Autoscalerを利用すると,CPUやメモリの要求量に応じてノード数を自動的に増減させることが可能です.
本稿では,Amazon EKSで以下を利用する方法を紹介します.
Cluster AutoscalerのPodにIAMロールを割り当てるため,あらかじめkube2iamもしくはkiamをデプロイしておく必要があります.詳しくは下記を参照してください.
(2020/9/23 追記)Cluster AutoscalerのHelm chartはgithub.com/kubernetes/autoscalerに移動しました。また、権限の割り当てはIAM Roles for Service Accountsが推奨されています。
Worker Auto Scaling Groupの修正
Auto Scaling GroupにAuto Discovery用のタグを追加します.
terraform-aws-eks module を利用している場合は以下のように autoscaling_enabled = true
を追加すればよいです.詳しくはモジュールの Autoscaling を参照してください.
worker_groups_launch_template_mixed = [ { # 中略 autoscaling_enabled = true asg_min_size = 1 asg_max_size = 8 asg_desired_capacity = 4 }, ]
kopsを利用している場合は kops edit ig nodes
で以下のようにノード用のタグを追加します.
cloudLabels: k8s.io/cluster-autoscaler/enabled: 1 k8s.io/cluster-autoscaler/CLUSTER_NAME: 1
IAM Roleの作成
Cluster AutoscalerがAuto Scaling Groupを取得したり変更したりするためのIAM Roleを作成します.必要なIAMポリシーは cluster-autoscaler/cloudprovider/aws に記載されています.
# IAM role for Cluster Autoscaler resource "aws_iam_role" "cluster_autoscaler" { name = "${var.cluster_name}-cluster-autoscaler" assume_role_policy = data.aws_iam_policy_document.kube2iam_assume_role.json } resource "aws_iam_role_policy" "cluster_autoscaler" { role = aws_iam_role.cluster_autoscaler.name policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup" ], "Resource": "*" } ] } EOF } data "aws_iam_policy_document" "kube2iam_assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } principals { type = "AWS" identifiers = [module.eks.worker_iam_role_arn] } } }
Helm chartのデプロイ
stable/cluster-autoscaler chart をデプロイします.
releases: # https://github.com/helm/charts/tree/master/stable/cluster-autoscaler - name: cluster-autoscaler namespace: kube-system chart: stable/cluster-autoscaler values: - cloudProvider: aws awsRegion: ap-northeast-1 autoDiscovery: clusterName: {{ .Environment.Values.clusterName }} rbac: create: true podAnnotations: # IAM role for Cluster Autoscaler iam.amazonaws.com/role: {{ .Environment.Values.clusterName }}-cluster-autoscaler # https://github.com/helm/charts/tree/master/stable/metrics-server - name: metrics-server namespace: kube-system chart: stable/metrics-server environments: default: values: - clusterName: CLUSTER_NAME
Cluster Autoscalerのログにエラーが出ていないことを確認します.IAMロールやIAMポリシーが不適切な場合はエラーが出ます.
スケールアップの動作確認
ここでは以下のように echoserver をデプロイします.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: echoserver namespace: echoserver spec: replicas: 1 template: metadata: labels: app: echoserver spec: containers: - image: gcr.io/google_containers/echoserver:1.10 name: echoserver ports: - containerPort: 8080
ここで,以下のようにCPU requestを設定します.1ノード2コアの場合は1500mにするとよいでしょう.要求値が大きすぎると,Cluster Autoscalerはノードを追加してもスケジュール不可能と判断してしまいます.
spec: template: spec: containers: - image: gcr.io/google_containers/echoserver:1.10 name: echoserver ports: - containerPort: 8080 resources: requests: cpu: 1500m
Cluster Autoscalerのログを確認します.以下のように Upcoming 1 nodes
と表示されると成功です.同時に,Auto Scaling GroupのDesired Capacityが書き換わっていることを確認します.しばらく経つと,ノードが増えてPodがスケジュールされるはずです.
I0927 11:50:35.158353 1 scale_up.go:263] Pod echoserver/echoserver-74fd7d865f-vkzqb is unschedulable I0927 11:50:35.158391 1 scale_up.go:300] Upcoming 0 nodes I0927 11:50:35.158521 1 scale_up.go:423] Best option to resize: ASG_NAME I0927 11:50:35.158540 1 scale_up.go:427] Estimated 1 nodes needed in ASG_NAME I0927 11:50:35.158556 1 scale_up.go:529] Final scale-up plan: [{ASG_NAME 4->5 (max: 8)}] I0927 11:50:35.158572 1 scale_up.go:694] Scale-up: setting group ASG_NAME size to 5 I0927 11:50:45.523906 1 scale_up.go:263] Pod echoserver/echoserver-74fd7d865f-vkzqb is unschedulable I0927 11:50:45.524041 1 scale_up.go:300] Upcoming 1 nodes I0927 11:52:36.144782 1 clusterstate.go:194] Scale up in group ASG_NAME finished successfully in 2m0.794268739s
スケールダウンの動作確認
前のセクションで設定したCPU requestを削除します.
デフォルトでは,Cluster Autoscalerがノードが必要ないと判断してから10分後に実際にノードを削除します(詳しくは How does scale-down work? を参照してください).Cluster Autoscalerのログを確認し,以下のように Terminating EC2 instance
が表示されると成功です.
I0927 11:57:07.790306 1 scale_down.go:407] Node ip-172-19-67-52.ap-northeast-1.compute.internal - utilization 0.055000 I0927 11:57:07.790634 1 static_autoscaler.go:359] ip-172-19-67-52.ap-northeast-1.compute.internal is unneeded since 2019-09-27 11:57:07.773690521 +0000 UTC m=+2997.491422805 duration 0s I0927 12:07:12.161679 1 static_autoscaler.go:359] ip-172-19-67-52.ap-northeast-1.compute.internal is unneeded since 2019-09-27 11:57:07.773690521 +0000 UTC m=+2997.491422805 duration 10m4.367847963s I0927 12:07:12.161767 1 scale_down.go:600] ip-172-19-67-52.ap-northeast-1.compute.internal was unneeded for 10m4.367847963s I0927 12:07:12.161868 1 scale_down.go:819] Scale-down: removing empty node ip-172-19-67-52.ap-northeast-1.compute.internal I0927 12:07:12.176857 1 delete.go:64] Successfully added toBeDeletedTaint on node ip-172-19-67-52.ap-northeast-1.compute.internal I0927 12:07:12.391908 1 auto_scaling_groups.go:269] Terminating EC2 instance: i-066bc60549f083e38
最後に,Auto Scaling Groupのdesired capacityが元に戻っていることを確認します.