Edited at

EKSでkubectl topやHorizontal Pod Autoscaler (HPA) が使えなかった理由 ※今は使えます


2018/12/31 追記

Amazon EKS Platform Version 2 のご紹介 の通り、2018年8月の時点でEKSはHPAに対応しました。

こちら の記事で動作確認まで実施しました。


概要

EKSでkubectl topコマンドを実行すると、以下のようなエラーが発生しました。

$ kubectl top node

Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)

原因を調べていった結果、EKSではkubectl topやHorizontal Pod Autoscaler (HPA) が使えないようだったので、その理由を調べました。


kubectl topのエラーへの対応

上記のエラーメッセージはHeapsterを入れれば解決するように見えますが、Heapsterはすでにdeprecatedでした。

そこで、Metrics Serverをデプロイしました。

$ git clone https://github.com/kubernetes-incubator/metrics-server.git

$ cd metrics-server
$ kubectl create -f deploy/1.8+/
clusterrolebinding.rbac.authorization.k8s.io "metrics-server:system:auth-delegator" created
rolebinding.rbac.authorization.k8s.io "metrics-server-auth-reader" created
apiservice.apiregistration.k8s.io "v1beta1.metrics.k8s.io" created
serviceaccount "metrics-server" created
deployment.extensions "metrics-server" created
service "metrics-server" created
clusterrole.rbac.authorization.k8s.io "system:metrics-server" created
clusterrolebinding.rbac.authorization.k8s.io "system:metrics-server" created

Metric Serverがデプロイされたか確認すると、CrashLoopBackOffになっていました。

$ kubectl -n kube-system get po

NAME READY STATUS RESTARTS AGE
aws-node-b8pbd 1/1 Running 1 1h
aws-node-lmmqd 1/1 Running 0 1h
aws-node-zk96m 1/1 Running 1 1h
kube-dns-7cc87d595-vb7qr 3/3 Running 0 1h
kube-proxy-6sqbh 1/1 Running 0 1h
kube-proxy-b29vj 1/1 Running 0 1h
kube-proxy-m868n 1/1 Running 0 1h
metrics-server-6fbfb84cdd-nqrgb 0/1 CrashLoopBackOff 21 1h

ログを見てみると...

$ kubectl -n kube-system logs metrics-server-6fbfb84cdd-nqrgb

I0726 12:44:02.490157 1 heapster.go:71] /metrics-server --source=kubernetes.summary_api:''
I0726 12:44:02.490284 1 heapster.go:72] Metrics Server version v0.2.1
I0726 12:44:02.490459 1 configs.go:61] Using Kubernetes client with master "https://10.100.0.1:443" and version
I0726 12:44:02.490492 1 configs.go:62] Using kubelet port 10255
I0726 12:44:02.491452 1 heapster.go:128] Starting with Metric Sink
I0726 12:44:02.867833 1 serving.go:308] Generated self-signed cert (apiserver.local.config/certificates/apiserver.crt, apiserver.local.c
onfig/certificates/apiserver.key)
W0726 12:44:03.222800 1 authentication.go:222] Unable to get configmap/extension-apiserver-authentication in kube-system. Usually fixed
by 'kubectl create rolebinding -n kube-system ROLE_NAME --role=extension-apiserver-authentication-reader --serviceaccount=YOUR_NS:YOUR_SA'
F0726 12:44:03.222895 1 heapster.go:97] Could not create the API server: configmaps "extension-apiserver-authentication" not found

ConfigMapにextension-apiserver-authenticationがないことが原因のようです。

Metric ServerのIssuesでも同様のエラーが報告されています。


I just got off a chat with AWS support. They confirmed that HPA is not supported in EKS yet. If anyone knows of a workaround, I would love to hear about it.


どうやらEKSがHPAをサポートしていないことと関係があるようですが、その繋がりがよく分かりません。

そこで、HPAの仕組みを調べました。


HPAの仕組み

KubernetesのドキュメントのHorizontal Pod Autoscalerのページを見てみると...


By default, the HorizontalPodAutoscaler controller retrieves metrics from a series of APIs. In order for it to access these APIs, cluster administrators must ensure that:


  • The API aggregation layer is enabled.



  • The corresponding APIs are registered:


    • For resource metrics, this is the metrics.k8s.io API, generally provided by metrics-server. It can be launched as a cluster addon.

    • For custom metrics, this is the custom.metrics.k8s.io API. It’s provided by “adapter” API servers provided by metrics solution vendors. Check with your metrics pipeline, or the list of known solutions. If you would like to write your own, check out the boilerplate to get started.

    • For external metrics, this is the external.metrics.k8s.io API. It may be provided by the custom metrics adapters provided above.



  • The --horizontal-pod-autoscaler-use-rest-clients is true or unset. Setting this to false switches to Heapster-based autoscaling, which is deprecated.



HPAはデフォルトでAPIからメトリックを収集するのですが、収集対象のAPIを使うには以下の3点を満たす必要があるようです。


  • API aggregation layerが有効になっていること

  • metrics.k8s.io API、custom.metrics.k8s.io API、external.metrics.k8s.io APIのうち、該当のAPIが有効になっていること

  • オプションがtrueか未設定であること

1つ目の条件に登場するAPI aggregation layerとはなんなのでしょうか。


API aggregation layerとは

公式ドキュメントのaggregation layerについてのページを見てみると...


The aggregation layer allows Kubernetes to be extended with additional APIs, beyond what is offered by the core Kubernetes APIs.


aggregation layerにより、KubernetesにAPIを追加することができるとのことです。



  • Then, setup an extension api-server to work with the aggregation layer.


また、aggregation layerを使うには、extension api-serverを設定するようにと書かれています。

Metric Serverのエラーログに出力されていたextension-apiserver-authenticationと何か関係があるのでしょうか。


extension api-serverとは

extension api-serverの設定についてのページによると...


Create a Kubernetes role binding from the service account in your namespace to the extension-apiserver-authentication-reader role. This allows your extension api-server to access the extension-apiserver-authentication configmap.


extension api-server設定手順の中には、extension-apiserver-authenticationにアクセスするためにRoleBindingを作るようにと書かれています。

ということは、extension api-serverを設定するために、extension-apiserver-authenticationが必要になるようです。

extension-apiserver-authenticationは、どのようにして作られるものなのでしょうか。


extension-apiserver-authenticationはいつ作られるのか

Service Catalogのドキュメントのauth.mdによると...


By default, a main Kubernetes API server configured with the --client-ca-file option automatically creates a ConfigMap called extension-apiserver-authentication in the kube-system namespace, populated with the the client CA file.


extension-apiserver-authenticationは、API Serverのオプションによって自動的に作成されるようです。

どうやら、EKSのAPI Serverは、extension-apiserver-authenticationが作られるように設定されていないようです。


結論

EKSでkubectl topやHPAが使えない理由をまとめると以下の通りです。


  • EKSはAPI Serverのオプションでextension-apiserver-authenticationを用意していない。

  • extension-apiserver-authenticationがないため、extension api-serverを設定することができない。

  • extension api-serverを設定することができないため、Metric Serverがデプロイできない

  • Metric Serverがデプロイできないため、kubectl topもHPAも使えない。

Service CatalogのIssuesによれば、同じ理由でService Catalogも使えないようです。