Amazon EKS にはデフォルトだと Metrics Server がいないので HorizontalPodAutoscaler が動いてくれないと言う話
TL;DR
HorizontalPodAutoscaler と Metrics Server
HorizontalPodAutoscaler は Deployment とか ReplicaSet とかの Pod 数をメトリクスに基づいてスケールさせてくれます。
この際に用いるメトリクスは metrics-server と呼ばれるコンポーネントから API で取得します。metrics-server は kube-system の namespace に Deployment として配置して動作する形になります。
このへんのドキュメント を読むと kubelet に cAdvisor が含まれていてそいつが metrics-server にメトリクスを集約しているらしいです。
Metrics Server がいない
Amazon EKS にはデフォルトだとこの Metrics Server がいません。
eksctl で真っさらのクラスタを新規作成して、namespace: kube-system のリソースを見てみます。
$ eksctl create cluster \ --region ap-northeast-1 \ --nodes 1 \ --nodes-min 1 \ --nodes-max 1 \ --version 1.12
$ kubectl get deployment -n kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 2 2 2 2 10m
CoreDNS しかいないですね。この状態で適当な HPA を apply して get してみます。
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-deployment <unknown>/50% 1 10 0 10s
このように、TARGETS のところが <unknown>/50%
のように表示され、動いてくれません。
describe してみると Event の所に以下のようなメッセージが出ています。
$ kubectl describe hpa sample-hpa ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedGetResourceMetric 3m26s (x4897 over 20h) horizontal-pod-autoscaler unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
メトリクスが取得できないと書かれてあります。このように metrics-server がいないと HorizontalPodAutoscaler が動作しません。
Metrics Server を apply する
metrics-server の apply 方法はドキュメントに書いてある通りです。 Helm chart もあるので Helm を用いる場合はこちらを使いましょう。
$ kubectl create -f deploy/1.8+/
metrics-server が apply できたら再度 kube-system の Deployment を確認してみます。
$ kubectl get deployment -n kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 2 2 2 2 1d metrics-server 1 1 1 1 3h
metrics-server という deployment ができました。
この状態で再度 HPA を get してみると正常に CPU のメトリクスを取得していることが確認できます。
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-deployment 130%/50% 1 10 10 1d
まとめ
Since metrics server is prerequisite for a number of Kubernetes components (HPA, scheduler, kubectl top) it will run by default in all Kubernetes clusters.