如何使用Prometheus和Grafana监控多个Kubernetes集群

介绍

为什么要监视多个Kubernetes集群,主要有两个原因。在第一个使用场景中,您拥有集群,每个开发阶段(如开发、阶段化和生产)都有一个集群。另一种情况是运行托管服务,或有运行工作负载的客户机,这些工作负载需要对可靠性进行监控,或作为运行服务的一部分进行使用。

使用Prometheus和inlets进行Kubernetes多集群监控

上图显示了一个在左侧有多个客户端集群的体系结构。广泛采用的基于度量的开源监控和告警系统Prometheus进行监控应用程序和集群。每个集群的监测设置都非常健全和完整; 然而,对于跨集群的度量标准没有明确的做法。

使用一个安全的入口隧道,那些Prometheus服务器可以从右边的集群中到达,也就是可观察性集群。通过这样做,左边的Prometheus服务器可以从其他的Prometheus服务器(也称为Prometheus联盟)上获取选定的时间序列。

对于长期存储,你可能还需要考虑Thanos或Cortex。

让我们看看我们如何构建它!

先决条件

  • 一些Kubernetes集群运行在不同的位置,例如在公共云上(例如GKE, AKS, EKS, DOKS,…)或在私人家庭实验室的测试环境上.
  • kubectl,配置为连接到集群
  • kubectx,可以选择,但对于管理不同的集群很有用
  • arkade -便携式Kubernetes安装市场
  • domain 并可以访问您的DNS管理面板以创建子域

本教程使用inlets PRO,因为它更容易配置,并提供支持,但如果你想自己配置的话,你也可以使用免费的OSS版本的inlets。可以在inlets文档中查看两个版本的区别https://inlets.dev/

对于本教程,我准备了三个Kubernetes集群:

  • Kubernetes集群运行在裸金属机器上
  • Kubernetes集群运行在Amazon orion-aws上
  • Kubernetes集群运行在谷歌云平台orion-gcp上

前两个集群将充当客户端集群,并在monitoring名称空间中运行一个Prometheus服务器。除了Prometheus,还安装了一些度量出口服务,如node- exporters、kube-state-metrics和我最喜欢的kube-eagle。

第三个集群将是我们的可观测性集群,与前两个类似,Prometheus也在这里运行。

安装Prometheus和所有组件有几种方式,但最常见的方式是使用Prometheus Operator或Helm来安装它。

代码语言:javascript
复制
$ kubectx
orion-aws
orion-gcp
orion-equinix

$ kubectl get pods,services --context orion-aws -n monitoring
NAME READY STATUS RESTARTS AGE
pod/node-exporter-dh75f 1/1 Running 0 63m
pod/kube-eagle-6687579fd8-xcsns 1/1 Running 0 63m
pod/prometheus-54d7b46745-lvbvk 1/1 Running 0 63m
pod/node-exporter-w6xx6 1/1 Running 0 63m
pod/node-exporter-p7dbv 1/1 Running 0 63m
pod/kube-state-metrics-7476dc6466-74642 1/1 Running 0 63m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/prometheus ClusterIP 10.43.97.123 <none> 9090/TCP 63m

$ kubectl get pods,services --context orion-equinix -n monitoring
NAME READY STATUS RESTARTS AGE
pod/node-exporter-mzbv2 1/1 Running 0 61m
pod/prometheus-67746cf46c-twbjk 1/1 Running 0 61m
pod/node-exporter-9m4nc 1/1 Running 0 61m
pod/kube-eagle-546bd88874-p4wfd 1/1 Running 0 61m
pod/node-exporter-fjjqv 1/1 Running 0 61m
pod/kube-state-metrics-cbfb75b4-kndwz 1/1 Running 0 61m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/prometheus ClusterIP 10.43.148.58 <none> 9090/TCP 61m

准备可观测性集群

首先,我们必须准备我们的可观察性集群。

目标是使运行在远程客户端集群中的Prometheus服务器在这个集群中可用。为了实现这一点,我们将使用inlets PRO在可观察性和客户端集群之间创建一个安全隧道。这些隧道的服务器部分即出口节点,必须在可观察性集群中创建,以便稍后客户端可以连接并将其它节点Prometheus指标发送到这个集群。

我们不是使用LoadBalancer来公开每个出口节点pod,而是使用一个IngressController,比如nginx,结合cert-manager来获得一些证书。

首先,将上下文切换到正确的集群:

代码语言:javascript
复制
$ kubectx orion-gcp
Switched to context "orion-gcp".

使用arkade安装nginx ingress控制器和cert-manager:

代码语言:javascript
复制
arkade install ingress-nginx --namespace ingress-nginx
arkade install cert-manager --namespace cert-manager

等待一段时间,直到nginx负载均衡器被创建,获取它的公共IP地址,并将你的域名指向它。每个客户端将连接到不同的子域,所以最简单的方法是创建一个通配符DNS记录(例如*.prometheus.example.com)。如果不喜欢通配符记录,可以为指向相同公共IP地址的每个Prometheus客户端创建一条记录(例如orion-aws.prometheus.example.com, orion-equinix.prometheus.example.com,…)。

安装证书颁发者:

代码语言:javascript
复制
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
namespace: monitoring
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: <your email>
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- selector: {}
http01:
ingress:
class: nginx

kubectl apply -f issuer-prod.yaml

为您的inlets服务器生成令牌:

代码语言:javascript
复制
export TOKEN=$(head -c 16 /dev/random | shasum|cut -d" " -f1)
kubectl create secret generic inlets-pro-secret -n monitoring --from-literal token=$TOKEN

Save a copy for later

echo $TOKEN > token.txt

创建具有数据平面所需端口自定义值。对于Prometheus,使用端口9090:

代码语言:javascript
复制
dataPlane:
type: ClusterIP
ports:

  • targetPort: 9090
    protocol: TCP
    name: prom-http
    port: 9090

现在得到inlets-pro helm chart,并安装每个远程Prometheus服务。

代码语言:javascript
复制
git clone https://github.com/inlets/inlets-pro

helm install orion-aws ./inlets-pro/chart/inlets-pro
-n monitoring -f custom.yaml
--set ingress.domain=orion-aws.prometheus.example.com

helm install orion-equinix ./inlets-pro/chart/inlets-pro
-n monitoring -f custom.yaml
--set ingress.domain=orion-equinix.prometheus.example.com

安装这个chart能够得到以下结果:

  • 一个装有inlets PRO服务器的Pod正在运行
  • 创建了一个类型为ClusterIP的控制平面业务,暴露端口8123
  • 使用证书创建Ingress,使控制平面服务以安全的方式可用
  • 创建了一个类型为ClusterIP的数据平面业务,公开了9090端口

这意味着,inlets PRO客户端可以使用适当的域名连接到控制平面,例如wss://orion-aws.prometheus.example.com/connect,并且可以输入端口9090,因为是ClusterIP类型,所以只能从这个集群中访问它。

连接客户端集群

现在已经运行了出口节点Pod,是时候连接客户机并创建隧道了。采取以下所有步骤,并在所有客户端集群执行它们。

将kubectl配置切换到正确的客户端集群:

代码语言:javascript
复制
$ kubectx orion-aws
Switched to context "orion-aws".

为您的inlets PRO许可和令牌创建token

代码语言:javascript
复制
kubectl create secret generic 
-n monitoring inlets-license
--from-file license=$HOME/inlets-license

kubectl create secret generic
-n monitoring inlets-pro-secret
--from-file token=./token.txt

并使用helm安装inlet -pro-client chart,以连接到可观察性集群中的出口节点Pods:

代码语言:javascript
复制
helm install prometheus-tunnel 
./inlets-pro/chart/inlets-pro-client
-n monitoring
--set url=wss://orion-aws2.prometheus.sphene.io/connect
--set upstream=prometheus
--set ports=9090

监控客户端集群

在安装了所有的helm cahrt、服务器和客户端之后,所有的Prometheus服务都可以在我们的可观察性集群中使用,现在我们有一些可以在Grafana中可视化这些指标。

要么我们在Grafana中将所有不同的Prometheus服务作为单独的数据源添加,要么我们用这些端点配置Prometheus服务。对于大多数情况,第二种选择是更可取的,因为它允许我们创建一个聚合视图。

添加这些目标的最简单方法是通过静态配置:

代码语言:javascript
复制
scrape_configs:

  • job_name: 'federated-clusters'
    scrape_interval: 15s

    honor_labels: true

    params:
    'match[]':
    - '{app="kube-state-metrics"}'
    - '{app="kube-eagle"}'
    - '{app="node-exporter"}'

    metrics_path: '/federate'

    static_configs:

    • targets:
      • 'orion-aws-inlets-pro-data-plane:9090'
      • 'orion-equinix-inlets-pro-data-plane:9090'

在这种配置下,我们在本文开头提到的图表右边的Prometheus将开始从其他的Prometheus服务器上抓取参数:

Prometheus抓取联邦客户端集群

现在所有的指标都在一台Prometheus服务器中收集,剩下要做的唯一事情就是构建漂亮的仪表板和告警。

Kube Eagle仪表盘给出了一个多集群概述

总结

这篇文章应该让你了解到,连接在多个、孤立的Kubernetes集群中运行监控服务并不复杂。

通过helm chart把安全隧道、服务器和客户端两侧的应用及必要的组件安装非常方便,您将很快拥有一个隧道。

Prometheus联邦(https://prometheus.io/docs/prometheus/latest/federation/)就是一个例子来说明这种技术。然而,这种设置适用于许多用例,比如将应用程序连接到运行在不同集群中的数据库。