将 Kubernetes 抓取目标添加到不在 Kubernetes 中的 Prometheus 实例

Add Kubernetes scrape target to Prometheus instance that is NOT in Kubernetes

我 运行 prometheus 在本地作为 http://localhost:9090/targets with

docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus

并想将它连接到我们拥有的几个 Kubernetes(集群)实例。 看到抓取有效,尝试 Grafana dashboards

然后我将在专门用于监控的专用服务器上执行相同的操作。 然而,所有谷歌搜索都给了我所有不同的方法来配置已经在一个 Kubernetes 实例中的普罗米修斯,并且无法从外部 Kubernetes 读取指标。

如何将 Kubernetes 抓取目标添加到不在 Kubernetes 中的 Prometheus 实例?


我已阅读 Where Kubernetes metrics come from 并检查我的(第一个)Kubernetes 集群是否具有 Metrics Server

kubectl get pods --all-namespaces | grep metrics-server 

将Prometheus实例添加到每个Kubernetes(集群)实例中绝对没有意义。一个 Prometheus 必须能够从许多 Kubernetes 集群及其中的每个节点读取指标。

P.S。一些 old question 有答案在每个 Kubernetes 中安装 Prometheus 然后使用联邦,这与我正在寻找的正好相反。

P.P.S。我也很奇怪,为什么 Kubernetes 和 Prometheus 是来自 Cloud Native Foundation 的 #1 和 #2 项目没有简单的“在 Prometheus 中添加 Kubernetes 目标”按钮或简单的步骤。

有很多agent能够将k8s收集的metrics保存到集群外的远程Prometheus服务器,例如Prometheus本身现在支持agent mode, exporter from Opentelemetry, or using managed Prometheus

如果我理解你的问题,你想监控远程 kubernetes 集群上没有安装 prometheus 的 kubernetes 集群。

I monitor many different kubernetes cluster from one prometheus which is installed on a standalone server.

您可以通过使用具有访问 kubernetes api. 适当权限的服务帐户在 kubernetes 服务器上生成令牌来实现此目的

Kubernetes-api:

以下是配置 prometheus 抓取作业所需的详细信息。

  1. 创建一个具有读取和观看权限的服务帐户 pods.
  2. 从服务帐户生成令牌。
  3. 创建抓取作业如下。
- job_name: kubernetes
  kubernetes_sd_configs:
  - role: node
    api_server: https://kubernetes-cluster-api.com
    tls_config:
      insecure_skip_verify: true
      bearer_token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  bearer_token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  scheme: https
  tls_config:
    insecure_skip_verify: true
  relabel_configs:
  - separator: ;
    regex: __meta_kubernetes_node_label_(.+)
    replacement: 
    action: labelmap

我在文章里也有详细解释
“使用普罗米修斯监控远程 kubernetes 集群”。 https://amjadhussain3751.medium.com/monitor-remote-kubernetes-cluster-using-prometheus-a3781b041745

在我看来,在每个集群中部署一个Prometheus实例比组织外部访问更简单、更干净。主要问题是使用 kubernetes_sd_configs 发现的目标是集群内部 DNS 名称和 IP 地址(或者至少,在我的 AWS EKS 集群中是这样)。要解决并达到这些,您必须在集群内。

这个问题可以通过使用代理来解决,因此下面的配置使用 API-server 的代理端点来到达目标。我不确定它在大型集群中的性能,但在这种情况下,部署一个内部 Prometheus 实例是非常值得的。

通过API-服务器代理进行外部访问

你需要的东西(每个集群):

  1. API-用于 HTTPS 工作的服务器 CA 证书(请参阅下文如何获取)。
  2. 具有适当权限的服务帐户令牌(取决于您的需要)。

假设您已经有了这些,下面是一个 Prometheus 配置示例:

- job_name: 'kubelet-cadvisor'
  scheme: https

  kubernetes_sd_configs:
  - role: node
    api_server: https://api-server.example.com

    # TLS and auth settings to perform service discovery
    authorization:
      credentials_file: /kube/token  # the file with your service account token
    tls_config:
      ca_file: /kube/CA.crt  # the file with the CA certificate

  # The same as above but for actual scrape request.
  # We're going to send scrape requests back to the API-server
  # so the credentials are the same.
  bearer_token_file: /kube/token
  tls_config:
    ca_file: /kube/CA.crt

  relabel_configs:
  # This is just to drop this long __meta_kubernetes_node_label_ prefix
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)

  # By default Prometheus goes to /metrics endpoint.
  # This relabeling changes it to /api/v1/nodes/[kubernetes_io_hostname]/proxy/metrics/cadvisor
  - source_labels: [kubernetes_io_hostname]
    replacement: /api/v1/nodes//proxy/metrics/cadvisor
    target_label: __metrics_path__

  # This relabeling defines that Prometheus should connect to the
  # API-server instead of the actual instance. Together with the relabeling
  # from above this will make the scrape request proxied to the node kubelet.
  - replacement: api-server.example.com
    target_label: __address__

以上内容专为抓取而设计role: node。要使其与其他角色一起使用,您必须更改 __metrics_path__ 标签。 "Manually constructing apiserver proxy URLs" 文章可以帮助构建路径。

如何获得API-服务器CA证书

有几种方法可以获得它,但从 kubeconfig 获得它对我来说是最简单的:

❯ kubectl config view --raw
apiVersion: v1
clusters:
- cluster:                      # you need this ⤋ long value 
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJ...
    server: https://api-server.example.com
  name: default
...

kubeconfig 中的证书是 base64 编码的,因此您必须先对其进行解码才能使用:

echo LS0tLS1CRUdJTiBDRVJUSUZJ... | base64 -d > CA.crt