あふん

ぷろぐらむとか

Amazon EKS にはデフォルトだと Metrics Server がいないので HorizontalPodAutoscaler が動いてくれないと言う話

f:id:ponde_m:20190325193636p:plain:w300

TL;DR

docs.aws.amazon.com

HorizontalPodAutoscaler と Metrics Server

HorizontalPodAutoscaler は Deployment とか ReplicaSet とかの Pod 数をメトリクスに基づいてスケールさせてくれます。

kubernetes.io

この際に用いるメトリクスは 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.