Kubernetes集群资源指标采集组件
metrics-server 是 Kubernetes 官方维护的集群资源指标采集器。它定期从每个节点的 kubelet 拉取 Summary API,聚合成标准 Metrics API(metrics.k8s.io)并通过 API 聚合层暴露出去。
它是两个高频功能的前置依赖:
kubectl top node / kubectl top pod — 查看节点与 Pod 的实时 CPU、内存占用组件构成(通常部署在 kube-system):
Deployment/metrics-server 采集与聚合进程
Service/metrics-server 暴露给聚合层
APIService/v1beta1.metrics.k8s.io 把 metrics.k8s.io 注册到 API Server
ClusterRole/ClusterRoleBinding 读取 nodes、pods、nodes/stats 等资源
RoleBinding/metrics-server-auth-reader 允许访问扩展 API
数据流:kubelet(Summary API) → metrics-server → Metrics API → kubectl top / HPA
metrics-server 只在内存中保留最近若干次采样,不写入持久化存储,因此不能用于长期趋势分析、容量规划或计费,这类需求请使用 Prometheus。
# 方式一:官方清单(单副本)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 方式二:高可用部署(需要 enable-aggregator-routing=true)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml
# 方式三:Helm
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update
helm upgrade --install metrics-server metrics-server/metrics-server \
--namespace kube-system \
--set args="{--kubelet-insecure-tls}"
# 指定版本
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.2/components.yaml
自签证书集群(如 kubeadm 默认部署)需要额外放宽 kubelet 证书校验:
kubectl patch deployment metrics-server -n kube-system --type=json -p='[
{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"},
{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-preferred-address-types=InternalIP,Hostname"}
]'
--kubelet-insecure-tls 跳过 kubelet 证书校验(仅测试环境)
--kubelet-preferred-address-types=InternalIP,Hostname 选择连接 kubelet 的地址类型
--kubelet-use-node-status-port 使用节点状态中的端口,而非默认 10250
--metric-resolution=15s 采集间隔,默认 15 秒
--secure-port=4443 HTTPS 服务端口
--cert-dir=/tmp 证书目录
--requestheader-allowed-names API 聚合层请求头认证
--authorization-always-allow-paths=/.well-known/openid-configuration,/healthz
# 节点资源占用
kubectl top node
kubectl top node --sort-by=memory
kubectl top node <node-name>
# Pod 资源占用
kubectl top pod
kubectl top pod -A
kubectl top pod -n kube-system
kubectl top pod --sort-by=cpu
kubectl top pod --sort-by=memory
# 按容器拆分显示
kubectl top pod my-app-7d9f8b6c5-abcde --containers
# 按标签筛选并汇总
kubectl top pod -l app=nginx --sum
# 指定命名空间
kubectl top pod -l app=nginx -n dev
# 查看 APIService 状态,Available 必须为 True
kubectl get apiservice v1beta1.metrics.k8s.io
kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
# 直接查询原始指标
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes"
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes/$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')"
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods"
# 确认资源已注册
kubectl api-resources | grep metrics
# 查看组件状态与日志
kubectl get deploy,pod -n kube-system -l k8s-app=metrics-server
kubectl logs -n kube-system deploy/metrics-server --tail=100
HPA 的目标利用率是「实际用量 / requests」,必须为容器配置 requests 才能生效:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app
namespace: dev
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
kubectl autoscale deployment my-app --cpu-percent=70 --min=2 --max=10 -n dev
kubectl get hpa -n dev
kubectl describe hpa my-app -n dev
# 1. Metrics API not available —— 组件没装好或 APIService 未就绪
kubectl top pods
kubectl get apiservice v1beta1.metrics.k8s.io
# 2. x509: cannot validate certificate for x.x.x.x —— kubelet 证书不被信任
kubectl logs -n kube-system deploy/metrics-server | grep -i x509
# 临时方案:增加 --kubelet-insecure-tls
# 3. dial tcp x.x.x.x:10250: connect: connection refused
# 节点地址类型选错,通常是走了 Flannel/Calico 网段之外的地址
# 增加 --kubelet-preferred-address-types=InternalIP
# 4. no metrics known for pod —— 刚启动尚无采集数据,等 1~2 个周期
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes"
# 5. HPA 显示 <unknown>/70%
kubectl describe hpa my-app -n dev
kubectl get deploy my-app -n dev -o jsonpath='{.spec.template.spec.containers[*].resources}'
kubectl get hpa 会显示 <unknown>,事件里报 unable to get metrics for resource cpu: no metrics returned from resource metrics API。resources.requests 时 HPA 无法计算利用率。utilization 是相对 requests 的百分比,缺了 requests 目标值只能是 <unknown>/70%,HPA 不会扩缩容。x509 错误,测试环境可加 --kubelet-insecure-tls,生产环境应把集群 CA 配置给 metrics-server 而不是跳过校验。kubectl top 会报错,需要等待至少一个 --metric-resolution 周期(默认 15 秒)才有数据,属于正常现象。--metric-resolution 不建议调得过小。每次采集都会访问全部节点的 kubelet,大集群下过高的采集频率会显著增加 kubelet 与 API Server 压力。enable-aggregator-routing,否则多副本时请求会被随机转发到尚未就绪的实例,出现间歇性 Metrics API not available。--authentication-token-webhook=true、--authorization-mode=Webhook),这是绝大多数发行版的默认值,但手工编译的 kubelet 可能未开启,表现为 401/403。kube-system 出流量时会直接导致采集失败。kubectl — Kubernetes集群管理工具kubeadm — Kubernetes集群安装工具k9s — 终端下的 Kubernetes 管理 UIhelm — Kubernetes包管理器