Terraformで構築したEKSにHelmでHPA、CA、ALB Ingressまで導入


概要

k8s上でオートスケールするWebアプリケーションを動かす場合、DeploymentとServiceに加え、Ingress、Horizontal Pod Autoscaler (HPA) まで作成することになります。

また、ホストのオートスケーリングのためにはCluster Autoscaler (CA) の導入も必要です。

そこで、 Amazon EKS Workshop などを参考にEKSでHPA、CA、Ingressまで試してみて、すんなり進まずハマった点を含めてまとめました。

この記事のソースコードは こちら です。


前提

以下のツールをインストール済みのMacを使って実施しました。


  • kubectl v1.13.1

  • aws cli 1.16.70


    • ~/.aws/credentials も設定済みとします



  • aws-iam-authenticator


    • heptio-authenticator-aws から名前が変わっているので注意してください



  • helm v2.12.1

  • terraform v0.11.10

  • jq 1.6


検証ステップ

以下のステップで検証しました。


  1. TerraformでEKSを構築

  2. Helmをインストール

  3. Metrics Serverをインストール

  4. Cluster Autoscalerをインストール

  5. AWS ALB Ingress Controllerをインストール

  6. Deployment、Service、Ingress、HPAを作成

  7. スケーリングの検証


検証内容


TerraformでEKSを構築

最近はeksctlで構築するサンプルが多いですが、個人的にTerraformで構築してみたかったので、 terraform-aws-modules/eks を使ってみました。

特に eks_test_fixture example を参考にして、以下の3ファイルを作成しました。


providers.tf

provider "aws" {

version = ">= 1.24.0"
region = "ap-northeast-1"
}

provider "random" {
version = "= 1.3.1"
}



vpc.tf

data "aws_availability_zones" "available" {}

resource "aws_security_group" "all_worker_mgmt" {
name_prefix = "all_worker_management"
vpc_id = "${module.vpc.vpc_id}"

ingress {
from_port = 22
to_port = 22
protocol = "tcp"

cidr_blocks = [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
]
}
}

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "1.14.0"
name = "test-vpc"
cidr = "10.0.0.0/16"
azs = ["${data.aws_availability_zones.available.names[0]}", "${data.aws_availability_zones.available.names[1]}", "${data.aws_availability_zones.available.names[2]}"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
tags = "${merge(local.tags, map("kubernetes.io/cluster/${local.cluster_name}", "shared"))}"
}



eks.tf

locals {

cluster_name = "test-eks-${random_string.suffix.result}"
worker_groups = [
{
instance_type = "t2.small"
subnets = "${join(",", module.vpc.private_subnets)}"
},
]
tags = {
Environment = "test"
}
}

resource "random_string" "suffix" {
length = 8
special = false
}

module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "${local.cluster_name}"
subnets = ["${module.vpc.private_subnets}"]
tags = "${local.tags}"
vpc_id = "${module.vpc.vpc_id}"
worker_groups = "${local.worker_groups}"
worker_group_count = "1"
worker_additional_security_group_ids = ["${aws_security_group.all_worker_mgmt.id}"]
}


ファイルを作成したら、Terraformを実行します。

$ ls

eks.tf providers.tf vpc.tf
$ terraform init
$ terraform apply

これだけで、EKSとワーカーノードが作成されます。

Terraformの実行が完了すると、ワーカーノードを登録するためのConfigMapとkubeconfigができています。

$ ls

config-map-aws-auth_test-eks-pSfTUN5w.yaml providers.tf
eks.tf terraform.tfstate
kubeconfig_test-eks-pSfTUN5w vpc.tf

Configmapは適用済みのため、kubectl applyする必要はありません。

kubeconfigは環境変数に設定します。

$ export KUBECONFIG=`pwd`/`ls kubeconfig_*`

$ kubectl get configmaps --all-namespaces
NAMESPACE NAME DATA AGE
kube-system aws-auth 3 3m
kube-system coredns 1 4m
kube-system extension-apiserver-authentication 5 4m
kube-system kube-proxy 1 4m
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-1-211.ap-northeast-1.compute.internal Ready <none> 2m v1.11.5


Helmをインストール

Install Helm CLI の通りHelmをインストールします。


helm/rbac.yaml

---

apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system

$ kubectl apply -f helm/rbac.yaml

$ helm init --service-account tiller

tillerのPodが起動したらHelmのインストールは完了です。

$ kubectl get po --all-namespaces

NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-dkzxr 1/1 Running 1 6m
kube-system coredns-7774b7957b-fndtt 1/1 Running 0 8m
kube-system coredns-7774b7957b-nmc6q 1/1 Running 0 8m
kube-system kube-proxy-bvzwf 1/1 Running 0 6m
kube-system tiller-deploy-85744d9bfb-ghm5j 1/1 Running 0 22s


Metrics Server


インストール

HPAはMetrics Serverに依存しているため、Configure Horizontal Pod Autoscaler (HPA) を参考に、HelmでMetrics Serverをインストールします。

CIを意識して、helm installの代わりにhelm upgrade --installを使っています。

$ helm upgrade --install \

metrics-server \
stable/metrics-server \
--version 2.0.4 \
--namespace kube-system


VPCのDNS設定

Metrics Serverが無事インストールできれば kubectl top nodes などでメトリクスを確認できます。

しかし、この時点の設定ではしばらく待ってもメトリクスが収集できません。

$ kubectl top nodes

error: metrics not available yet

Metrics Serverのログを確認すると...

$ kubectl -n kube-system logs metrics-server-5f64dbfb9d-rc67t

:
E1231 02:40:13.761695 1 manager.go:102] unable to fully collect metrics: unable to fully scrape metrics from source kubelet_summary:ip-10-0-1-211.ap-northeast-1.compute.internal: unable to fetch metrics from Kubelet ip-10-0-1-211.ap-northeast-1.compute.internal (ip-10-0-1-211.ap-northeast-1.compute.internal): Get https://ip-10-0-1-211.ap-northeast-1.compute.internal:10250/stats/summary/: dial tcp: lookup ip-10-0-1-211.ap-northeast-1.compute.internal on 172.20.0.10:53: no such host
:

ワーカーノードが名前解決できていないことが原因のようです。

これは、AWS VPC Terraform Moduleでは、デフォルトでenable_dns_hostnamesがfaluseに設定されているためです。

vpc.tfに enable_dns_hostnames = true という記述を追加して、再度Terraformを実行します。

$ cat vpc.tf

:
module "vpc" {
:
enable_dns_hostnames = true
:
}
$ terraform apply

しばらく待つと、メトリクスの収集ができるようになっています。

$ kubectl top nodes

NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
ip-10-0-1-211.ap-northeast-1.compute.internal 30m 3% 330Mi 17%

HPAが動作するかどうかは、後でCAとまとめて確認します。


参考


Cluster Autoscaler


インストール

terraform-aws-eks - autoscaling.md を参考に、Cluster Autoscalerをインストールします。

values.yamlを作成しますが、リージョンとクラスタ名はここに記述せず、Helm実行時の引数で渡すようにします。


cluster-autoscaler/values.yaml

rbac:

create: true

sslCertPath: /etc/ssl/certs/ca-bundle.crt

cloudProvider: aws

autoDiscovery:
enabled: true


helm upgrade --install を実行します。

$ helm upgrade --install \

cluster-autoscaler \
stable/cluster-autoscaler \
--version 0.11.0 \
--namespace kube-system \
--values cluster-autoscaler/values.yaml \
--set autoDiscovery.clusterName=test-eks-pSfTUN5w \
--set awsRegion=ap-northeast-1

CAの状態はConfigMapのcluster-autoscaler-statusで確認できます。

この時点では、CAはインストールされたものの、まだスケーリング対象のワーカーグループが登録されていません。

$ kubectl -n kube-system describe configmaps cluster-autoscaler-status

Name: cluster-autoscaler-status
Namespace: kube-system
Labels: <none>
Annotations: cluster-autoscaler.kubernetes.io/last-updated: 2018-12-31 03:20:54.995043016 +0000 UTC

Data
====
status:
----
Cluster-autoscaler status at 2018-12-31 03:20:54.995043016 +0000 UTC:
Cluster-wide:
Health: Healthy (ready=1 unready=0 notStarted=0 longNotStarted=0 registered=1 longUnregistered=0)
LastProbeTime: 2018-12-31 03:20:54.932736374 +0000 UTC m=+222.490186161
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591
ScaleUp: NoActivity (ready=1 registered=1)
LastProbeTime: 2018-12-31 03:20:54.932736374 +0000 UTC m=+222.490186161
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-12-31 03:20:54.932736374 +0000 UTC m=+222.490186161
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591

Events: <none>


ワーカーグループの登録

スケーリング対象のワーカーグループを登録するため、eks.tfを修正してワーカーグループの設定を変更します。

autoscaling_enabled = trueprotect_from_scale_in = true を追記し、asg_min_sizeasg_max_sizeasg_desired_capacity も設定しておきます。


eks.tf

locals {

cluster_name = "test-eks-${random_string.suffix.result}"
worker_groups = [
{
instance_type = "t2.small"
subnets = "${join(",", module.vpc.private_subnets)}"
asg_min_size = 2
asg_max_size = 10
asg_desired_capacity = 2
autoscaling_enabled = true
protect_from_scale_in = true
},
]
:
}
:

$ terraform apply

すると、cluster-autoscaler-statusにNodeGroupsが追加されます。

$ kubectl -n kube-system describe configmaps cluster-autoscaler-status

Name: cluster-autoscaler-status
Namespace: kube-system
Labels: <none>
Annotations: cluster-autoscaler.kubernetes.io/last-updated: 2018-12-31 03:34:54.585531666 +0000 UTC

Data
====
status:
----
Cluster-autoscaler status at 2018-12-31 03:34:54.585531666 +0000 UTC:
Cluster-wide:
Health: Healthy (ready=2 unready=0 notStarted=0 longNotStarted=0 registered=2 longUnregistered=0)
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591
ScaleUp: NoActivity (ready=2 registered=2)
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591

NodeGroups:
Name: test-eks-pSfTUN5w-02018123102273646430000000f
Health: Healthy (ready=2 unready=0 notStarted=0 longNotStarted=0 registered=2 longUnregistered=0 cloudProviderTarget=2 (minSize=2, maxSize=10))
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:32:31.956211675 +0000 UTC m=+919.513661423
ScaleUp: NoActivity (ready=2 cloudProviderTarget=2)
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:32:31.956211675 +0000 UTC m=+919.513661423
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-12-31 03:34:54.458541261 +0000 UTC m=+1062.015991044
LastTransitionTime: 2018-12-31 03:32:31.956211675 +0000 UTC m=+919.513661423

Events: <none>

CAの動作確認は最後に実施します。


参考


補足 - k8sクラスタ名の取得

CAのインストールを自動化したい場合、k8sクラスタ名をTerraformから取得することになります。

その場合、outputs.tfを作成して再度 terraform apply を実行した後、 terraform output を実行することになります。


outputs.tf

output "cluster_name" {

value = "${local.cluster_name}"
}

$ terraform apply

$ terraform output -json
{
"cluster_name": {
"sensitive": false,
"type": "string",
"value": "test-eks-pSfTUN5w"
}
}
$ terraform output -json | jq -r '.cluster_name.value'
test-eks-pSfTUN5w


AWS ALB Ingress Controller


インストール

k8s on AWSでALBを使うには、 AWS ALB Ingress Controller をインストールする必要があります。

Setup ALB Ingress Controller を参考に、Helmでインストールします。


aws-alb-ingress-controller/values.yaml

autoDiscoverAwsRegion: true

autoDiscoverAwsVpcID: true

$ helm repo add \

incubator http://storage.googleapis.com/kubernetes-charts-incubator
$ helm upgrade --install \
aws-alb-ingress-controller \
incubator/aws-alb-ingress-controller \
--version 0.1.4 \
--namespace kube-system \
--values aws-alb-ingress-controller/values.yaml \
--set clusterName=test-eks-pSfTUN5w


IAM Roleの設定

これでインストール自体はできましたが、まだALB Ingressを作ることはできません。

この状態ではEKSがELBを扱う権限を持たないため、IAM Roleを追加する必要があります。

iam.tfというファイルを作り、Terraformを実行します。


iam.tf

resource "aws_iam_role_policy_attachment" "alb_ingress_policy_attachment" {

role = "${module.eks.worker_iam_role_name}"
policy_arn = "${aws_iam_policy.alb_ingress_policy.arn}"
}

resource "aws_iam_policy" "alb_ingress_policy" {
name = "alb-ingress-policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:GetCertificate"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DeleteSecurityGroup",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInternetGateways",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVpcs",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteRule",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:SetWebACL"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:GetServerCertificate",
"iam:ListServerCertificates"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"waf-regional:GetWebACLForResource",
"waf-regional:GetWebACL",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"tag:GetResources",
"tag:TagResources"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"waf:GetWebACL"
],
"Resource": "*"
}
]
}
EOF
}


$ terraform apply

これで、ALB Ingressを作るための設定が完了しました。


サブネットのオートディスカバリ設定

今の状態でIngressを作成する場合、マニフェストは以下のようになります。


ingress.yaml

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/subnets: subnet-aaa,subnet-bbb,subnet-ccc
name: sample-app
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: sample-app
servicePort: 80

このままではマニフェストにサブネットIDを書くことになり、面倒です。

そこで、 Subnet Auto Discovery を設定します。

vpc.tfを修正し、Private Subnetに kubernetes.io/role/internal-elb 、Public Subnetに kubernetes.io/role/elb というキーのタグを作成します。


vpc.tf

    :

module "vpc" {
:
tags = "${merge(local.tags, map("kubernetes.io/cluster/${local.cluster_name}", "shared"))}"
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = ""
}
public_subnet_tags = {
"kubernetes.io/role/elb" = ""
}
}

$ terraform apply

これでAWS ALB Ingress Controllerの設定は完了です。


参考


注意

この記事には記載しませんが、Route53との連携やACMを用いたHTTPSを実現するためには追加の設定が必要です。


Deployment、Service、Ingress、HPAを作成

これだけセットアップしたので、ついにオートスケールするWebアプリケーションをデプロイできます。

Deployment、Service、Ingress、HPAの4つのマニフェストを作成します。


deployment.yaml

---

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sample-app
spec:
replicas: 2
selector:
matchLabels:
app: sample-app
minReadySeconds: 5
progressDeadlineSeconds: 60
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
template:
metadata:
labels:
app: sample-app
spec:
terminationGracePeriodSeconds: 60
containers:
- name: sample-app
image: nginx:1.15.8-alpine
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 3
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 500m
memory: 512Mi


service.yaml

---

apiVersion: v1
kind: Service
metadata:
name: sample-app
spec:
selector:
app: sample-app
ports:
- name: sample-app
port: 80
targetPort: 80
type: NodePort


ingress.yaml

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
name: sample-app
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: sample-app
servicePort: 80


hpa.yaml

---

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: sample-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sample-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 10

kubectlでデプロイします。

$ ls

deployment.yaml hpa.yaml ingress.yaml service.yaml
$ kubectl apply -R -f .
deployment.extensions/sample-app created
horizontalpodautoscaler.autoscaling/sample-app created
ingress.extensions/sample-app created
service/sample-app created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/sample-app-665765dbcd-kqd9g 1/1 Running 0 24s
pod/sample-app-665765dbcd-vl6nm 1/1 Running 0 24s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 2h
service/sample-app NodePort 172.20.100.78 <none> 80:30913/TCP 23s

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/sample-app 2 2 2 2 24s

NAME DESIRED CURRENT READY AGE
replicaset.apps/sample-app-665765dbcd 2 2 2 24s

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/sample-app Deployment/sample-app <unknown>/10% 2 10 0 24s

Ingressの起動には時間がかかります。

しばらく待つと、無事Ingress経由でNginxにアクセスできます。

$ curl `kubectl get ingresses -o jsonpath --template {.items[0].status.loadBalancer.ingress[0].hostname}`

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


スケーリングの検証

HPA、CAの検証のため、 kubectl exec を利用して、コンテナ内でCPU使用率を高めてみます。

$ kubectl exec -it sample-app-665765dbcd-kqd9g sh

/ # yes > /dev/null

このまま別ターミナルを見てみると、Podが2個から3個にオートスケールしています。

$ kubectl get all

NAME READY STATUS RESTARTS AGE
pod/sample-app-665765dbcd-kqd9g 1/1 Running 0 12m
pod/sample-app-665765dbcd-m79hs 0/1 Pending 0 50s
pod/sample-app-665765dbcd-vl6nm 1/1 Running 0 12m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 2h
service/sample-app NodePort 172.20.100.78 <none> 80:30913/TCP 12m

NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/sample-app 3 3 3 2 12m

NAME DESIRED CURRENT READY AGE
replicaset.apps/sample-app-665765dbcd 3 3 2 12m

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/sample-app Deployment/sample-app 50%/10% 2 10 3 12m

HPAで作成されたPodのSTATUSがPendingのため、CAによりノードの追加が行われるはずです。

cluster-autoscaler-statusを見てみると...

$ kubectl -n kube-system describe configmaps cluster-autoscaler-status

Name: cluster-autoscaler-status
Namespace: kube-system
Labels: <none>
Annotations: cluster-autoscaler.kubernetes.io/last-updated: 2018-12-31 04:47:06.27366144 +0000 UTC

Data
====
status:
----
Cluster-autoscaler status at 2018-12-31 04:47:06.27366144 +0000 UTC:
Cluster-wide:
Health: Healthy (ready=3 unready=0 notStarted=0 longNotStarted=0 registered=3 longUnregistered=0)
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 03:17:22.931577808 +0000 UTC m=+10.489027591
ScaleUp: NoActivity (ready=3 registered=3)
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236

NodeGroups:
Name: test-eks-pSfTUN5w-02018123102273646430000000f
Health: Healthy (ready=3 unready=0 notStarted=0 longNotStarted=0 registered=3 longUnregistered=0 cloudProviderTarget=3 (minSize=2, maxSize=10))
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 03:32:31.956211675 +0000 UTC m=+919.513661423
ScaleUp: NoActivity (ready=3 cloudProviderTarget=3)
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236
LastTransitionTime: 2018-12-31 04:47:06.088555494 +0000 UTC m=+5393.646005236

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScaledUpGroup 2m22s cluster-autoscaler Scale-up: setting group test-eks-pSfTUN5w-02018123102273646430000000f size to 3
Normal ScaledUpGroup 2m22s cluster-autoscaler Scale-up: group test-eks-pSfTUN5w-02018123102273646430000000f size set to 3

Scale-upのイベントが発生しています。

しばらく待つと、Pod、ノードともにオートスケールしたことを確認できます。

HPA、CA、ALB Ingressまで無事導入できました。


片付け

$ kubectl delete deployment sample-app

$ kubectl delete service sample-app
$ kubectl delete ingress sample-app
$ kubectl delete hpa sample-app
$ helm delete --purge `helm ls -aq`
$ terraform destroy

※ AutoScalingGroupは手動で削除しないとterraform destoryに失敗するかもしれません。