# Prometheus 监控 k8s 集群节点、容器资源

https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config

# 前言

对于K8s集群的监控一般我们需要考虑以下几个方面:

  • Kubernetes 节点的监控:比如节点的 cpu、load、disk、memory 等指标
  • 内部系统组件的状态:比如 kube-scheduler、kube-controller-manager、kubedns/coredns 等组件的详细运行状态
  • 编排级的 metrics:比如 Deployment 的状态、资源请求、调度和 API 延迟等数据指标

Kubernetes 集群的监控方案目前主要有以下几种方案:

  • cAdvisor(Container Advisor)是由 Google 开发的一个开源工具,用于自动收集、处理和导出运行在 Linux 系统上的容器的性能指标。它是 Kubernetes 中的一个核心组件,广泛用于监控容器化应用程序的资源使用情况。
  • Kubernetes Metrics Server 是 Kubernetes 生态系统中的一个轻量级指标收集工具,专门用于在集群内部收集资源使用数据。它是 Kubernetes 控制面板中用于资源监控的核心组件之一。
  • kube-state-metrics 是一个开源项目,用于在 Kubernetes 集群中导出集群对象的状态指标。与监控集群节点和容器的资源使用情况的 metrics-server 不同,kube-state-metrics 专注于 Kubernetes API 对象的状态,而不是节点和容器资源消耗。

# 部署node_exporter

市面上有很多成熟的节点监控方案,常见的如zabbix、prometheus+node_exporter,这里通过daemonset方式部署node_exporter来采集k8s集群节点的数据

cat > node_exporter.yaml << EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitor
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
      name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: quay.io/prometheus/node-exporter:v1.9.1
        ports:
        - containerPort: 19100
        resources:
          requests:
            cpu: 0.15
        securityContext:
          privileged: true
        args:
        - --web.listen-address=:19100
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --collector.filesystem.ignored-mount-points
        - '"^/(sys|proc|dev|host|etc)($|/)"'
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/control-plane"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

EOF

# 配置prometheus监控k8s节点

Prometheus 使用 kubernetes_sd_configs 允许 Prometheus 自动发现 Kubernetes 集群中的服务、节点、Pod 以及其他资源,并从中抓取监控指标。主要支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。

# prometheus安装在k8s集群外

Kubernetes 在 v1.22 版本之前自动创建用来访问 Kubernetes API 的长期凭据。 这一较老的机制是基于创建令牌 Secret 对象来实现的,Secret 对象可被挂载到运行中的 Pod 内。 在最近的版本中,包括 Kubernetes v1.32,API 凭据可以直接使用 TokenRequest API 来获得,并使用一个投射卷挂载到 Pod 中。使用此方法获得的令牌具有受限的生命期长度,并且能够在挂载它们的 Pod 被删除时自动被废弃。

你仍然可以通过手动方式来创建服务账号令牌 Secret 对象,例如你需要一个永远不过期的令牌时。 不过,使用 TokenRequest 子资源来获得访问 API 的令牌的做法仍然是推荐的方式。

当 Prometheus 部署在 Kubernetes 集群外部,并希望使用 Kubernetes 服务发现特性(kubernetes_sd_configs),以便抓取集群内的节点或服务信息时,需要正确配置访问 Kubernetes API Server 的连接地址和认证信息。 因为在集群外部,Prometheus 无法通过集群内部的 DNS 名称 kubernetes.default.svc 访问 API Server。 同时,还需要提供访问 Kubernetes API Server 所需的认证信息,例如 Bearer Token 或 TLS 证书。

  • 准备Bearer Token,用于API Server认证
kubectl create ns monitor
kubectl -n monitor create sa prometheus

# 自定义集群角色
kubectl create clusterrole prometheus --verb=get,list,watch --resource=nodes,nodes/proxy,services,endpoints,pods

# 创建集群角色绑定
kubectl create clusterrolebinding prometheus --clusterrole prometheus --serviceaccount monitor:prometheus

# 手动为 ServiceAccount 创建长期有效的 API 令牌
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: prometheus
  namespace: monitor
  annotations:
    kubernetes.io/service-account.name: prometheus
type: kubernetes.io/service-account-token
EOF

# 从secret中提取token字段并base64解码,并写入k8s-sa-prometheus.token文件
kubectl -n monitor get secret prometheus -o jsonpath="{.data.token}" |base64 -d |tee k8s-sa-prometheus.token
# 从secret中提取ca.crt字段并base64解码,并写入k8s-sa-prometheus.ca.crt文件
kubectl -n monitor get secret prometheus -o jsonpath="{.data.ca\.crt}" | base64 -d |tee k8s-sa-prometheus.ca.crt
  • 配置prometheus接入node_exporter监控指标数据

将上面的k8s-sa-prometheus.token和k8s-sa-prometheus.ca.crt文件复制到prometheus服务器的某个目录下存放,这里放置到 /usr/local/prometheus/secrets/目录下

vim prometheus.yml
...
  - job_name: 'kubernetes-node'
    kubernetes_sd_configs:
    - role: node
      api_server: https://<controlPlaneEndpoint>
      tls_config:
        ca_file: /usr/local/prometheus/secrets/k8s-sa-prometheus.ca.crt
      bearer_token_file: /usr/local/prometheus/secrets/k8s-sa-prometheus.token
    relabel_configs:
    - source_labels: [__address__]
      regex: '(.*):10250'
      replacement: '${1}:19100'
      target_label: __address__
      action: replace

# prometheus安装在k8s集群内

由于prometheus在容器内部,这里不需要单独指定API Server地址和token文件,但是部署prometheus的时候需要单独指定一个sa才有权限

  • 配置prometheus接入node_exporter监控指标数据
vim prometheus.yml
...
  - job_name: 'kubernetes-node'
    kubernetes_sd_configs:
    - role: node
    relabel_configs:
    - source_labels: [__address__]
      regex: '(.*):10250'
      replacement: '${1}:19100'
      target_label: __address__
      action: replace

# 配置prometheus监控容器资源

前面说过,cAdvisor 广泛用于监控容器化应用程序的资源使用情况,在k8s中已经内置了该组件,所以不需要我们单独去安装

cAdvisor数据接口可以从以下2个路径获取:

  • 直接通过 kubelet 获取: https://<node-ip>:10250/metrics/cadvisor
  • 通过 API Server 代理访问 kubelet:https://<controlPlaneEndpoint>/api/v1/nodes/<node>/proxy/metrics

这里我们直接通过kubelet的10250获取数据

注意需要启用 kubelet 的认证和授权 Webhook,确保对请求的管理

添加权限,特别注意需要nodes/metrics的create权限

kubectl edit clusterrole prometheus
...
rules:
  - apiGroups: [""]
    resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources:
      - nodes/metrics
    verbs: ["create", "get", "list", "watch"]

# prometheus安装在k8s集群外

修改prometheus配置文件如下:

vim prometheus.yml
...
  - job_name: 'kubernetes-cadvisor'
    scheme: https
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /usr/local/prometheus/secrets/k8s-sa-prometheus.token
    kubernetes_sd_configs:
    - role: node
      api_server: https://<controlPlaneEndpoint>
      tls_config:
        ca_file: /usr/local/prometheus/secrets/k8s-sa-prometheus.ca.crt
      bearer_token_file: /usr/local/prometheus/secrets/k8s-sa-prometheus.token
    relabel_configs:
    - target_label: __metrics_path__
      replacement: /metrics/cadvisor
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)

# prometheus安装在k8s集群内

修改prometheus的configmap

# 编辑prometheus资源清单文件
vim prometheus.yaml
...
  - job_name: 'kubernetes-cadvisor'
    scheme: https
    tls_config:
      insecure_skip_verify: true
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    kubernetes_sd_configs:
    - role: node
    relabel_configs:
    - target_label: __metrics_path__
      replacement: /metrics/cadvisor
    - action: labelmap
      regex: __meta_kubernetes_node_label_(.+)

1745740682374.png

编撰人:wangyxyf