Kubernetes监控混合器
这个词出现在很多Kubernetes相关项目中,涉及Prometheus和Grafana。尽管它被广泛使用,但有关它的细节却不容易找到。有很多情况下,混合器的使用没有明显提到它们(例如在prometheus-operator中)。在这篇文章中,我们将探讨它是什么,以及你如何在你的Kubernetes集群中使用它。
具体来说,我们将定义什么是Kubernetes监控混合器
,它们试图解决什么问题以及如何使用它们。此外,通过开发一个伴随着详细解释的实例展示,这应该有助于读者理解所提出的概念。
术语的定义应该明确社区对它的参考意义。它还将解释该术语的根源和它所包括的内容。因为它本质上是一个行动和工具的集合,所以必须明确这两者。
通过调查其使用前所面临的问题,你将能够理解其概念背后的动机。这也将揭示出为什么在使用混合器工作时要使用特定的工具。由于问题本身在于云原生应用的其他领域,通过了解这个特定案例的考虑,你将能够在相关问题上利用类似的方法。
在这篇文章中,我们将创建一个.jsonnet文件和一个附带的Docker镜像,与kubernetes混合库进行交互。
定义
监控混合器
这个词的准确定义可以在https://monitoring.mixins.dev/。
mixin是一组Grafana仪表盘和Prometheus规则和警报,被打包成一个可重复使用和可扩展的包。混合器是用 jsonnet编写的,通常用 jsonnet-bundler安装和更新。
由于上述定义有很多术语,我们需要对其进行分解,以便深入理解其含义。一个可以帮助我们的资源是Prometheus Monitoring Mixins Design Document,其中提到了更多细节。根据这份文件。
监控混合器是一个包含Prometheus警报、Prometheus记录规则和Grafana仪表盘的配置包。混合体将作为一组文件被维护在版本控制的仓库(例如:Git)中。混合器的版本控制将由版本控制系统提供;混合器本身不应包含多个版本。
混合器仅用于Prometheus和Grafana的组合,而不是其他监控或可视化系统。 混合器的目的是对监控技术的选择提出意见。
然而,混合器不应该是关于如何部署这种配置的意见;例如,它们不应该包含在Kubernetes上部署Prometheus和Grafana的清单。 多个独立的项目可以也应该存在,以帮助部署混搭;我们将提供如何在Kubernetes上这样做的例子,以及与传统配置管理系统集成的工具。
上述内容意味着,通过使用监控混合器
这个术语,我们指的是使用jsonnet产生的Prometheus记录规则、Prometheus警报规则和Grafana仪表板的配置文件包。它对它要配置的工具(只有用于监控的Prometheus和用于可视化的Grafana)以及它们的子组件(对于Prometheus只有规则和警报,对于Grafana只有仪表盘)都非常具体。
问题所在
领域
这个问题领域与Kubernetes集群中的监控和警报有关。鉴于你已经安装了Prometheus来收集指标,并安装了Grafana来查看这些指标,没有简单的方法来创建规则、警报和仪表盘。这个问题包括Prometheus记录规则、Prometheus警报规则和Grafana仪表板的配置文件的创建、修改、版本和分发。
问题的另一个方面是如何应用这些配置文件。由于Prometheus和Grafana可以用不同的方法安装,它们的配置不是一个琐碎的任务。例如,Prometheus可以通过自定义YAML文件、使用Helm包管理器或通过Prometheus运营商安装。每个选项都有其关于Prometheus组件的安装和配置的权衡。监控混合器指定了它所支持的安装方法。
Prometheus和Grafana的配置复杂性
正如《你需要知道的关于监控混合器的一切》一文中所描述的,尽管每个组件都有现成的资源,但将它们连接在一起仍然很复杂。每个组件都被设计用来执行一个特定的任务。为了在各种环境(虚拟机、Docker容器、Kubernetes pods等)中做到这一点,设计者引入了许多配置选项。由于每个组件都是高度可配置的,因此创建一个能在现有的Kubernetes集群中工作的组件包变得很有挑战性。
此外,它们在动态Kubernetes集群中的核心功能使其必须易于配置。在定期添加服务和组件的集群中,监控和警报系统也需要定期扩展和修改。在重构的情况下,这个过程尤其紧张,因为新的资源被添加或旧的资源被修改,甚至被撤销。
问题的另一个方面来自于Kubernetes清单在集群中的应用方式的限制。具体来说,接受的格式是YAML和JSON。这两种格式都是静态的、缩进的,用于存储数据。它们不是模板,所以你不能选择使用变量、条件语句或循环。当你试图概括一套Prometheus配置和Grafana仪表盘时,这是一个限制,因为每个管理员或开发人员将需要编辑这些.json
或.yaml
文件,以便在他们的环境中工作。此外,如果这些变化是手动完成的,那么它将成为一个乏味和容易出错的程序。
上述情况表明,需要一种方法来将Prometheus、Grafana和Alertmanager的配置文件打包成可分发和可配置的包。这应该考虑到.json
和.yaml
清单文件的固有局限性,这些文件是Kubernetes集群真正关心的终端资源。
一个行之有效的解决方案--Kubernetes监控混合器
Kubernetes监控混合器是如何解决问题的
Kubernetes监控混合器
通过采用一系列的实践和工具来解决上述问题。这些旨在创建可重用的、可配置的和可扩展的软件包,非监控专家可以轻松安装。同时,这些包能够与Prometheus和Grafana的安装清单一起存储在版本控制系统中。
解决方案的第一步是定义系统中应该已经存在的组件,同时限制解决方案所负责的配置方面。Prometheus和Grafana需要已经安装在系统上。另外,mixin本身将只为Prometheus记录规则、Prometheus警报规则和Grafana仪表盘创建配置文件。
为了实现可重用性、可配置性和可扩展性,监控混合器利用了jsonnet。具体来说,他们为自己负责的组件提供jsonnet库(扩展名为.libsonnet
)。Jsonnet是一种数据模板语言,可以产生所需的.json
清单文件。它提供了所需的模板化能力、变量、条件语句、函数和循环。这意味着,使用所提供的库,我们能够根据现有设置的需要定制配置文件。
监控器混合器可以方便地进行分发和版本管理,因为它们可以在代码库中找到。它们需要与现有Kubernetes集群设置所需的定制有关的最小输入。这种输入又是以jsonnet文件的形式提供的。后者意味着我们可以将jsonnet文件与其他清单文件一起进行版本控制。
上述内容总结起来就是一套带有jsonnet接口的jsonnet库,允许使用它们。在指示这些库根据现有集群设置(使用jsonnet接口)产生配置后,预期的结果是一组清单文件,准备应用于集群。
具体的kubernetes-mixin是如何结构的
正如介绍中提到的,我们将对kubernetes-mixin的使用情况进行分析。从它的存储库可以看出,它有一个目录,分别以将要配置的三个组件命名。
每个目录都包含相关的jsonnet库。
存储库还提供了关于底层jsonnet库的版本信息,以及关于如何制作和使用清单文件的说明,这些文件有望成为这些库的成果。舱单文件的制作已被简化为只需调用给定的jsonnet库,只需进行一些配置。可以看出,关于如何应用清单文件的说明在很大程度上取决于Prometheus和Grafana的设置方式。
关于Jsonnet如何参与kubernetes-mixin的概述/解释
虽然详细解释jsonnet是如何工作的不在本文的范围内,但看看jsonnet是如何被利用的,以便为kubernetes-mixin的用例提供所需的灵活性是很有用的。
上一节中讨论的目录结构允许轻松检查所包含的库。每个警报
、规则
和仪表盘
目录都有一组.libsonnet
文件。这些文件是jsonnet库。lib
目录作为一个入口点,因为它结合了上述的库。它有一组.libsonnet
和.jsonnet
文件,实际上包括库文件。
不同组件的配置是通过根目录下名为config.libsonnet
的文件完成的。在那里你可以看到基本配置,这些配置将被库用来生成清单文件。此配置可由您自己的 jsonnet 文件修改和扩展。
例子
我们将使用kubernetes-mixin。 正如该库的描述中提到的,它是 "一套用于Kubernetes的Grafana仪表盘和Prometheus警报"。
前提条件
由于我们想看到监控混合器的运行,我们需要一个Kubernetes集群。在你的本地机器上建立这样一个集群的一个简单方法是使用Kind。它是轻量级的,快速的,推荐用于本地开发。要在你的本地机器上安装Kind,只需遵循这里的说明。然后,你可以使用这些命令来启动你的本地集群。
为了与你的集群互动,还需要kubectl,它将让你检查和创建本地Kind Kubernetes集群上的资源。由于我们要安装一些组件,你需要有kubectl。你可以期望kubectl能够自动与你的Kind集群通信,因为它们都使用默认路径来放置所需的配置文件。
另一件要注意的事情是,例子中的命令是指Linux主机。它们会很简单,在其他主机环境中也有各自的替代方法。
使用kubernetes-mixin jsonnet工作
我们的目标是创建一个.jsonnet
文件,说明如何与kubernetes-mixin中的库互动。首先创建以下目录结构。
~/k8s-mixin-example ├──jsonnet └── manifests
jsonnet目录将存放你的.jsonnet
文件,其中有关于如何创建Prometheus和Grafana配置文件的说明。这些配置文件稍后将存储在 manifests 目录内。
创建一个文件jsonnet/mixin-simple.jsonnet
,内容如下。
local utils = import "./vendor/kubernetes-mixin/lib/utils.libsonnet"。
local conf = (import "./vendor/kubernetes-mixin/mixin.libsonnet")
+
{
_config+::{
kubeStateMetricsSelector: 'job="kube-state-metrics"'。
cadvisorSelector: 'job="kubernetes-cadvisor"',
nodeExporterSelector: 'job="kubernetes-node-exporter"',
kubeletSelector: 'job="kubernetes-kubelet"'。
grafanaK8s+::{
dashboardNamePrefix: 'Mixin / ',
dashboardTags。['kubernetes', 'infrastucture'],
},
prometheusAlerts+::{
groups: ['kubernetes-resources'],
}
},
}
+ {
prometheusAlerts+::{
/* 从警报中只选择 "kubernetes-system"。
https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/alerts/system_alerts.libsonnet#L9
*/
组。
std.filter(
function(alertGroup)
alertGroup.name == 'kubernetes-system' (警报组)。
, super.groups
)
}
}
+ {
prometheusRules+:: {
/* 从规则中只选择 "k8s.rules"。
https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/rules/apps.libsonnet#L10
*/
组。
std.filter(
function(alertGroup)
alertGroup.name == 'k8s.rules'。
, super.groups
)
}
}
+ {
grafanaDashboards+::{}
}
;
{ ['prometheus-alerts']: conf.prometheusAlerts }
+
{ ['prometheus-rules']: conf.prometheusRules }
+
{ ['grafana-dashboard'] : conf.grafanaDashboards['kubelet.json'], }
上面的jsonnet命令将配置组件。你可以看到,它们参考了。
- 带有"_config "的一般配置参数
prometheusAlerts
配置。具体来说,它将只选择kubernetes-system
警报prometheusRules
配置。具体来说,它将只选择k8s.rules
grafanaDashboards
,其中它只选择kubelet.json
的
虽然官方的kubernetes-mixin有一套命令可以产生所有的Prometheus警报、规则和Grafana仪表盘,但jsonnet/mixin-simple.jsonnet
文件实际上将利用底层库,以产生它们的一个子集。它展示了你如何利用mixin中的jsonnet库,只产生你需要的东西。在我们的案例中,我们需要的是一个单一的PrometheusAlert
、PrometheusRule
和一个grafanaDashboard
。
创建并使用一个能产生配置的Docker镜像
为了尽量减少需要安装的工具,你可以将其中一些工具打包到Docker镜像中。这个镜像将启动一个容器,它将安装jsonnet二进制文件并下载所需的库。然后你就可以安装你的配置,它将产生Prometheus警报和Grafana仪表盘。
产生Docker镜像的Docker文件有以下内容。
FROM golang:1.16-alpine3.14 AS golang
FROM alpine:3.14 AS runtime
# 下载二进制文件
FROM golang AS builder
RUN apk add git\
&& GO111MODULE=on go get -u github.com/google/go-jsonnet/cmd/jsonnet@v0.16.0\
&& go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@v0.4.0
&& GO111MODULE=on go get github.com/mikefarah/yq/v3@3.3.2
# 建立我们的最终图像
From runtime
COPY --from=builder /go/bin/jsonnet /usr/local/bin/jsonnet
COPY --from=builder /go/bin/jb /usr/local/bin/jb
COPY --from=builder /go/bin/yq /usr/local/bin/yq
运行 apk add bash make git
工作区/app
运行jb init && jb install github.com/kubernetes-monitoring/kubernetes-mixin
CMD jsonnet -J vendor jsonnet/mixin-simple.jsonnet -m . > json-files-list &&\\
cat json-files-list | grep -v grafana | xargs -i{ }/bin/sh -c 'cat {} !| yq r -P - > manifests/{}.yaml && rm {}' && \
cat json-files-list | grep grafana | xargs -i{ }/bin/sh -c 'cat {} > manifests/{}.json && rm {}' 。
在上述多阶段Docker文件中,构建步骤为。
1.使用golang alpine base下载jsonnet、jb和yq并构建其二进制文件
2.将所需的jsonnet和yq二进制文件复制到容器将使用的镜像中
3.定义一个默认运行的命令
该命令很复杂,可能需要一些进一步的解释。它包括三个与操作符&&相关的链式命令。第一部分jsonnet -J vendor jsonnet/mixin-simple.jsonnet -m . > json-files-list
表示 jsonnet 将执行jsonnet/mixin-simple.jsonnet
,产生的文件名将被保存到json-files-list
文件中。第二条命令读取json-files-list
里面的文件列表,并过滤掉那些不包含 "grafana "的文件。然后将这些.json
文件转换为.yaml
文件,并将其移至manifests
目录下。第三条命令读取json-files-list
中的文件列表,指出含有 "grafana "一词的文件,并将其移至manifests目录下。
将文件从.json
格式转换为.yaml
格式(grafana除外),是为了符合Prometheus和Grafana的预期格式,它们将是这些文件的消费者。
要创建Docker镜像,你可以使用以下命令。
docker build -t manifests-factory:v0.1.0 -f Dockerfile .
这将创建一个名为manifests-factory:v0.1
.0的镜像,你将用它来启动容器,该容器将使用文件jsonnet/mixin-simple.jsonnet
来生成清单文件。
接下来,通过以下命令使用你刚刚创建的docker镜像。
docker run --rm -ti -v ~/k8s-mixin-example/jsonnet:/app/jsonnet -v ~/k8s-mixin-example/manifests:/app/manifests manifests-factory:v0.1.0
docker容器挂载了两个目录作为卷。
- ~/k8s-mixin-example/jsonnet,其中存在
jsonnet/mixin-simple.jsonnet
(输入) - ~/k8s-mixin-example/manifests,这里将放置生成的文件(输出)。
通过运行上述命令,预期结果是三个文件。
~/k8s-mixin-example/manifests ├──grafana-dashboard.json └── prometheus-alerts.yaml └── prometheus-rules.yaml
安装和配置Prometheus和Grafana
如前几节所述,Prometheus和Grafana应该已经安装。另外,kubernetes-mixin中提到了关于如何使用你在上一步中产生的配置文件的以下选项。
然后,你有三个选项来部署你的仪表板
1.生成配置文件并自行部署
2.使用ksonnet将此混合器与Prometheus和Grafana一起部署
3.使用Prometheus-operator来部署这个混合器(TODO)。
在这个例子中,重点是选项1,它比较通用。
你需要一种方法来安装Prometheus和Grafana,并指示它们使用你在前面步骤中创建的警报、规则和仪表盘。这种安装也必须与上面提到的限制兼容。
Prometheus和Grafana的安装说明不在本例的范围内,所以你可以使用ingress-nginx仓库,该仓库提供了你可以用来让它们到位的清单。这意味着你需要克隆该仓库。
[~/k8s-mixin-example]: git clone https://github.com/kubernetes/ingress-nginx.git [~/k8s-mixin-example]: tree -L 1 . ├── ingress-nginx ├───jsonnet └──清单
现在你应该有了所有需要的清单文件,所以现在是时候在运行中的 Kind 集群上安装和配置 Prometheus 和 Grafana 了。
普罗米修斯
首先创建manifests/prometheus-config.yaml
文件,内容如下。
全局。
scrape_interval: 10s
rule_files:
- rules.yaml
- alerts.yaml
scrape_configs:
- job_name: 'ingress-nginx-endpoints'.
kubernetes_sd_configs:
- role: pod
命名空间。
names:
- ingress-nginx
relabel_configs:
- source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_scrape] 。
Action: keep
regex: true
- source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_scheme]。
动作:替换
target_label:__scheme__
重码: (https?)
- source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_path] 。
动作:替换
target_label:__metrics_path__
重码: (.+)
- source_labels:[__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]。
动作:替换
target_label:__address__
搜索结果: ([^:]+)(?:\d+)?;(\d+)
替换:1:2
- source_labels:[__meta_kubernetes_service_name]。
重码: prometheus-server
操作:删除
在这个配置中,你可能会注意到rule_files
。这些文件将包含manifests/prometheus-rules.yaml
和manifests/prometheus-alerts.yaml
。
为了让Prometheus使用你的配置文件,需要通过ConfigMap挂载这些文件。具体步骤如下。
[~/k8s-mixin-example]: kubectl create ns ingress-nginx
[~/k8s-mixin-example]: kubectl apply -k ingress-nginx/deploy/prometheus
[~/k8s-mixin-example]: kubectl create -n ingress-nginx configmap $(kubectl get configmaps -n ingress-nginx | grep prometheus | awk '{print 1}' )--from-file=prometheus.yaml=manifests/prometheus-config.yaml --from-file=rules.yaml=manifests/prometheus-rules.yaml --from-file=alerts.yaml=manifests/prometheus-alerts.yaml --dry-run=client -o yaml | kubectl apply -f -.
[~/k8s-mixin-example]: kubectl delete pod -n ingress-nginx $(kubectl get pods -n ingress-nginx | grep prometheus-server | awk '{print 1}' )
这些步骤将创建命名空间ingress-nginx
,应用清单文件以创建所需的Prometheus资源,更新Prometheus的配置以考虑到你所创建的警报和规则,最后删除prometheus-server
pod。删除实际上将重新创建豆荚,现在将使用正确的配置。
你可以通过访问Prometheus用户界面来验证警报和规则是否已经到位。要做到这一点,首先要对其服务进行端口转发。
kubectl port-forward -n ingress-nginx svc/prometheus-server 9090:9090
然后用你的浏览器访问这些URL。
Grafana
Grafana的情况比较简单,因为它涉及到使用Web界面。要做到这一点,你需要首先通过以下方式部署Grafana。
[~/k8s-mixin-example]: kubectl apply -k ingress-nginx/deploy/grafana
在grafana pod就绪后,你可以暴露grafana服务。
[~/k8s-mixin-example]: kubectl port-forward -n ingress-nginx svc/grafana 3000:3000
用你的浏览器进入http://localhost:3000,使用 "admin "作为用户名和密码。然后导航到创建>导入
,点击上传JSON文件
按钮。在那里你可以选择你的~/k8s-mixin-example/manifests/grafana-dashboard.json
文件,这将在General/Mixin/Kubelet
下创建仪表板。
作为一个数据源,可以使用URL http://prometheus-server:9090。
总结
在这篇文章中,我们探讨了Kubernetes监控混合器。我们表明,它们基本上是通过使用jsonnet库来构建Prometheus警报、规则和Grafana仪表板的一种方式。后者解决了分发代码的问题,同时也处理了所需清单文件中需要的高水平定制问题。
所提供的例子显示了你如何使用混合器。具体而言,您可以如何配置它、生成清单文件并在本地Kubernetes集群中使用它们。通过说明如何使用所需的工具以及它们如何相互作用,它旨在成为一个详细的例子,您可以用来开发更复杂的配置。
虽然我们主要关注的是一个特定的项目,但开发jsonnet库来产生配置的想法也可以在Kubernetes生态系统的其他方面使用。Jsonnet可以用来修改JSON模板,注入新的块,删除和添加属性等。这意味着在制作清单文件时,减少了手动和容易出错的任务。在写这篇文章的时候,许多工具都提供了jsonnet库,以便对其进行定制。一个突出的例子是kube-prometheus,它提供了一个jsonnet接口。
请注意,在不久的将来会有一篇jsonnet的深入研究文章,其中会介绍更多关于其使用的高级概念。