k8s安装metrics-server,以及相关报错排查

背景:有监控node节点pod的CPU等资源,实现自动扩缩容的需要下,需要安装metrics-server

k8s版本:1.30.14(kubadm安装) 对应metrics-server版本:0.8x(本文使用0.8.1)

1、下载部署清单

复制代码
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml

2、修改components.yaml配置文件

复制代码
containers:
- args:
  - --cert-dir=/tmp
  - --secure-port=10250
  # ... 可能还有其他参数 ...
  - --kubelet-insecure-tls  # 添加这一行(添加)
  image: registry.k8s.io/metrics-server/metrics-server:v0.8.1 # 您的镜像地址(修改)
  name: metrics-server

3、部署与验证

复制代码
kubectl apply -f components.yaml
# 查看 metrics-server Pod 是否运行正常
kubectl get pods -n kube-system -l k8s-app=metrics-server
(最好是kubectl get all -A|grep metrics-server验证)

ubuntu@VM-0-4-ubuntu:~$ kubectl get all -A|grep metrics-server

kube-system pod/metrics-server-588d67bbf8-k8gjm 1/1 Running 0 98m

kube-system service/metrics-server ClusterIP 10.50.168.106 <none> 443/TCP 98m

kube-system deployment.apps/metrics-server 1/1 1 1 98m

kube-system replicaset.apps/metrics-server-588d67bbf8 1 1 1 98m

如果 Pod 状态为 Running,通常表示安装成功。kubectl top nodes会有数据

复制代码
ubuntu@VM-0-4-ubuntu:~$ kubectl top nodes
NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
vm-0-4-ubuntu   81m          2%     2006Mi          55%       
vm-4-5-ubuntu   57m          2%     1042Mi          56% 

5、版本兼容性

不同版本的 metrics-server 对 Kubernetes 集群有兼容性要求。选择版本时,请务必参考官方或云服务商提供的兼容性矩阵。

​​​​​​​6、生产环境安全

在上述示例中,我们使用了 --kubelet-insecure-tls 参数来跳过证书验证,这仅在测试环境中推荐使用。在生产环境中,为了安全起见,你应该配置和使用有效的 TLS 证书。

7、重点来了,安装过程中遇到的问题

由于我们是kubadm安装,因此本文不讲二进制安装k8s后再部署metrics-server问题。kubadm安装的k8s,基本不用考虑apiservice链路聚合问题,二进制安装才会考虑,进而修改api配置文件。

先描述下我们遇到的问题:

kubectl get all -A|grep metrics-server检查时,server,pod,deployment都没问题,但是kubectl top nodes报错,这个时候就需要排查metrics-server最重要的一个东西:apiservice v1beta1.metrics.k8s.io,这个api是metrics-server向k8s注册的一个api接口,主要负责的就是通过k8s获取各个节点pod的cpu等资源使用情况,下面展示下排查细节**

复制代码
ubuntu@VM-0-4-ubuntu:~$ kubectl get apiservice v1beta1.metrics.k8s.io
NAME                     SERVICE                      AVAILABLE                      AGE
v1beta1.metrics.k8s.io   kube-system/metrics-server   False (FailedDiscoveryCheck)   139m

可以看到api状态False,接着看详细描述

复制代码
ubuntu@VM-0-4-ubuntu:~$ kubectl describe apiservice v1beta1.metrics.k8s.io
Name:         v1beta1.metrics.k8s.io
Namespace:    
Labels:       k8s-app=metrics-server
Annotations:  <none>
API Version:  apiregistration.k8s.io/v1
Kind:         APIService
Metadata:
  Creation Timestamp:  2026-08-30T08:09:10Z
  Resource Version:    38004
  UID:                 ceda4901-435b-425f-ab56-b0abaa5c9348
Spec:
  Group:                     metrics.k8s.io
  Group Priority Minimum:    100
  Insecure Skip TLS Verify:  true
  Service:
    Name:            metrics-server
    Namespace:       kube-system
    Port:            443
  Version:           v1beta1
  Version Priority:  100
Status:
  Conditions:
    Last Transition Time:  2026-08-30T10:08:28Z
    Message:               failing or missing response from https://10.50.168.106:443/apis/metrics.k8s.io/v1beta1: Get "https://10.50.168.106:443/apis/metrics.k8s.io/v1beta1": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
    Reason:                FailedDiscoveryCheck
    Status:                False
    Type:                  Available
Events:                    <none>

看,报错metrics-server的 ClusterIP 10.50.168.106 443链接超时

复制代码
vim /etc/kubernetes/manifests/kube-apiserver.yaml
添加
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- --enable-aggregator-routing=true(添加该参数)
会临时解决报错443超时(不建议使用)

但是这会引起另一个类似报错是metrics-server的pod 10250超时

复制代码
ubuntu@VM-0-4-ubuntu:~$ kubectl describe apiservice v1beta1.metrics.k8s.io
Name:         v1beta1.metrics.k8s.io
Namespace:    
Labels:       k8s-app=metrics-server
Annotations:  <none>
API Version:  apiregistration.k8s.io/v1
Kind:         APIService
Metadata:
  Creation Timestamp:  2026-08-30T08:09:10Z
  Resource Version:    38004
  UID:                 ceda4901-435b-425f-ab56-b0abaa5c9348
Spec:
  Group:                     metrics.k8s.io
  Group Priority Minimum:    100
  Insecure Skip TLS Verify:  true
  Service:
    Name:            metrics-server
    Namespace:       kube-system
    Port:            443
  Version:           v1beta1
  Version Priority:  100
Status:
  Conditions:
    Last Transition Time:  2026-08-30T10:08:28Z
    Message:               failing or missing response from https://10.60.139.19:10250/apis/metrics.k8s.io/v1beta1: Get "https://10.60.139.19:10250/apis/metrics.k8s.io/v1beta1": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
    Reason:                FailedDiscoveryCheck
    Status:                False
    Type:                  Available
Events:                    <none>

到现在,我们弄清楚了报错信息,但是还要找原因

先说根本原因:网络不通(不要想什么api聚合问题,就是网络原因)

为什么我笃定是网络原因呢,因此就这个问题我排查了2天,api聚合链路,metrics-server配置文件什么的各种参数,甚至k8s我都重装了一遍,网上也各种搜索,有的文章也说到了是网络问题,但是给出的解决方案安全性不高,基于此才想把该问题分享下

先说下网上的解决方案:

在metrics-server配置文件里加一个参数

复制代码
      serviceAccountName: metrics-server
      hostNetwork: true #(加的参数)
      volumes:
      - emptyDir: {}
        name: tmp-dir

该参数确实能解决以上我们遇到的问题,但是会增加风险:暴露宿主机网络、端口冲突、安全性下降

那么有没有什么更安全的解决方案呢?有的。其实能遇到443,10250链接超时问题的小伙伴,我想大多数应该都是在云主机上搭建的测试环境(或者是本地环境的网络配置有问题)

我的环境就是腾讯云主机的环境,基于此分析,那么为什么我们443,10250会超时就很简单了,就是因为calico vxlan模式使用的是4789端口UDP协议,但是云防火墙该端口协议没开!!!

只要我们在云主机防火墙规则打开4789端口UDP协议就可以,不用其他什么配置

至于本地环境的小伙伴,依据此问题判断,大概率就是路由器规则不允许4789端口UDP协议通行导致的

当然,这只是本人遇到的443,10250超时的一种情况,若是有其他情况,欢迎补充。