Kubernetes 监控

Jun 20, 2021 15:30 · 2509 words · 6 minute read Kubernetes

kubernetes

监控任何应用程序,都要能回答上两个问题:正在发生什么?为什么会发生这个?从应用程序中获取数据来定位这些问题,可以确保迅速发现问题并采取应对措施。这些数据以两种形式呈现:计量指标和日志。

时间序列的计量指标告诉我们正在发生什么,比如当前系统的负载或资源消耗。就像飞机上的各种仪表,为我们提供对系统当前状态数据化的展示,有时也是问题发生的警告信号。

日志告诉我们状况发生的原因,提供了应用程序中事件发生的记录。它们可以是信息性的,提供了应用程序作业的上下文;也可以是错误性的,表明为什么出问题。日志就像机械师插入诊断工具后的结果,确定为什么检查引擎的灯亮了。

监控的类型

  • 资源监控

    CPU、内存、网络等资源类的指标

  • 性能监控

    应用的内部监控,通常是通过 Hook 的机制在虚拟机层、字节码执行层隐式回调,或者在应用层显式注入,获取更深层的监控指标,常用来应用诊断与调优。

  • 安全监控

    针对安全进行的一系列监控策略,例如越权管理、安全漏洞扫码

  • 事件监控

    Kubernetes 中一种另类的监控方式,紧密贴合 Kubernetes 的设计理念,补充常规监控方案的缺欠与弊端。

通用计量指标

Kubernetes 是用 Golang 写的,有一些关于 Go 运行时的基本指标,它们对于关注 Go 程序中正在发生的事情是必要的;还有 etcd 方面的关键指标,多个组件与 etcd 交互,关注这些交互可以了解到 etcd 潜在的问题。下面是大多数 Kubernetes 组件暴露出来的一些顶级 Golang 数据和常见的 etcd 指标:

计量指标 组件 描述
go_gc_duration_seconds 所有 GC 持续时间摘要
go_threads 所有 创建的 OS 线程数量
go_goroutines 所有 当前存在的 goroutine 数量
etcd_helper_cache_hit_count API Server
Controller Manager
etcd 缓存命中计数
etcd_helper_cache_miss_count API Server
Controller Manager
etcd 缓存未命中计数
etcd_request_cache_add_latencies_summary API Server
Controller Manager
向 etcd 缓存添加对象的延迟
etcd_request_cache_get_latencies_summary API Server
Controller Manager
从 etcd 缓存获取对象的延迟
etcd_request_latencies_summary API Server
Controller Manager
etcd 每次操作的请求延迟

Kubernetes 控制面

控制面是驱动 Kubernetes 的引擎,由多个组件构成。每个组件都有特定的功能并暴露出自己的计量指标,以监测它的健康状况。

API Server

API Server 为 Kubernetes 集群提供前端,是所有组件交互的中心点。

计量指标 描述
apiserver_request_count API Server 请求计数
apiserver_request_latencies 响应延迟(微秒级)

etcd

etcd 是 Kubernetes 的数据后端,是一个强一致性且高可用的键值存储,容纳 Kubernetes 集群所有数据。

计量指标 描述
etcd_server_has_leader 1 表示存在领袖,反之则是 0
etcd_server_leader_changes_seen_total 领袖变更次数量
etcd_server_proposals_applied_total 已落实的提议数量
etcd_server_proposals_committed_total 已提交的提议数量
etcd_server_proposals_pending 待决的提议数量
etcd_server_proposals_failed_total 失败的提议数量
etcd_debugging_mvcc_db_total_size_in_bytes 压缩后的数据库真实大小
etcd_disk_backend_commit_duration_seconds 后端提交的延迟
etcd_disk_wal_fsync_duration_seconds WAL 落盘的延迟
etcd_network_client_grpc_received_bytes_total gRPC 客户端接收的字节总数
etcd_network_client_grpc_sent_bytes_total gRPC 客户端发送的字节总数
grpc_server_started_total 服务器发起的 gRPC 总数
grpc_server_handled_total 服务器处理的 gRPC 总数

Scheduler(调度器)

调度器观察 Kubernetes 中新创建的 Pod,并决定这些 Pod 在哪个节点上运行。它根据现有的数据来决策,包括集群资源的可用性和 Pod 本身的资源需求。

计量指标 描述
scheduler_e2e_scheduling_latency_microseconds 端到端调度延迟,是调度 & 绑定的延迟之和

Controller Manager

Controller Manager 是通过控制循环将集群调谐至理想状态的守护进程。它会监视 API Server 并根据当前状态与理想状态的差距采取措施。下面这些计量指标仅对 AWS、GCE 和 OpenStack 这些云商可用。

计量指标 描述
cloudprovider_*_api_request_duration_seconds 云商的 API 调用延迟
cloudprovider_*_api_request_errors 云商 API 请求错误

Kube State Metrics

Kube State Metrics 是一个提供 Kubernetes 状态的插件。它会监视 Kubernetes API 并生成各种计量指标,我们就能知道当前正在跑什么。几乎所有的 Kubernetes 资源都会产生计量数据(Pod、Deployment、DaemonSet 和 Node)。

计量指标 描述
kube_pod_status_phase Pod 当前所处的阶段
kube_pod_container_resource_limits_cpu_cores 容器可使用的 CPU 核心数量限制
kube_pod_container_resource_limits_memory_bytes 容器可使用的内存大小限制
kube_pod_container_resource_requests_cpu_cores 容器所要求的 CPU 核心数量
kube_pod_container_resource_requests_memory_bytes 容器所要求的内存大小
kube_pod_container_status_ready 1 表示容器已就绪,反之不然
kube_pod_container_status_restarts_total 容器重启总次数
kube_pod_container_status_terminated_reason 容器处于终止状态的原因
kube_daemonset_status_desired_number_scheduled 应当运行 Pod 的节点数量
kube_daemonset_status_number_unavailable 应当但并没有运行 Pod 的节点数量
kube_deployment_spec_replicas Deployment 期望的 Pod 副本数量
kube_deployment_status_replicas_unavailable Deployment 不可用的 Pod 副本数量
kube_node_spec_unschedulable 某个节点是否可以调度新的 Pod
kube_node_status_capacity_cpu_cores 节点上可用的 CPU 核心数
kube_node_status_capacity_memory_bytes 节点上可用的内存大小
kube_node_status_capacity_pods 节点可调度的 Pod 数量
kube_node_status_condition 节点当前状态

节点组件

Kubelet

我们还要密切关注 Kubelet,确保控制面始终能够与运行 Kubelet 的节点进行通讯。除了通用的 Go 运行时计量指标,Kubelet 还暴露了一些内部的行为,很适合追踪。

计量指标 描述
kubelet_running_container_count 当前运行的容器数量
kubelet_runtime_operations 不同操作类型提供的运行时操作累计数量
kubelet_runtime_operations_latency_microseconds 按类型划分的每个操作的延迟(毫秒级)

节点资源计量指标

检测集群中每个节点的健康状况,避免因节点问题导致的宕机,我们需要看到节点的方方面面,包括 CPU 和内存消耗、系统负载、文件系统和网络活动。

容器资源计量指标

对所有 Kubernetes 计量指标的监控只是拼图的一部分,我们还要保持对 Kubernetes 正在编排的容器化应用程序的可见性。最起码也要知道这些容器的资源消耗。Kubelet 从 cAdvisor 访问容器计量数据,这是一个可以分析容器的资源使用情况的工具,和节点资源计量指标差不多:CPU、内存、文件系统和网络。

Kubernetes 的监控接口标准

通过 API Server Aggregated API 注册了三种不同的 metrics 接口,将监控的消费能力进行标准化和解耦。

API 注释
Resource Metrics metrics.k8s.io 主要的实现为 Metrics-Server 提供资源监控
Custom Metrics custom.metrics.k8s.io 主要的实现为 Prometheus 提供资源监控和自定义监控
External Metrics external.metrics.k8s.io 主要的实现为云商的 Provider 提供云资源的监控指标

计量指标采集方案

Kubernetes 各组件都以 Prometheus 数据格式暴露计量指标,通过 HTTP 服务将计量指标以 URL 给出。标准规定服务以 /metrics 路径来访问。只需要抓取不同服务的相同路径即可获取这些指标。

日志

Kubernetes 为其每个组件提供了大量日志,使得我们能够深入了解对应组件正在进行的决策。我们的容器化应用程序也在生成日志,提供详细的信息。对这些日志的访问确保我们可以监控和排除应用程序故障。

  • 主机内核的日志

    • 可以协助开发者诊断例如
    • 网络栈异常
    • 驱动异常
    • 文件系统异常
    • 影响节点稳定的异常
  • Runtime 的日志

    最常见的运行时是 Docker,通过 Docker 的日志排查例如删除 Pod Hang 等问题

  • 核心组件的日志

    • APIServer 日志可以用来审计
    • Scheduler 日志可以诊断调度
    • etcd 日志可以查看存储状态
    • Ingress 日志可以分析接入层流量
  • 部署应用的日志

    通过应用日志分析业务层的状态,诊断异常(500请求)

日志的采集

当容器在 Kubernetes 集群中运行,其产生的日志文件将被写入容器所在节点的磁盘,所以每个节点上都有在本节点上运行的所有容器的日志。

  1. 宿主机文件

    容器内通过挂载卷将日志写在宿主机中,通过宿主机日志轮转的策略进行日志的轮转,再通过宿主机上的代理进行采集

  2. 容器内文件

    通过 SideCar Streaming 容器转写到 stdout,再写到相应的日志文件,通过本地的轮转和外部的代理进行采集

  3. 容器标准/错误输出

    直接写到 stdout

日志采集方案

在每个节点以 DaemonSet 上起一个 fluentd 进程,将数据汇集到 Fluentd Server,再将数据离线到相应的例如 ElasticSearch(Kibana 作为展现)或 influxdb(grafana 作为展现)数据库中。