Metrics Server 面试题
8 道题- 分类
- 可观测性
- 子分类
- metrics
- 题目数
- 8 道
1 Metrics Server 的核心定位和架构是什么?
答案:
Metrics Server 是 Kubernetes 集群范围内的资源指标聚合器(Cluster-wide Aggregator),是 HPA、VPA、kubectl top 等功能的指标数据源。
核心定位:
| 维度 | 说明 |
|---|---|
| 本质 | Kubernetes 部署插件(Addon) |
| 作用 | 聚合 kubelet 的资源指标,对外暴露 Metrics API |
| 数据源 | kubelet Summary API(10250 端口) |
| API 注册 | metrics.k8s.io (v1beta1) / metrics.k8s.io (v1) |
| 存储 | 内存存储,不持久化历史数据 |
| 官方仓库 | kubernetes-sigs/metrics-server |
架构流程:
graph LR
A["kubelet
Summary API
(10250)"] -->|每 15s 抓取| B["Metrics Server"]
B -->|聚合| C["内存存储
(In-Memory)"]
C -->|APIService 注册| D["kube-apiserver"]
D -->|Metrics API| E["HPA / kubectl top
Scheduler / VPA"]
关键特性:
- 单实例部署:Metrics Server 自身是单 Pod,不支持高可用(HA),因为只做内存聚合
- 精简职责:只做"采集 → 聚合 → 暴露 API",不做长期存储、不做告警
- Metrics Pipeline 标准化:替代早期废弃的 Heapster 方案
2 Metrics Server 的数据采集机制(kubelet Summary API 聚合)是什么?
答案:
Metrics Server 通过 kubelet 10250 端口暴露的 Summary API 周期性抓取节点级资源使用数据,聚合后暴露 Metrics API。
kubelet Summary API:
| 字段 | 说明 |
|---|---|
| Node 维度 | node_cpu_usage_seconds_total、node_memory_working_set_bytes |
| Pod 维度 | 每个 Pod 的 CPU/内存使用量、Limit/Request |
| 容器维度 | cgroups 统计的 CPU/内存使用 |
| 网络/磁盘 | 本节点 fs/network 统计(Metrics Server 不采集) |
采集流程:
Metrics Server 启动
↓
1. 监听 Node / Pod 列表(List-Watch API)
↓
2. 对每个 Node 并发请求 Summary API
GET https://<NodeIP>:10250/stats/summary
↓
3. 解析 cgroups 数据 → 计算 CPU 使用率(核数)
↓
4. 校验数据新鲜度(默认 1 分钟内)
↓
5. 聚合到内存 → 通过 Metrics API 暴露
核心参数:
args:
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-insecure-tls=true # 自签证书场景
- --metric-resolution=15s # 采集间隔
- --request-timeout=10s # 单节点请求超时
- --node-selector=kubernetes.io/os=linux
CPU 使用率计算:
公式:
CPU 使用率(核) = node_cpu_usage_seconds_total[1m] rate × 1
CPU 使用率(%) = CPU 使用率(核) / node_cpu_capacity
底层:
cgroup cpuacct.usage(纳秒)→ 差分 → 转换为核数
与 cAdvisor 的关系:
- kubelet 内置 cAdvisor 负责采集 cgroup 原始数据
- Summary API 是 cAdvisor 数据的格式化封装
- Metrics Server 不直接读 cgroup,只调 Summary API
3 HPA 指标来源有哪些?Metrics Server 在 HPA 中扮演什么角色?
答案:
HPA 指标来源分为三类:Resource Metrics(资源指标)、Custom Metrics(自定义指标)、External Metrics(外部指标),分别由不同的 Metrics Adapter 提供。
HPA 指标分类:
| 指标类型 | API 组 | 数据源 | 版本演进 |
|---|---|---|---|
| Resource Metrics | metrics.k8s.io | Metrics Server | v1beta1 → v1 (1.21+) |
| Custom Metrics | custom.metrics.k8s.io | Custom Metrics Adapter | v1beta1 → v1beta2 |
| External Metrics | external.metrics.k8s.io | External Metrics Adapter | v1beta1 → v1beta2 |
HPA 工作机制:
sequenceDiagram
participant HM as HPA Controller
participant API as kube-apiserver
participant MS as Metrics Server
participant K as kubelet
loop 每 15s
HM->>API: 查询指标 (Metrics API)
API->>MS: 转发请求
MS->>K: 拉取 Summary API
K-->>MS: CPU/内存使用
MS-->>API: 聚合数据
API-->>HM: 指标值
end
HM->>HM: 计算期望副本数
HM->>API: 更新 Deployment replicas
HPA v2 配置示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
# 1. Resource Metrics(Metrics Server 提供)
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# 2. Custom Metrics(Custom Adapter 提供)
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1k"
# 3. External Metrics(External Adapter 提供)
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: orders
target:
type: Value
value: "30"
Metrics Server 提供的指标(仅限 CPU/内存):
- Pod CPU 使用量(核)
- Pod 内存使用量(字节)
- Node CPU / 内存使用量
- 容器级别指标(v1 API)
HPA 副本数计算公式:
desiredReplicas = ceil[currentReplicas × (currentMetricValue / desiredMetricValue)]
注意:仅当 metrics 字段中所有指标均计算后,HPA 才发布新副本数
(多指标取最大副本数)
4 Metrics Server 与 kube-state-metrics 的区别是什么?
答案:
Metrics Server 与 kube-state-metrics 均暴露 K8s 资源指标,但定位、数据源、用途完全不同,常被混淆。
核心区别:
| 维度 | Metrics Server | kube-state-metrics |
|---|---|---|
| 数据源 | kubelet Summary API(运行时指标) | kube-apiserver List-Watch(状态指标) |
| 指标性质 | 资源使用量(CPU/内存) | 资源状态(健康/配置/关系) |
| 指标类型 | Gauge(瞬时值) | Gauge(大部分)、Counter(少量) |
| 暴露方式 | Metrics API(K8s 标准 API) | Prometheus 格式(/metrics) |
| API 注册 | metrics.k8s.io | 无(独立 Service,需要 Prometheus 抓取) |
| 主要消费者 | HPA / kubectl top / VPA | Prometheus + Grafana + Alertmanager |
| 存储 | 内存(不持久化) | 无状态(计算后丢弃) |
| 部署数量 | 单实例(HA 不支持) | 多实例(无状态,可水平扩展) |
| 官方地址 | kubernetes-sigs/metrics-server | kubernetes/kube-state-metrics |
指标对比:
| Metrics Server 指标 | kube-state-metrics 指标 |
|---|---|
node_cpu_usage_seconds_total | kube_node_status_condition |
node_memory_working_set_bytes | kube_node_info |
pod_cpu_usage_seconds_total | kube_pod_status_phase |
pod_memory_working_set_bytes | kube_pod_container_status_restarts_total |
container_cpu_usage_seconds_total | kube_deployment_status_replicas_* |
| — | kube_job_status_* |
| — | kube_statefulset_replicas_* |
| — | kube_pod_labels_* (label 关联) |
典型应用场景:
Metrics Server:
- HPA 副本伸缩(CPU/内存触发)
- kubectl top node/pod 实时查看
- Scheduler 调度(resource 感知)
- VPA 垂直 Pod 伸缩
kube-state-metrics:
- Prometheus 采集 → Grafana 仪表盘
- 告警规则(Pod 长时间未就绪、Deployment 副本不一致)
- 业务监控(Job 失败次数、StatefulSet 滚动状态)
- 关联分析(Pod 状态、节点健康、Owner Reference)
协同关系: 生产环境需同时部署:Metrics Server 满足伸缩需求,kube-state-metrics 满足可观测性需求,二者通过不同 API 暴露数据,互不替代。
5 Metrics API 是如何在 Kubernetes 中注册的?APIService 机制是什么?
答案:
Metrics Server 通过 Kubernetes 的 Aggregator 机制(API Aggregation)注册为 APIService,将 /apis/metrics.k8s.io/ 路径下的请求代理到 Metrics Server Pod。
Aggregator 架构:
graph TB
Client["kubectl / HPA"] -->|GET /apis/metrics.k8s.io/v1beta1/pods| APIServer["kube-apiserver"]
APIServer -->|路径匹配| Agg["Aggregator Layer"]
Agg -->|代理| AS["APIService
metrics.k8s.io"]
AS -->|转发| MS["Metrics Server
(Service: 443)"]
MS -->|查询内存| Mem["聚合数据"]
APIService 注册清单:
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1beta1.metrics.k8s.io
spec:
service:
name: metrics-server
namespace: kube-system
port: 443
group: metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: true # 自签证书
groupPriorityMinimum: 100
versionPriority: 100
Aggregator 启用要求:
1. kube-apiserver 启动参数:
--enable-aggregator-routing=true # 1.18+ 默认开启
--proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
--proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-
2. Aggregator 工作原理:
- kube-apiserver 监听到 APIService CR
- 注册路由:/apis/metrics.k8s.io/* → 后端 Service
- 转发时携带原始请求头 + 客户端 CA 证书
- 后端 Service 验证请求头中的客户端 CA
Metrics Server RBAC 权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:metrics-server
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "nodes/stats", "namespaces"]
verbs: ["get", "list", "watch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
常见排查命令:
# 查看 APIService 注册状态
kubectl get apiservices | grep metrics
kubectl describe apiservice v1beta1.metrics.k8s.io
# 直接访问 Metrics API
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods
# 验证 aggregator 启用
kubectl -n kube-system get pod -l k8s-app=metrics-server
kubectl logs -n kube-system -l k8s-app=metrics-server
关键问题:
若 kubectl top node 无输出但 Pod 正常,需检查:
- APIService 是否 AVAILABLE(True)
- kube-apiserver 是否启用
--enable-aggregator-routing - front-proxy 证书链是否完整
6 Metrics Server 的标准部署方式(Helm Chart)是什么?
答案:
Metrics Server 推荐使用 Helm Chart 部署(metrics-server chart),亦支持静态 YAML 清单。生产环境需配置证书、RBAC、节点选择等参数。
Helm Chart 部署(推荐):
# 添加仓库
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[0]="--kubelet-insecure-tls" \
--set args[1]="--kubelet-preferred-address-types=InternalIP"
# 生产推荐配置
helm upgrade --install metrics-server metrics-server/metrics-server \
--namespace kube-system \
--version 3.12.0 \
--set replicas=1 \
--set args[0]="--kubelet-preferred-address-types=InternalIP" \
--set args[1]="--kubelet-insecure-tls=true" \
--set args[2]="--metric-resolution=15s" \
--set args[3]="--request-timeout=10s" \
--set resources.requests.cpu=100m \
--set resources.requests.memory=200Mi \
--set resources.limits.cpu=500m \
--set resources.limits.memory=512Mi \
--set serviceMonitor.enabled=true \
--set serviceMonitor.namespace=monitoring \
--set podDisruptionBudget.enabled=true
values.yaml 关键配置:
# Chart 关键配置项
replicas: 1 # 不支持 HA
image:
repository: registry.k8s.io/metrics-server/metrics-server
tag: v0.7.2
args:
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-insecure-tls=true
- --metric-resolution=15s
- --request-timeout=10s
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 500m
memory: 512Mi
nodeSelector:
kubernetes.io/os: linux
tolerations:
- operator: Exists
effect: NoSchedule
podDisruptionBudget:
enabled: true
minAvailable: 1
priorityClassName: system-cluster-critical
serviceAccount:
create: true
name: metrics-server
serviceMonitor:
enabled: true # 由 Prometheus Operator 采集
namespace: monitoring
interval: 30s
静态 YAML 部署(不推荐生产):
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
部署验证:
# 1. Pod 状态
kubectl -n kube-system get pod -l k8s-app=metrics-server
# 2. APIService 状态
kubectl get apiservice v1beta1.metrics.k8s.io
# 输出 AVAILABLE=True 表示正常
# 3. 功能验证
kubectl top node
kubectl top pod -A
# 4. Metrics API 直接调用
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes | jq .
# 5. HPA 联动验证
kubectl get hpa -A
生产部署关键点:
| 项目 | 推荐值 | 说明 |
|---|---|---|
| replicas | 1 | 单实例即可(无状态、内存聚合) |
| 资源限制 | 500m CPU / 512Mi | 1000 节点集群参考值 |
| kubelet-insecure-tls | 生产环境尽量关闭 | 改用 --tls-cert-file 校验 |
| metric-resolution | 15s-30s | 与 HPA --horizontal-pod-autoscaler-sync-period 匹配 |
| nodeSelector | 排除 Windows 节点 | 仅 Linux 节点运行 |
| priorityClassName | system-cluster-critical | 保证关键路径可用 |
7 Metrics Server 的扩展方式是什么?Custom Metrics Adapter 如何对接自定义指标?
答案:
Metrics Server 仅提供 Resource Metrics(CPU/内存)。如需 Custom Metrics(QPS、延迟等业务指标)或 External Metrics(消息队列积压、SLA 指标),需部署 Custom Metrics Adapter 实现 Metrics API 扩展。
Metrics Adapter 体系:
graph TB
HPA["HPA Controller"] -->|Custom Metrics API| CMA["Custom Metrics Adapter"]
HPA -->|External Metrics API| EMA["External Metrics Adapter"]
HPA -->|Resource Metrics API| MS["Metrics Server"]
CMA -->|实现| Adapter1["prometheus-adapter"]
EMA -->|实现| Adapter1
Adapter1 -->|查询| Prom["Prometheus"]
Prom -->|采集| App["Application
(Exporter)"]
APIService 扩展点:
| API | 用途 | 常见 Adapter |
|---|---|---|
metrics.k8s.io | Resource Metrics | Metrics Server |
custom.metrics.k8s.io | Custom Metrics(K8s 内资源指标) | prometheus-adapter |
external.metrics.k8s.io | External Metrics(K8s 外指标) | prometheus-adapter |
prometheus-adapter 部署:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
--set prometheus.url=http://kube-prometheus-stack-prometheus.monitoring.svc \
--set rules.default=false \
--set rules.custom[0].seriesQuery='http_requests_total{namespace!="",pod!=""}' \
--set rules.custom[0].resources.overrides.namespace.resource=namespace \
--set rules.custom[0].resources.overrides.pod.resource=pod \
--set rules.custom[0].name.matches='^(.*)_total$' \
--set rules.custom[0].name.as='${1}_per_second' \
--set rules.custom[0].metricsQuery='sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
Custom Metrics 查询规则配置:
# prometheus-adapter ConfigMap
rules:
# 自定义指标 1:HTTP QPS
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: { resource: "namespace" }
pod: { resource: "pod" }
name:
matches: "^(.*)_total$"
as: "${1}_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
# 自定义指标 2:P99 延迟
- seriesQuery: 'http_request_duration_seconds_bucket{namespace!="",pod!=""}'
resources:
overrides:
namespace: { resource: "namespace" }
pod: { resource: "pod" }
name:
matches: "^http_request_duration_seconds_bucket$"
as: "http_request_duration_seconds_p99"
metricsQuery: |
histogram_quantile(0.99,
sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (le, <<.GroupBy>>)
)
HPA 引用自定义指标:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa-custom
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 20
metrics:
# Custom Metrics:基于 Pod 维度
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1k"
# External Metrics:基于外部系统
- type: External
external:
metric:
name: rabbitmq_queue_messages_ready
selector:
matchLabels:
queue: orders
target:
type: AverageValue
averageValue: "100"
验证自定义指标:
# 1. APIService 状态
kubectl get apiservice | grep -E "custom.metrics|external.metrics"
# 2. Custom Metrics API
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_per_second
# 3. External Metrics API
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/default/rabbitmq_queue_messages_ready
自研 Adapter 要求:
如 prometheus-adapter 不满足需求,可基于 k8s.io/metrics 客户端库自研 Adapter:
- 实现
custom.metrics.k8s.ioProvider 接口 - 注册为 APIService(
custom.metrics.k8s.io/external.metrics.k8s.io) - 申请 front-proxy 客户端证书(kube-apiserver 转发时携带)
- 部署在 kube-system 命名空间,使用
system:auth-delegatorClusterRole
8 Metrics Server 生产实践中的常见问题与故障案例有哪些?
答案:
生产环境中 Metrics Server 故障直接影响 HPA 伸缩、kubectl top 查看、Scheduler 调度精度。常见问题集中在证书、数据新鲜度、网络、配置四类。
故障案例集锦:
| 故障现象 | 根因 | 解决方案 |
|---|---|---|
kubectl top node 返回空 / Error | kubelet 10250 自签证书校验失败 | 设置 --kubelet-insecure-tls=true 或签发 kubelet 证书 |
HPA unknown 状态 | Metrics API 未注册或 APIService 不可用 | 检查 kubectl get apiservice v1beta1.metrics.k8s.io |
| 数据延迟 > 5 分钟 | metric-resolution 过大 / kubelet 10250 阻塞 | 调小 resolution 至 15s、排查网络/防火墙 |
| Metrics Server 频繁 OOMKill | 单 Pod 处理 5000+ 节点 | 拆分集群或部署 v0.7+(性能优化) |
not able to fetch metrics 错误 | kubelet Summary API 调用超时 | 调大 --request-timeout、优化 kubelet 性能 |
| Windows 节点 metrics 缺失 | Summary API 在 Windows 不可用 | 通过 nodeSelector 排除 Windows 节点 |
| HPA 不扩容 | 未设置 resources.requests | Deployment 必须声明 resources.requests.cpu/memory |
典型故障排查流程:
# 1. 确认 Pod 状态
kubectl -n kube-system get pod -l k8s-app=metrics-server
kubectl -n kube-system logs -l k8s-app=metrics-server --tail=100
# 2. 确认 APIService 注册
kubectl get apiservice v1beta1.metrics.k8s.io
kubectl describe apiservice v1beta1.metrics.k8s.io
# 3. 直接查询 Metrics API
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
# 4. 验证 kubelet Summary API 可达性
kubectl -n kube-system exec -it metrics-server-pod -- \
curl -k https://<NodeIP>:10250/stats/summary
# 5. 抓包分析(深层次排查)
kubectl -n kube-system exec -it metrics-server-pod -- \
tcpdump -i any port 10250 -w /tmp/cap.pcap
kubelet 证书签发(生产推荐):
Metrics Server 启用 --kubelet-insecure-tls 仅为快速方案,生产应签发合法 kubelet 证书:
# 在 Master 节点生成 kubelet serving 证书 CSR
kubectl get csr
# 签发(kubelet 证书需包含 node IP / DNS SAN)
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=ca-config.json \
-hostname=<NodeIP>,<NodeDNS>,<NodeName> \
-profile=kubernetes \
kubelet-csr.json | cfssljson -bare kubelet
# 签发后移除 --kubelet-insecure-tls 参数
数据新鲜度与 HPA 同步:
# Metrics Server 配置
args:
- --metric-resolution=15s # 采集间隔
# HPA Controller 配置(kube-controller-manager)
--horizontal-pod-autoscaler-sync-period=15s
--horizontal-pod-autoscaler-tolerance=0.1
--horizontal-pod-autoscaler-cpuInitializationPeriod=5m
--horizontal-pod-autoscaler-initial-readiness-delay=30s
# 数据新鲜度必须 < sync-period,否则 HPA 报错
# 推荐:metric-resolution ≤ sync-period / 2
大规模集群优化(1000+ 节点):
1. 调高 Pod 资源限制
resources:
limits:
cpu: 1
memory: 1Gi
2. 调大 kubelet 并发与超时
<!-- --max-requests-per-second 参数不存在;metrics-server 使用 --kubelet-qps 控制 kubelet 并发 -->
--kubelet-qps=10 # 控制 kubelet 请求 QPS
3. 调优 APIService(kube-apiserver 侧)
--max-requests-inflight=2000
--max-mutating-requests-inflight=1000
4. 启用 ServiceMonitor(监控 Metrics Server 自身健康)
metrics_server_healthy = up{job="metrics-server"}
5. 监控告警:
- Metrics Server Pod OOMKill
- 采集耗时 > 10s
- 节点 metrics 缺失 > 1%
- APIService unavailable
生产 Checklist:
[ ] 1. 部署单实例 + PodDisruptionBudget
[ ] 2. 签发合法 kubelet 证书(禁用 insecure-tls)
[ ] 3. 设置 priorityClassName=system-cluster-critical
[ ] 4. 配置 resource.requests/limits
[ ] 5. 启用 ServiceMonitor + 告警规则
[ ] 6. metric-resolution 与 HPA sync-period 匹配
[ ] 7. 部署 prometheus-adapter 支持 Custom / External Metrics
[ ] 8. Windows 节点通过 nodeSelector 排除
[ ] 9. 验证 kubectl top node / pod 正常输出
[ ] 10. 定期演练:HPA 扩容链路全链路压测