【翻译】使用Kubernetes监控混合器

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清单在集群中的应用方式的限制。具体来说,接受的格式是YAMLJSON。这两种格式都是静态的、缩进的,用于存储数据。它们不是模板,所以你不能选择使用变量、条件语句或循环。当你试图概括一套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库,只产生你需要的东西。在我们的案例中,我们需要的是一个单一的PrometheusAlertPrometheusRule和一个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下载jsonnetjbyq并构建其二进制文件
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.yamlmanifests/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-serverpod。删除实际上将重新创建豆荚,现在将使用正确的配置。

你可以通过访问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的深入研究文章,其中会介绍更多关于其使用的高级概念。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值