跳转到内容

Metrics Server 面试题

8 道题
分类
可观测性
子分类
metrics
题目数
8 道
已阅读 0 / 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 Metricsmetrics.k8s.ioMetrics Serverv1beta1 → v1 (1.21+)
Custom Metricscustom.metrics.k8s.ioCustom Metrics Adapterv1beta1 → v1beta2
External Metricsexternal.metrics.k8s.ioExternal Metrics Adapterv1beta1 → 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 Serverkube-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 / VPAPrometheus + Grafana + Alertmanager
存储内存(不持久化)无状态(计算后丢弃)
部署数量单实例(HA 不支持)多实例(无状态,可水平扩展)
官方地址kubernetes-sigs/metrics-serverkubernetes/kube-state-metrics

指标对比:

Metrics Server 指标kube-state-metrics 指标
node_cpu_usage_seconds_totalkube_node_status_condition
node_memory_working_set_byteskube_node_info
pod_cpu_usage_seconds_totalkube_pod_status_phase
pod_memory_working_set_byteskube_pod_container_status_restarts_total
container_cpu_usage_seconds_totalkube_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 正常,需检查:

  1. APIService 是否 AVAILABLE(True)
  2. kube-apiserver 是否启用 --enable-aggregator-routing
  3. 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

生产部署关键点:

项目推荐值说明
replicas1单实例即可(无状态、内存聚合)
资源限制500m CPU / 512Mi1000 节点集群参考值
kubelet-insecure-tls生产环境尽量关闭改用 --tls-cert-file 校验
metric-resolution15s-30s与 HPA --horizontal-pod-autoscaler-sync-period 匹配
nodeSelector排除 Windows 节点仅 Linux 节点运行
priorityClassNamesystem-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.ioResource MetricsMetrics Server
custom.metrics.k8s.ioCustom Metrics(K8s 内资源指标)prometheus-adapter
external.metrics.k8s.ioExternal 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:

  1. 实现 custom.metrics.k8s.io Provider 接口
  2. 注册为 APIService(custom.metrics.k8s.io / external.metrics.k8s.io
  3. 申请 front-proxy 客户端证书(kube-apiserver 转发时携带)
  4. 部署在 kube-system 命名空间,使用 system:auth-delegator ClusterRole
8 Metrics Server 生产实践中的常见问题与故障案例有哪些?

答案:

生产环境中 Metrics Server 故障直接影响 HPA 伸缩、kubectl top 查看、Scheduler 调度精度。常见问题集中在证书、数据新鲜度、网络、配置四类。

故障案例集锦:

故障现象根因解决方案
kubectl top node 返回空 / Errorkubelet 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.requestsDeployment 必须声明 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 扩容链路全链路压测