Предполагается, что AWS EKS уже создан, и имеет рабочие ноды.
Ниже — выполним настройку подключения к кластеру, создадим тестовый деплоймент с HPA — Kubernetes Horizontal Pod AutoScaler, и попробуем получить данные об используемых ресурсах с помощью kubectl top.
Содержание
Kubernetes cluster
Создаём тестовый кластер:
[simterm]
$ eksctl create cluster --profile arseniy --region us-east-2 --name eks-dev-1 ... [ℹ] node "ip-192-168-54-141.us-east-2.compute.internal" is ready [ℹ] node "ip-192-168-85-24.us-east-2.compute.internal" is ready [ℹ] kubectl command should work with "/home/setevoy/.kube/config", try 'kubectl get nodes' [✔] EKS cluster "eks-dev-1" in "us-east-2" region is ready
[/simterm]
Переключаемся на него.
Kubernetes cluster context
Настраиваем kubectl:
[simterm]
$ aws eks --profile arseniy --region us-east-2 update-kubeconfig --name eks-dev-1 Added new context arn:aws:eks:us-east-2:534***385:cluster/eks-dev-1 to /home/setevoy/.kube/config
[/simterm]
Проверяем доступные в аккаунте и регионе кластера EKS:
[simterm]
$ aws eks --profile arseniy --region us-east-2 list-clusters --output text CLUSTERS eksctl-bttrm-eks-production-1 CLUSTERS mobilebackend-dev-eks-0-cluster CLUSTERS eks-dev-1
[/simterm]
Проверяем текущий профиль:
[simterm]
$ kubectl config current-context arn:aws:eks:us-east-2:534***385:cluster/eks-dev-1
[/simterm]
aws eks уже настроил и подключил нам новый профиль kubectl.
При необходимости — находим настроенные профили:
[simterm]
$ kubectl config get-contexts
[/simterm]
И переключаемся на нужный:
[simterm]
$ kubectl config use-context arn:aws:eks:us-east-2:534***385:cluster/eks-dev-1 Switched to context "arn:aws:eks:us-east-2:534***385:cluster/eks-dev-1".
[/simterm]
Deployment
Для тестов используем деплоймент с AutoScaler.
HPA использует метрики, полученные от mertics-server для собра данных о нагрузке на нодах и подах для принятия решения о необходимости скейлинга подов.
Создаём HPA и деплоймент:
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: hello-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hello
minReplicas: 1
maxReplicas: 2
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: gcr.io/google-samples/node-hello:1.0
resources:
limits:
cpu: "0.1"
requests:
cpu: "0.1"
Деплоим:
[simterm]
$ kubectl apply -f example-deployment.yml horizontalpodautoscaler.autoscaling/hello-hpa created deployment.apps/hello created
[/simterm]
Проверяем:
[simterm]
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hello-hpa Deployment/hello <unknown>/80% 1 2 1 26s
[/simterm]
HPA — TARGETS <TARGETS> и unable to get metrics
Если проверить состояние HPA сейчас — то увидим, что он не видит текущего состояния своих таргетов (подов в деплойментах):
[simterm]
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hello-hpa Deployment/hello <unknown>/80% 1 2 1 26s
[/simterm]
В Conditions и Events можем увидеть более детальные сообщения об ошибках:
[simterm]
$ kubectl describe hpa hello-hpa ... Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: 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) ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedGetResourceMetric 12s (x3 over 43s) 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) Warning FailedComputeMetricsReplicas 12s (x3 over 43s) horizontal-pod-autoscaler failed to get cpu utilization: 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)
[/simterm]
Собственно, вот наша ошибка:
failed to get cpu utilization: unable to get metrics for resource cpu
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
Кроме того, при попытке выполнить сейчас top для подов или нод — Kubernetes сообщит:
[simterm]
$ kubectl top node Error from server (NotFound): the server could not find the requested resource (get services http:heapster:) $ kubectl top pod Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
[/simterm]
Что бы top мог отобразить данные об испуользуемых ресурсах — он пытается обратиться к Heapster, см. исходный код:
... o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port) ...
А Heaspter — устаревший сервис, который ранее использовался для сбора метрик.
Сейчас для получения метрик об используемых CPU и памяти — используем metrics-server, который заменил Heapster.
Запуск metrics-server
Клонируем репозиторий:
[simterm]
$ git clone https://github.com/kubernetes-sigs/metrics-server.git $ cd metrics-server/
[/simterm]
Настройки для AWS EKS
Что бы metrics-сервер мог собирать метрики в AWS Elastic Kubernetes Service кластере — редактируем его деплоймент deploy/kubernetes/metrics-server-deployment.yaml, и добавляем command с запуском сервера с четырьмя аргументами:
...
command:
- /metrics-server
- --logtostderr
- --kubelet-insecure-tls=true
- --kubelet-preferred-address-types=InternalIP
- --v=2
...
kubelet-insecure-tls— не выполнять проверку CA сертификата kubelet-клиента на нодахkubelet-preferred-address-types— как выполнять обращение к нодам и подам — по Hostname, InternalDNS, InternalIP, ExternalDNS или ExternalIP, для EKS задаём InternalIPv=2— уровень детализации логов
Сохраняем, и деплоим в кластер:
[simterm]
$ kubectl apply -f deploy/kubernetes/ clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created 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.apps/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
[/simterm]
Проверяем:
[simterm]
$ kubectl -n kube-system get pod NAME READY STATUS RESTARTS AGE aws-node-mt9pq 1/1 Running 0 2m5s aws-node-rl7t2 1/1 Running 0 2m2s coredns-74dd858ddc-xmrhj 1/1 Running 0 7m33s coredns-74dd858ddc-xpcwx 1/1 Running 0 7m33s kube-proxy-b85rv 1/1 Running 0 2m5s kube-proxy-n647l 1/1 Running 0 2m2s metrics-server-546565fdc9-56xwl 1/1 Running 0 6s
[/simterm]
Или так:
[simterm]
$ kubectl get apiservices | grep metr v1beta1.metrics.k8s.io kube-system/metrics-server True 91s
[/simterm]
Проверяем его логи:
[simterm]
$ kubectl -n kube-system logs -f metrics-server-546565fdc9-qswck I0215 11:59:05.896014 1 serving.go:312] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key) I0215 11:59:06.439725 1 manager.go:95] Scraping metrics from 0 sources I0215 11:59:06.439749 1 manager.go:148] ScrapeMetrics: time: 2.728µs, nodes: 0, pods: 0 I0215 11:59:06.450735 1 secure_serving.go:116] Serving securely on [::]:4443 E0215 11:59:10.096632 1 reststorage.go:160] unable to fetch pod metrics for pod default/hello-7d6c85c755-r88xn: no metrics known for pod E0215 11:59:25.109059 1 reststorage.go:160] unable to fetch pod metrics for pod default/hello-7d6c85c755-r88xn: no metrics known for pod
[/simterm]
Пробуем top ноды:
[simterm]
$ kubectl top node error: metrics not available yet
[/simterm]
И под:
[simterm]
$ kubectl top pod W0215 13:59:58.319317 4014051 top_pod.go:259] Metrics not available for pod default/hello-7d6c85c755-r88xn, age: 4m51.319306547s error: Metrics not available for pod default/hello-7d6c85c755-r88xn, age: 4m51.319306547s
[/simterm]
Через 1-2 минуты в логах metrics-server:
[simterm]
I0215 12:00:06.439839 1 manager.go:95] Scraping metrics from 2 sources I0215 12:00:06.447003 1 manager.go:120] Querying source: kubelet_summary:ip-192-168-54-141.us-east-2.compute.internal I0215 12:00:06.450994 1 manager.go:120] Querying source: kubelet_summary:ip-192-168-85-24.us-east-2.compute.internal I0215 12:00:06.480781 1 manager.go:148] ScrapeMetrics: time: 40.886465ms, nodes: 2, pods: 8 I0215 12:01:06.439817 1 manager.go:95] Scraping metrics from 2 sources
[/simterm]
Пробуем ещё раз top:
[simterm]
$ kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% ip-192-168-54-141.us-east-2.compute.internal 25m 1% 406Mi 5% ip-192-168-85-24.us-east-2.compute.internal 26m 1% 358Mi 4%
[/simterm]
Под:
[simterm]
$ kubectl top pod NAME CPU(cores) MEMORY(bytes) hello-7d6c85c755-r88xn 0m 8Mi
[/simterm]
И проверим HPA:
[simterm]
$ kubectl describe hpa hello-hpa ... Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True ReadyForNewScale recommended size matches current size ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited True TooFewReplicas the desired replica count is more than the maximum replica count Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedComputeMetricsReplicas 4m23s (x12 over 7m10s) horizontal-pod-autoscaler failed to get cpu utilization: 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) Warning FailedGetResourceMetric 4m8s (x13 over 7m10s) 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)
[/simterm]
Тут обращаем внимание на:
- the HPA was able to successfully calculate a replica count from cpu resource utilization — HPA смог получить метрики
- unable to get metrics for resource cpu — смотрим Age, и счётчик событий (х13), должен перестать расти
Собственно, на этом всё.
Ниже — ещё одна достаточно часто встречающая проблема при настройке HPA, связанная с метриками.
HPA was unable to compute the replica count: missing request for cpu
Иногда HPA может сообщать об ошибках вида:
[simterm]
$ kubectl describe hpa hello-hpa ... Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: missing request for cpu ... Warning FailedGetResourceMetric 2s (x2 over 17s) horizontal-pod-autoscaler missing request for cpu
[/simterm]
Возникает она при отсутствии resources и requests в шаблоне пода — тут они закомментированы, и деплоймент был обновлён:
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: gcr.io/google-samples/node-hello:1.0
# resources:
# limits:
# cpu: "0.1"
# requests:
# cpu: "0.1"
Возвращаем обратно requests — и всё работает.
Готово.