Fix HorizontalPodAutoscaler Không Scale: "unable to get metrics for resource cpu: no metrics returned from resource metrics API"

intermediate☸️ Kubernetes2026-03-18| Kubernetes 1.20+, kubectl, metrics-server, HorizontalPodAutoscaler v2

Error Message

unable to get metrics for resource cpu: no metrics returned from resource metrics API
#kubernetes#hpa#autoscaler#metrics-server#scaling

Tình huống gặp phảiBạn đã cấu hình HorizontalPodAutoscaler với kỳ vọng deployment sẽ tự scale khi tải tăng, nhưng không có gì xảy ra. Chạy kubectl describe hpa cho ra kết quả:

Warning  FailedGetResourceMetric  15s   horizontal-pod-autoscaler  unable to get metrics for resource cpu: no metrics returned from resource metrics API

HPA hiển thị TARGETS: <unknown>/50% và số lượng replica đứng yên — dù các pod đang chịu tải rõ ràng.

Nguyên nhânHPA controller truy vấn metrics-server để lấy dữ liệu CPU và memory. Không có metrics-server thì không có dữ liệu. Không có dữ liệu thì không thể ra quyết định scale.

Thường có ba nguyên nhân chính:

  • metrics-server chưa được cài vào cluster- metrics-server đang chạy nhưng health check thất bại — thường do TLS/certificate không khớp- metrics-server không kết nối được tới kubelet trên từng node (network policy hoặc thiếu API flag)## Bước 1: Xác nhận vấn đềKiểm tra trạng thái HPA trước:
kubectl get hpa -n your-namespace
kubectl describe hpa your-hpa-name -n your-namespace

Kéo xuống phần Events — cảnh báo unable to get metrics sẽ hiện ở đó. Tiếp theo, kiểm tra xem metrics-server đã được cài chưa:

kubectl get deployment metrics-server -n kube-system

Nếu thấy Error from server (NotFound) nghĩa là chưa cài. Nếu đã tồn tại, kiểm tra xem nó có đang chạy không:

kubectl get pods -n kube-system | grep metrics-server
kubectl logs -n kube-system deployment/metrics-server

Lỗi TLS sẽ hiện rõ trong log:

E0318 10:23:45.123456       1 scraper.go:139] "Failed to scrape node" err="Get \"https://192.168.1.10:10250/metrics/resource\": x509: certificate signed by unknown authority"

Sửa nhanh: Cài đặt hoặc patch metrics-server### Trường hợp A — metrics-server chưa được càiCài đặt bằng manifest chính thức:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Chờ khoảng 60 giây, sau đó kiểm tra:

kubectl top nodes
kubectl top pods -n your-namespace

Nếu kubectl top nodes trả về dữ liệu nghĩa là metrics-server đã hoạt động.

Trường hợp B — metrics-server đã cài nhưng bị crash (lỗi x509 / TLS)Các cluster bare-metal và cài bằng kubeadm thường xuyên gặp vấn đề này. Kubelet ở đó dùng self-signed certificate, còn metrics-server mặc định từ chối loại certificate này. Cách khắc phục là patch một dòng để tắt xác thực TLS:

kubectl patch deployment metrics-server -n kube-system \
  --type='json' \
  -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'

Theo dõi quá trình rollout hoàn tất:

kubectl rollout status deployment/metrics-server -n kube-system

Sửa triệt để: Manifest metrics-server tùy chỉnhPhải chạy kubectl patch sau mỗi lần cài lại rất mất công. Với môi trường production, hãy lưu sẵn file components.yaml đã được patch vào repo infrastructure. Tải file chính thức trước:

curl -LO https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Mở file và thêm --kubelet-insecure-tls vào phần args trong section Deployment:

spec:
  template:
    spec:
      containers:
      - name: metrics-server
        args:
        - --cert-dir=/tmp
        - --secure-port=10250
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls   # thêm dòng này

Apply lên cluster:

kubectl apply -f components.yaml

Commit file này vào repo. Flag sẽ được giữ nguyên qua các lần cài lại và nâng cấp cluster.

Dùng Helm (cách thay thế)Nếu bạn quản lý metrics-server bằng Helm, truyền flag ngay khi cài:

helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm upgrade --install metrics-server metrics-server/metrics-server \
  --namespace kube-system \
  --set args={--kubelet-insecure-tls}

Xác nhận đã sửa xongKiểm tra kubectl top đã trả về dữ liệu chưa:

kubectl top nodes
# Kết quả mong đợi:
# NAME         CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
# node-1       245m         6%     2312Mi          30%

kubectl top pods -n your-namespace
# NAME                        CPU(cores)   MEMORY(bytes)
# my-app-7d4b9c6f8-xk2pq      12m          128Mi

Kiểm tra HPA — cột TARGETS lúc này phải hiển thị số thực thay vì <unknown>:

kubectl get hpa -n your-namespace
# NAME       REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS
# my-hpa     Deployment/my-app     8%/50%    2         10        2

Theo dõi HPA theo thời gian thực:

kubectl get hpa -n your-namespace -w

Để kiểm tra scale-up, hãy tạo tải CPU lên các pod. Số replica sẽ bắt đầu tăng trong vòng một đến hai phút.

Vẫn còn lỗi?metrics-server trông có vẻ ổn nhưng TARGETS vẫn hiển thị <unknown>? Kiểm tra thêm một số điều sau:

  • Chưa khai báo resource requests: HPA tính phần trăm CPU dựa trên resources.requests.cpu của pod. Nếu thiếu trường này, phép tính phần trăm sẽ không thực hiện được — dù đã có metrics thô.resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi"- API aggregation chưa được đăng ký: Một số cluster thiếu hoàn toàn endpoint metrics API. Chạy kubectl api-versions | grep metrics — kết quả phải có metrics.k8s.io/v1beta1.- NetworkPolicy chặn metrics-server: Các policy nghiêm ngặt có thể âm thầm chặn traffic. Đảm bảo metrics-server trong kube-system có thể kết nối tới kubelet trên cổng 10250 của tất cả các node.

Related Error Notes