search
数据采集 采集源配置 Kubernetes 监控指标采集

Kubernetes 监控指标采集

简介

采集 Kubernetes 集群指标上报到 DataFlux 中。kubernetes 集群指标采集,主要通过两个 input 插件完成:

  • kubernetes: 主要针对集群中 kubelet 的数据采集,即 node 节点相关性能
  • kube_inventory: 主要针对集群中 api-server 的数据采集,即集群、pod 相关性能

场景参考

kubernetes Overview 视图

内置视图

内置视图

kubernetes Node 内置视图

内置视图

内置视图

kubernetes Pod 内置视图

内置视图

Kubernetes视图模板下载

前置条件

kubernetes 采集器配置

进入 DataKit 安装目录下的 conf.d/k8s 目录,复制 kubernetes.conf.sample 并命名为 kubernetes.conf.sample。示例如下:

[[inputs.kubernetes]]
  ## URL for the kubelet
  url = "http://127.0.0.1:10255"

  ## Use bearer token for authorization. ('bearer_token' takes priority)
  ## If both of these are empty, we'll use the default serviceaccount:
  ## at: /run/secrets/kubernetes.io/serviceaccount/token
  # bearer_token = "/path/to/bearer/token"
  ## OR
  # bearer_token_string = "abc_123"

  ## Pod labels to be added as tags.  An empty array for both include and
  ## exclude will include all labels.
  # label_include = []
  # label_exclude = ["*"]

  ## Set response_timeout (default 5 seconds)
  # response_timeout = "5s"

  ## Optional TLS Config
  # tls_ca = /path/to/cafile
  # tls_cert = /path/to/certfile
  # tls_key = /path/to/keyfile
  ## Use TLS but skip chain & host verification
  # insecure_skip_verify = false

配置好后, 重启 DataKit 即可生效

kube_inventory 采集器配置

进入 DataKit 安装目录下的 conf.d/k8s 目录,复制 kube_inventory.conf.sample 并命名为 kube_inventory.conf。示例如下:

[[inputs.kube_inventory]]
  ## URL for the Kubernetes API
  url = "https://127.0.0.1"

  ## Namespace to use. Set to "" to use all namespaces.
  # namespace = "default"

  ## Use bearer token for authorization. ('bearer_token' takes priority)
  ## If both of these are empty, we'll use the default serviceaccount:
  ## at: /run/secrets/kubernetes.io/serviceaccount/token
  # bearer_token = "/path/to/bearer/token"
  ## OR
  # bearer_token_string = "abc_123"

  ## Set response_timeout (default 5 seconds)
  # response_timeout = "5s"

  ## Optional Resources to exclude from gathering
  ## Leave them with blank with try to gather everything available.
  ## Values can be - "daemonsets", deployments", "endpoints", "ingress", "nodes",
  ## "persistentvolumes", "persistentvolumeclaims", "pods", "services", "statefulsets"
  # resource_exclude = [ "deployments", "nodes", "statefulsets" ]

  ## Optional Resources to include when gathering
  ## Overrides resource_exclude if both set.
  # resource_include = [ "deployments", "nodes", "statefulsets" ]

  ## selectors to include and exclude as tags.  Globs accepted.
  ## Note that an empty array for both will include all selectors as tags
  ## selector_exclude overrides selector_include if both set.
  selector_include = []
  selector_exclude = ["*"]

  ## Optional TLS Config
  # tls_ca = "/path/to/cafile"
  # tls_cert = "/path/to/certfile"
  # tls_key = "/path/to/keyfile"
  ## Use TLS but skip chain & host verification
  # insecure_skip_verify = false

  ## Uncomment to remove deprecated metrics.
  # fielddrop = ["terminated_reason"]

配置好后, 重启 DataKit 即可生效

Troubleshooting

  1. kube_inventory.conf采集器配置后,可能会出现以下报错:
    /run/secrets/kubernetes.io/serviceaccount/token: no such file or directory
    

执行如下两两条命令即可解决:

mkdir -p /run/secrets/kubernetes.io/serviceaccount

touch /run/secrets/kubernetes.io/serviceaccount/token
  1. kube_inventory.conf采集器配置后,可能会出现以下报错:
error making HTTP request to http://<k8s-host>/stats/summary: dial tcp <k8s-hosst>:10255: connect: connect refused

按如下方式调整 k8s 配置:

1. 编辑所有节点的 `/var/lib/kubelet/config.yaml` 文件,加入`readOnlyPort` 这个参数:`readOnlyPort: 10255`

2. 重启kubelet 服务:`systemctl restart kubelet.service`

Kubernetes Permissions

如果使用 RBAC 授权, 则需要创建一个集群角色以列出 persistentvolumesnodes。然后, 需要创建一个聚合的 ClusterRole, 它最终将绑定到用户或组。

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: influx:cluster:viewer
  labels:
    rbac.authorization.k8s.io/aggregate-view-telegraf: "true"
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes", "nodes"]
    verbs: ["get", "list"]

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: influx:telegraf
aggregationRule:
  clusterRoleSelectors:
    - matchLabels:
        rbac.authorization.k8s.io/aggregate-view-telegraf: "true"
    - matchLabels:
        rbac.authorization.k8s.io/aggregate-to-view: "true"
rules: [] # Rules are automatically filled in by the controller manager.

将新创建的聚合ClusterRole与以下配置文件绑定, 并根据需要更新主题。

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: influx:telegraf:viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: influx:telegraf
subjects:
  - kind: ServiceAccount
    name: telegraf
    namespace: default

指标集 kubernetes_daemonset

标签 描述
daemonset_name
namespace
指标 描述 类型
generation
current_number_scheduled
desired_number_scheduled
number_available
number_misscheduled
number_ready
number_unavailable
updated_number_scheduled

指标集 kubernetes_deployment

标签 描述
deployment_name
namespace
指标 描述 类型
replicas_available
replicas_unavailable
created

指标集 kubernetes_endpoints

标签 描述
endpoint_name
namespace
hostname
node_name
port_name
port_protocol
kind
指标 描述 类型
created
generation
ready
port

指标集 kubernetes_ingress

标签 描述
ingress_name
namespace
hostname
ip
backend_service_name
path
host
指标 描述 类型
created
generation
backend_service_port
tls

指标集 kubernetes_node

标签 描述
node_name
指标 描述 类型
capacity_cpu_cores
capacity_memory_bytes
capacity_pods
allocatable_cpu_cores
allocatable_memory_bytes
allocatable_pods

指标集 kubernetes_persistentvolume

标签 描述
pv_name
phase
storageclass
指标 描述 类型
phase_type

指标集 kubernetes_persistentvolumeclaim

标签 描述
pvc_name
namespace
phase
storageclass
指标 描述 类型
phase_type

指标集 kubernetes_pod_container

标签 描述
container_name
namespace
node_name
pod_name
指标 描述 类型
restarts_total
state
terminated_reason
resource_requests_cpu_units
resource_requests_memory_bytes
resource_limits_cpu_units
resource_limits_memory_bytes

指标集 kubernetes_service

标签 描述
service_name
namespace
port_name
port_protocol
external_name
cluster_ip
指标 描述 类型
created
generation
port
target_port

指标集 kubernetes_statefulset

标签 描述
statefulset_name
namespace
指标 描述 类型
created
generation
replicas
replicas_current
replicas_ready
replicas_updated
spec_replicas

指标集 kubernetes_node

标签 描述
node_name
指标 描述 类型
cpu_usage_nanocores
cpu_usage_core_nanoseconds
memory_available_bytes
memory_usage_bytes
memory_working_set_bytes
memory_rss_bytes
memory_page_faults
memory_major_page_faults
network_rx_bytes
network_rx_errors
network_tx_bytes
network_tx_errors
fs_available_bytes
fs_capacity_bytes
fs_used_bytes
runtime_image_fs_available_bytes
runtime_image_fs_capacity_bytes
runtime_image_fs_used_bytes

指标集 kubernetes_pod_container

标签 描述
container_name
namespace
node_name
pod_name
指标 描述 类型
cpu_usage_nanocores
cpu_usage_core_nanoseconds
memory_usage_bytes
memory_working_set_bytes
memory_rss_bytes
memory_page_faults
memory_major_page_faults
rootfs_available_bytes
rootfs_capacity_bytes
rootfs_used_bytes
logsfs_avaialble_bytes
logsfs_capacity_bytes
logsfs_used_bytes

指标集 kubernetes_pod_volume

标签 描述
volume_name
namespace
node_name
pod_name
指标 描述 类型
available_bytes
capacity_bytes
used_bytes

指标集 kubernetes_pod_network

标签 描述
namespace
node_name
pod_name
指标 描述 类型
rx_bytes
rx_errors
tx_bytes
tx_errors

采集器示例数据

kubernetes_pod_container,container_name=deis-controller,namespace=deis,node_name=ip-10-0-0-0.ec2.internal,pod_name=deis-controller-3058870187-xazsr cpu_usage_core_nanoseconds=2432835i,cpu_usage_nanocores=0i,logsfs_available_bytes=121128271872i,logsfs_capacity_bytes=153567944704i,logsfs_used_bytes=20787200i,memory_major_page_faults=0i,memory_page_faults=175i,memory_rss_bytes=0i,memory_usage_bytes=0i,memory_working_set_bytes=0i,rootfs_available_bytes=121128271872i,rootfs_capacity_bytes=153567944704i,rootfs_used_bytes=1110016i 1476477530000000000
kubernetes_pod_network,namespace=deis,node_name=ip-10-0-0-0.ec2.internal,pod_name=deis-controller-3058870187-xazsr rx_bytes=120671099i,rx_errors=0i,tx_bytes=102451983i,tx_errors=0i 1476477530000000000
kubernetes_pod_volume,volume_name=default-token-f7wts,namespace=default,node_name=ip-172-17-0-1.internal,pod_name=storage-7 available_bytes=8415240192i,capacity_bytes=8415252480i,used_bytes=12288i 1546910783000000000
kubernetes_configmap,configmap_name=envoy-config,namespace=default,resource_version=56593031 created=1544103867000000000i 1547597616000000000
kubernetes_daemonset,daemonset_name=telegraf,selector_select1=s1,namespace=logging number_unavailable=0i,desired_number_scheduled=11i,number_available=11i,number_misscheduled=8i,number_ready=11i,updated_number_scheduled=11i,created=1527758699000000000i,generation=16i,current_number_scheduled=11i 1547597616000000000
kubernetes_deployment,deployment_name=deployd,selector_select1=s1,namespace=default replicas_unavailable=0i,created=1544103082000000000i,replicas_available=1i 1547597616000000000
kubernetes_node,node_name=ip-172-17-0-2.internal allocatable_pods=110i,capacity_memory_bytes=128837533696,capacity_pods=110i,capacity_cpu_cores=16i,allocatable_cpu_cores=16i,allocatable_memory_bytes=128732676096 1547597616000000000
kubernetes_persistentvolume,phase=Released,pv_name=pvc-aaaaaaaa-bbbb-cccc-1111-222222222222,storageclass=ebs-1-retain phase_type=3i 1547597616000000000
kubernetes_persistentvolumeclaim,namespace=default,phase=Bound,pvc_name=data-etcd-0,selector_select1=s1,storageclass=ebs-1-retain phase_type=0i 1547597615000000000
kubernetes_pod,namespace=default,node_name=ip-172-17-0-2.internal,pod_name=tick1 last_transition_time=1547578322000000000i,ready="false" 1547597616000000000
kubernetes_service,cluster_ip=172.29.61.80,namespace=redis-cache-0001,port_name=redis,port_protocol=TCP,selector_app=myapp,selector_io.kompose.service=redis,selector_role=slave,service_name=redis-slave created=1588690034000000000i,generation=0i,port=6379i,target_port=0i 1547597616000000000
kubernetes_pod_container,container_name=telegraf,namespace=default,node_name=ip-172-17-0-2.internal,node_selector_node-role.kubernetes.io/compute=true,pod_name=tick1,state=running,readiness=ready resource_requests_cpu_units=0.1,resource_limits_memory_bytes=524288000,resource_limits_cpu_units=0.5,restarts_total=0i,state_code=0i,state_reason="",resource_requests_memory_bytes=524288000 1547597616000000000
kubernetes_statefulset,namespace=default,selector_select1=s1,statefulset_name=etcd replicas_updated=3i,spec_replicas=3i,observed_generation=1i,created=1544101669000000000i,generation=1i,replicas=3i,replicas_current=3i,replicas_ready=3i 1547597616000000000

Kubernetes监控最佳实践

Kubernetes对容器的作用

由于容器比传统的虚拟化更加高效,快速和轻便,因此大型应用程序部署企业在实际业务场景中通常会将多个容器部署为一个或多个容器集。

但是,由于大型的分布式容器化应用程序通常难以协调,因此该环境面临着一系列挑战。Kubernetes是一个开源容器编排工具,可跨主机群集自动执行应用程序容器的部署,扩展和操作。Kubernetes与Docker一起使用是最常用的场景。

Kubernetes的工作方式

Kubernetes提供了一个框架来运行弹性的分布式系统。部署后,您将获得一个Kubernetes集群——一组运行Kubernees管理的容器化应用程序的机器或节点。集群至少具有一个:

  • 承载Pod的辅助节点。(每个pod是一组一个或多个容器。)
  • 主节点,用于管理集群中的工作节点和Pod。

Kubernetes监控涉及什么?

Kubernetes可以极大地简化容器内和跨云的应用程序部署,但是却带来了自己的复杂性。

监控大型,复杂的系统面临两个主要挑战:正在监控的组件数量庞大,以及需要对运维人员保持“合理的低维护的工作量”。这些要求需要一个监控系统,该系统不仅可以发出有关高级服务目标的警报,还可以检查单个组件。

要监控Kubernetes集群中的应用程序性能,检查容器,容器和服务的性能以及整个集群的特性至关重要。通过提供有关应用程序资源使用情况的信息,Kubernetes允许您评估应用程序性能以检测和消除瓶颈。

Kubernetes组成部分:要监控的内容及指标

Kubernetes集群架构包括一个主节点和从属的Node节点。

  1. 主节点的主要组件包括:
  • etcd:存储配置信息,集群中的每个节点均可使用。
  • API server(kube-apiserver):验证和配置API对象(例如Pod,服务,复制控制器等)的数据。
  • Scheduler(kube-scheduler):管理工作负载利用率以及将pod分配到可用节点。
  • kube-controller-manager:一个守护程序,负责收集信息并将其发送到API服务器。
  • cloud-controller-manager:运行与云供应商进行交互的控制器。
  1. Kubernotes Node节点组件包括:
  • 容器运行时(例如,Docker)
  • kubelet:主要节点代理,通过API服务器监控pod规范;它还在Kubernetes集群中注册了一个节点并报告事件,pod状态和资源利用率。
  • Kubernetes代理(kube-proxy):在每个节点上运行的代理服务,有助于使服务对外部主机可用。

根据Kubernetes.io,应该密切跟踪Kubernetes指标的几种关键类型:

  • 运行Pod及其部署
  • 资源指标,包括CPU,内存使用情况和磁盘I/O
  • 容器原生指标
  • 应用指标

Kubernetes有很多好处,但也增加了复杂性。例如,其要在多个数据中心甚至不同的云供应商之间分布容器化应用程序的能力,就需要一种全面的监控解决方案来跨多个不同来源收集和汇总指标。DataFlux的

一、资源和利用率指标

资源和利用率指标来自通过Kubernetes的metrics API进行获取,由Kubelets本身提供。大多数时候,我们仅将CPU使用情况用作健康状况的指标,但是监视内存使用情况和网络流量也很重要。

推荐观测指标

指标 名称 描述
CPU使用率 cpu_usage_nanocores 节点或Pod每秒使用的CPU核数。
CPU容量 capacity_cpu 节点上可用的CPU内核数量(不适用于Pod)。
内存使用情况 used(resource:memory,units:bytes) 节点或Pod使用的内存量(以字节为单位)。
内存容量 capacity_memory(units:bytes) 节点可用的内存容量(不适用于Pod),以字节为单位。
网络流量 rx{resource:network,units:bytes},tx{resource:network,units:bytes} 节点(或Pod)看到的总网络流量(已接收(传入)流量和已传输(传出)流量),以字节为单位。

CPU使用率是重要的健康状况指标:作为运维IT人员应该跟踪Node正在使用多少CPU。原因有两个:

  1. 我们不希望耗尽应用程序的处理资源,如果应用程序受到CPU的限制,则需要增加CPU分配或向集群添加更多节点。
  2. 我们不希望CPU闲置在那里。

二、状态指标

Kubernetes中可提供有关集群对象状态的数据主要有node,pod,DaemonSet,namespaces等。

指标 名称 描述
节点状态 kube_node_status_condition {status:true,condition:OutOfDisk, MemoryPressure,PIDPressure, DiskPressure,NetworkUnavailable} 当status为true时,指示该节点当前正在经历该条件。
循环崩溃(Crash Loops) kube_pod_container_status_waiting_reason {reason:CrashLoopBackOff} 指示pod中的容器是否正在发生循环崩溃。
任务状态(失败) kube_job_status_failed 指示任务是否失败。
持久卷状态(失败) kube_persistentvolume_status _phase {phase:Failed} 指示持久卷是否失败。
Pod状态(Pending) kube_pod_status_phase{phase:Pending} 指示Pod是否处于挂起状态。
Deployment kube_deployment_metadata _generation 代表Deployment的序列号。
Deployment kube_deployment_status_observed_generation 代表控制器观察到的当前Deployment生成的序列号。
DaemonSet期望的节点数 kube_daemonset_status_ desired_number_scheduled DaemonSet期望的节点数。
DaemonSet当前的节点数 kube_daemonset_status_ current_number_scheduled DaemonSet运行中的节点数。
期望的StatefulSet副本 kube_statefulset_status_replicas 每个StatefulSet期望的副本数。
准备就绪的StatefulSet副本 kube_statefulset_status_replicas _ready 每个StatefulSet准备好的副本数。

使用这些度量标准,可以对以下指标监视并发出警报:

  • 崩溃循环
  • 磁盘压力
  • 内存压力
  • PID压力
  • 网络不可用
  • 任务失败
  • 持久卷失败
  • Pod挂起
  • Deployment故障
  • DaemonSets未准备好
  • StatefulSets未准备好

三、控制平面指标

Kubernetes控制平面包含Kubernetes的“系统组件”,可以帮助进行集群管理。在云提供商提供的托管环境中,控制平面由云提供商管理,通常不必担心监视这些指标。但是,如果kubernetes集群是自建的,则需要了解如何监视控制平面。

指标 名称 描述
etcd leader etcd_server_has_leader 指示该成员是否知道其leader是谁。
etcd leader 变动 etcd_server_leader_changes_ seen_total etcd集群中leader变更总数。
API延迟数 apiserver_request_latencies_count API请求总数;用于计算每个请求的平均延迟。
API延迟总和 apiserver_request_latencies_sum 所有API请求持续时间的总和;用于计算每个请求的平均延迟。
队列等待时间 workqueue_queue_duration_ seconds 每个控制器管理器中的工作队列等待所花费的总时间。
队列持续时间 workqueue_work_duration_ seconds 每个控制器管理器中的工作队列处理操作所花费的总时间。
调度失败Pod的总尝试次数 scheduler_schedule_attempts _total {result:unschedulable} 调度程序尝试在节点上调度失败了Pod的总尝试次数。
Pod调度延迟 scheduler_e2e_scheduling_ delay_microseconds(<v1.14) 或 scheduler_e2e_scheduling_ duration_seconds 将Pod调度到节点上所花费的总时间。

四、控制平面健康状况

对于自建kubernetes集群,我们通常建议监视控制平面上的以下健康状况:

etcd集群中是否有leader

etcd集群应始终有一个leader(在更改leader的过程中除外,这种情况很少见)。我们应该密切注意所有etcd_server_has_leader指标,因为如果很多集群成员没有leader,那么集群性能将会下降。 另外,如果在etcd_server_leader_changes_seen_total中看到leader变更很多次,则可能表明etcd集群存在连接性或资源问题。

API请求延迟

如果将apiserver_request_latencies_count划分为apiserver_request_latencies_sum,则将获得API服务器每个请求的平均延迟。跟踪随时间不断变化的平均请求延迟可以让你知道服务器何时不堪重负。

工作队列延迟

工作队列是由controller manager管理的队列,用于处理集群中的所有自动化流程。监视workqueue_queue_duration_seconds的增加,将使你知道队列延迟何时增加。如果发生这种情况,可能需要深入研究controller manager日志以查看发生了什么。

调度程序问题

调度程序有两个方面值得关注。首先,应该监视scheduler_schedule_attempts_total {result:unschedulable},因为无法调度的Pod的增加可能意味着你的集群存在资源问题。其次,应该使用上面指示的延迟指标之一来监视调度程序延迟。Pod调度延迟的增加可能会导致其他问题,也可能表明集群中存在资源问题。

五、事件

除了从Kubernetes集群中收集数值指标外,从集群中收集和跟踪事件也很有用。集群事件可以帮助监视Pod生命周期并观察重大Pod故障,并且监视从集群流出的事件的速率可以是一个很好的预警指标。如果事件发生率突然显着变化,则可能表明发生了问题。

六、应用程序指标

与我们上面检查的指标和事件不同,应用程序指标不是从Kubernetes本身发出的,而是从集群运行的工作负载发出的。从应用程序的角度来看,这种监控可以是你认为重要的任何事情:错误响应,请求延迟,处理时间等。

关于如何收集应用程序度量标准,有两种方式。

  • 第一个是,应该将指标数据从应用程序“推送”到收集端点。这意味着必须将像StatsD这样的客户端与每个应用程序捆绑在一起,以提供一种将指标标准数据推出该应用程序的机制。该技术需要更多的管理开销,以确保正确地检测集群中运行的每个应用程序,因此它在集群管理器中不受欢迎。
  • 第二种是,指标收集原理(正在被越来越广泛地采用),指标应由收集代理从应用程序中“拉取”。这使应用程序更易于编写,因为它们所要做的只是适当地发布了它们的指标标准,但是应用程序不必担心这些度量标准是如何被提取或删除的。这是OpenMetrics的工作方式,也是Kubernetes集群指标收集的方式。当此技术与收集代理的服务发现相结合时,它将创建一种功能强大的方法,用于从集群应用程序中收集你需要的任何类型的指标。