写点什么

Kubernetes APIServer 可观测最佳实践

作者:观测云
  • 2025-04-02
    上海
  • 本文字数:3194 字

    阅读完需:约 10 分钟

Kubernetes APIServer 可观测最佳实践

简介

kube-apiserver 是 Kubernetes 控制平面组件之一,作为控制平面的前端负责向集群内外部提供 RestFul 接口,完成认证鉴权、Kubernetes 对象配置和持久化等功能。例如,常用于 Kubernetes 自动注入的 AdmissionControl 机制就在 kube-apiserver 中实现。在高可用 Kubernetes 集群中,kube-apiserver 通过负载均衡以多实例的方式提供服务,存在多种实例部署方式,主机守护进程、Static Pod、自托管 Pod、云托管 Pod 等。

kube-apiserver 的众多功能分布在不同的领域,例如 API 扩展、安全控制、自动化等,但从集群和组件稳定性保障的角度来看,只需要关注部分核心指标:QPS、错误率、延迟、限流情况和计算资源用量,这些指标对于任何 apiserver 都是适用的。Kubernetes 在设计上遵循 OpenMetric,这是一个在 Prometheus 格式基础上扩展和规范化的云原生指标事实标准,kube-apiserver 自然也使用此协议暴露指标,我们可以通过 kube-apiserver 的 metrics 端点获得指标。

具体到 kube-apiserver,它的核心指标中包含了丰富的业务标签,例如资源名、动词等,因此可以在以上通用核心指标的基础上进行一些扩展:请求失败或者延迟分布在对哪些资源的哪些操作之中?从核心指标告警到基于标签的分析再到确定问题的细节是我们推荐的工作流,为告警监控器关联分析仪表盘可以快速达成分析目的,后面我们会通过一个案例做说明。相较来说,为每个 API 的每个维度配置精确的监控检测反而会带来大量的噪声,当然,也存在一些例外情况,例如针对高频操作配置有限维度的监控检测等。除了以上提到的通用指标之外,还有一些特定指标会对 kube-apiserver 的性能产生影响,例如它的存储后端 Etcd 的请求延时情况,以及各类资源的数量,当某些资源的数量太大且存在频繁操作时可能会引起一些问题。

在 kube-apiserver 的众多问题中性能问题占有较大的比重,当性能出现问题时会触发 kube-apiserver 的自我保护机制:限流,因此在这里我们有必要简单说明下相关的原理,用来为问题分析提供一些支撑。Kubernetes 1.18 版本之后默认采用 APF(API Priority and Fairness)机制进行细粒度和公平的流量控制,避免了以往使用 --max-requests-inflight 和 --max-mutating-requests-inflight 参数整体控制容易导致大流量请求挤占其他请求的问题。APF 机制涉及两类资源:

  • Flowschemas,将对资源的操作映射到一个 PriorityLevelConfiguration;

  • PriorityLevelConfiguration,可以被多个 Flowschemas 关联,定义了不同优先级的并发资源限制;

它们都可以通过 kubectl get xxx 的方式查询。不同优先级的并发资源是隔离的,因此不会相互影响,相同优先级的请求从公平队列中分发,不同 Flowschemas 的请求也不会相互影响,但 APF 机制对长时间的请求是不生效的,例如 Watch。那在何时会触发限流呢?我们从 PriorityLevelConfiguration 的配置看,首先,spec.type 的值为 Limited,spec.limited.limitResponse.type 的值为 Reject 时,实际单位时间请求量超过该优先级 spec.limited.nominalConcurrencyShares 设定值时会被直接拒绝,spec.limited.limitResponse.type 的值为 Queue 时,超限制的请求会被排队,队列长度到达上限时才会被拒绝,一旦拒绝客户端就会收到 HTTP 429 响应码。

观测云

观测云采集器 DataKit 支持 Kubernetes Prometheus Discovery,能够根据标签自动匹配 Prometheus 指标端点并收集指标。

部署 DataKit

登录观测云控制台,点击「集成」-「DataKit」-「Kubernetes」,下载 datakit.yaml,拷贝第 3 步中 ENV_DATAWAY 键的值。



编辑 datakit.yaml,修改 DaemonSet 环境变量:

  • 修改 ENV_DATAWAY 的值为上一步中拷贝的值;

  • 修改 ENV_CLUSTER_NAME_K8S 的值为集群名称;

  • 新增 ENV_NAMESPACE,值为集群名称;

执行以下命令部署 Datakit 并验证:

kubectl apply -f datakit.yamlkubectl get pods -n datakit
复制代码

开启 Kubernetes Prometheus Discovery 插件

创建 Configmap 并挂载为 Datakit kubernetesprometheus 采集器的配置文件即可开启采集,插件通过角色、命名空间、标签自动发现采集端点。注意在 [inputs.kubernetesprometheus.instances.custom.tags] 中配置 Kubernetes 集群名作为指标标签,其他标签将根据配置自动取值。标签用于区分不同集群、实例、关联基础设施指标。插件配置举例如下:

apiVersion: v1kind: ConfigMapmetadata:  name: datakit-conf  namespace: datakitdata:  kube-apiserver.conf: |-    [inputs.kubernetesprometheus]        node_local = true        [[inputs.kubernetesprometheus.instances]]            role            = "pod"            namespaces      = ["kube-system"]            selector        = "component=kube-apiserver,tier=control-plane"            scrape          = "true"            scheme          = "https"            port            = "6443"            path            = "/metrics"            scrape_interval = "60s"            [inputs.kubernetesprometheus.instances.custom]                measurement        = "kube_apiserver"                job_as_measurement = false                [inputs.kubernetesprometheus.instances.custom.tags]                    cluster_name_k8s = "fill-your-cluster-name"                    instance         = "__kubernetes_mate_instance"                    pod_name         = "__kubernetes_pod_name"                    pod_namespace    = "__kubernetes_pod_namespace"                    node_name        = "__kubernetes_pod_node_name"            [inputs.kubernetesprometheus.instances.auth]                bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"                [inputs.kubernetesprometheus.instances.auth.tls_config]                    insecure_skip_verify = false                    ca_certs             = ["/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"]
复制代码

为 DataKit 挂载配置文件的方式如下:

apiVersion: apps/v1kind: DaemonSet...spec:  ...  template:    ...    spec:      ...      containers:        ...        volumeMounts:          ...          - name: datakit-conf-kube-apiserver            subPath: kube-apiserver.conf            mountPath: /usr/local/datakit/conf.d/kubernetesprometheus/kube-apiserver.conf      volumes:        ...        - name: datakit-conf-kube-apiserver          configMap:            name: datakit-conf-kube-apiserver
复制代码

完整配置请参考观测云文档:

监控视图

监控视图包含关键指标、概览、资源、QPS 和延时、工作队列、准入控制器和 Webhook、客户端,共 7 个部分,可针对动词和资源过滤。截图如下:





关键指标


Kubernetes 完整指标请参考 Kubernetes Metrics Reference

监控器

观测云已内置部分监控器:



克隆一个“Kube-APIServer 准入 Webhook Admit 耗时过高”监控器用于测试,设置阈值大于 0 即告警,然后删除一个使用 Datakit Operator 做自动注入的资源,这将触发对 Webhook 的调用,从而触发告警:



点击告警事件,在详情页中点击查看关联仪表盘,在准入控制器和 Webhook 部分可以看到告警由 mutation.datakit.svc 引发,它正是由 Datakit Operator 提供的:



总结

Kubernetes 作为云原生理念的核心项目,其自身组件内置指标导出能力,观测云全面支持 Prometheus 集成,并内置监控器和根因分析支持。在 Kubernetes 的稳定性保障实践中,对 kube-apiserver 的观测是至关重要的,它不但是控制面的前端,也是观测控制面的窗口。

用户头像

观测云

关注

还未添加个人签名 2021-02-08 加入

云时代的系统可观测平台

评论

发布
暂无评论
Kubernetes APIServer 可观测最佳实践_Kubernetes_观测云_InfoQ写作社区