【全面解説】在Kubernetes上部署Prometheus的方法
首先
本篇文章将介绍如何在Kubernetes上部署Prometheus。还将解释如何在Metricfire上配置远程长期存储,该服务提供了Prometheus的托管服务。本教程使用一个具有一个节点的minikube集群,但这些步骤应该适用于任何Kubernetes集群。请观看下方所列的视频(英语)或阅读本文,以了解所有步骤的详细说明。
如果您使用免费试用版,就可以访问MetricFire的产品,并轻松应用您所学到的知识。
视频请点击这里。
请用中文将以下内容进行释义,只需要一个版本: https://youtu.be/V4ApOm37XCU
我们将使用YAML文件来创建资源。这意味着我们可以记录我们所做的事情,并在需要进行更改时随时重新使用文件。文件的版本在这里,但也有空间供您编写您自己的详细信息。
在这里,我们将查看YAML文件包含什么以及它们做什么,但不会深入了解Kubernetes的工作原理。然而,这应该是进一步深入探索时的一个好起点。这些YAML文件各自指示Kubectl向Kubernetes API服务器发送请求,并根据这些指示创建资源。
命名空间
为了更精细地控制监控设置,我们将创建一个名为“monitoring”的新命名空间,其中所有Kubernetes资源都会以命名空间方式启动,如果未指定命名空间,则将使用“默认”命名空间。
这是一个非常简单的手动执行命令,但为了速度、准确性和精确的再现性,在后面我们坚持使用文件代替。查看文件后,我们得知它被发布到了名为v1的apiversion中,并且像一个资源一样被称为命名空间,其名称是“monitoring”。
适用此命令
kubectl apply -f monitoring-namespace.yaml
应用此操作,您可以通过命令显示可用的命名空间。
kubectl get namespaces
配置图
下一步是配置ConfigMap。Kubernetes的ConfigMap会为部署中的所有Pod提供配置数据。
这个文件的apiversion显示为v1,kind显示为ConfigMap。元数据中显示了名为”prometheus-config”和”monitoring”的名称。
在下面的数据部分中有一个非常简单的prometheus.yml文件。仔细看的话,里面包含了简单的时间间隔设置,没有任何警报或规则设置,只是通过Prometheus的抓取作业获取与自己相关的指标。
此外,由于Metricfire远程存储的详细信息也包含在内,因此当Prometheus实例启动并运行时,数据将开始发送到远程写入位置。只需提供remote_read和remote_write的端点和API密钥即可。
配置图本身并不执行任何操作,但在文章的后半部分中,将其应用以便在部署Prometheus时使用。
kubectl apply -f prometheus-config.yaml
角色
接下来,在两个监控的命名空间中,设置角色和服务账户以授予对所有Kubernetes资源的访问权限。具体而言,设置ClusterRole。通常情况下,通常的角色只能访问同一命名空间内的资源。为了获取Prometheus提供的所有指标,它需要从整个集群访问节点和Pod。
集群角色的规则可以适用于 Kubernetes API 组(kubectl 使用这些 yaml 文件来应用)或非资源 URL(在这种情况下为 “/metrics”)。这将作为用于抓取 Prometheus 指标的端点。每个规则的动词将决定在这些 API 或 URL 上可以执行的操作。
ServiceAccount是一个可以应用于运行中资源和Pod的标识符。如果没有指定ServiceAccount,则将应用默认的ServiceAccount,该ServiceAccount会在名为Monitoring的命名空间下创建。换句话说,Prometheus将默认使用该ServiceAccount。
最后,应用 ClusterRoleBinding 并将角色绑定到服务账号上。
这些都是在一个文件中创建的。根据需要,您还可以将它们捆绑到部署中。为了更易理解,我们将它们分开保留。
kubectl apply -f prometheus-roles.yml
注意:将此应用于自己的Kubernetes集群时,可能会在此时通过kubectl对已经存在的资源使用kubectl apply方法时显示与仅限于使用kubectl apply的错误消息,但该命令会正常运行。
部署
由于已经创建了一个包含全部命名空间、配置和绑定了集群角色的默认服务账号,因此已经准备好部署Prometheus本身。
部署文件中包含了包含在集合中的所有Pod上应用的PodTemplate的详细信息。 ReplicaSet数据包含在文件的第一个”spec”部分中。
replicas是指集合中所需的副本数量。在本例中,我们只会启动一个。
选择器详细说明了ReplicaSet如何识别所控制的Pods。这是一种常见的资源指向另一个资源的方式。
战略是指实施更新的方式。
模板部分是应用于集合内每个Pod的Pod模板。
由于ReplicaSet的存在,因此此处不需要命名空间。
根据上述的选择器规则,标签是必需的,并且将在启动时用于找到适用的Pod的所有服务中使用。
annotations的值不仅在配置Prometheus的抓取目标时非常重要,还在抓取Pod指标时非常重要。这些值将被转换为标签,并可以在作业运行之前用于设置值。例如,可以使用替代端口或过滤指标的值。尽管当前可能还没有使用,但可以看到已经为端口添加了注解9090。您也可以进一步展示这些注解的内容。
在模板的第二个Spec部分中,包含了每个容器的执行方式规范。由于其非常复杂,所以只会详细说明与Prometheus相关的选项。
-
- Imageは、使用されるDockerイメージです。この場合、quay.ioでホストされているprometheusイメージです。
-
- commandは、コンテナの起動時にコンテナで実行するコマンドです。
-
- argsは、そのコマンドに渡す引数であり、以下で設定する構成ファイルの場所も含まれます。
-
- portsは、ポート9090がWebトラフィック用に開かれるように指定する場所です。
- volumeMountsは、外部ボリュームまたはディレクトリがコンテナにマウントされる場所です。ここではnameとmountPathが指定されています-ここでは、起動時にprometheusに渡される引数で指定された場所に構成ボリュームがマウントされていることがわかります。
在这里有两个卷,每个卷都分别针对容器进行了配置,并且包含了卷的名称。
首选是ConfigMap。这被视为卷的一种类型,可以在容器内的进程中引用。其次是 emptyDir 卷,它是存在于 Pod 存在时的存储类型。即使删除容器,卷仍然存在,但当整个 Pod 被删除时,数据将丢失。
在理想情况下,应将数据保存在更持久的位置。尽管教程中仅使用了临时存储,但通过配置remote_read和remote_write,Prometheus能够将从远程接收的所有数据发送到Metricfire。
在这里,应用部署文件。
kubectl apply -f prometheus-deployment.yaml
让我们来查看监视命名空间资源的状态。
Kubectl get all --namespace=monitoring
节点端口
在使用Prometheus之前,还有一件事尚未完成。目前,Prometheus在集群中运行,因此无法访问。需要设置一个名为NodePort的服务,以便通过节点的IP地址来访问Prometheus。
这个文件非常简洁,可以通过写入命名空间和选择器,将自己应用于正确的Pod和使用的端口。
kubectl apply -f prometheus-nodeservice.yaml
如果应用此设置,你可以通过任何节点的端口30900来查看正在运行的Prometheus。获取节点的IP地址会因Kubernetes的设置而异,但幸运的是,Minikube提供了一种简单的方式来获取节点的URL。你可以使用以下方法来查看所有的服务。
minikube service list
或者,您可以使用以下命令直接在默认浏览器中打开prometheus的URL。
minikube service --namespace=monitoring prometheus
通过一个名为”prometheus”的标签”job”,您可以检索到该作业的所有指标,并通过配置内的一个爬虫任务从Prometheus本身获取所有可用指标。
{job=”prometheus”}
Node Exporter和新的ConfigMap
接下来,我们需要获取一些关于集群的有用指标。我们可以使用一个叫做Node Exporter的应用程序来获取与集群节点相关的指标,并且通过修改Prometheus configmap来包含集群内节点和Pod的作业。我们可以使用Kubernetes服务发现来获取这些新作业的终结点和元数据。
Node Exporter使用特殊类型的ReplicaSet称为DaemonSet进行部署。当ReplicaSet控制任意数量的Pod在一个或多个节点上运行时,DaemonSet在每个节点上运行一个Pod。它非常适合用于节点监视应用程序。
创建DaemonSet所需的文件与常规部署文件非常相似。但是,由于DaemonSet进行了修改,因此没有副本数,但仍有包含带注释的元数据和容器规范的PodTemplate。
然而,Node Exporter的卷有相当大的差异。虽然没有configmap卷,但我们可以发现代替的是将节点的系统目录作为卷映射到容器中。这就是node exporter访问metric值的方式。通过设置securityContext为”privileged: true”,node exporter被授予访问这些值的权限。
在应用此配置后,确认DaemonSet正在运行。
kubectl apply -f node-exporter-daemonset.yml
kubectl get all --namespace=monitoring
在新的configMap文件中,由于要使用不同的方法获取度量,因此prometheus作业已被注释掉。取而代之的是,添加了两个新作业kubernetes-nodes和kubernetes-pods。
Kubernetes-pods从集群中的每个Pod请求指标,包括Node Exporter和Prometheus,而kubernetes-nodes通过使用服务发现获取所有节点的名称,并向Kubernetes本身请求与它们相关的信息。
在节点作业中,可以看到添加了使用由Kubernetes提供的认证信息进行安全连接的详细信息。还有一些标签变更规则。这些规则作用于由prometheus创建的标准标签和由服务发现提供的metadata标签构成的作业的labelset。这些规则可以创建新标签或在作业执行之前更改作业本身的配置。
在这种情况下,规则执行了三个动作。
-
- 最初に、ノードに適用されたラベルに基づいてジョブのラベルを作成します。
-
- 次に、ジョブに使用されるアドレスを、サービスディスカバリによって提供されるアドレスから、ノードメトリックにアクセスするための特定のエンドポイントに変更します。
- 3番目に、メトリックパスを/ metricsから、ノード名を含む特定のAPIパスに変更します。
在第二个工作中,需要访问Pod设置的annotation。为了明确要进行指标抓取的Pod,使用了prometheus.io/scrape这个注解。annotation prometheus.io/port与addresstag一起,确保每个Pod的抓取使用正确的端口。
首先,配置图的替换是Prometheus的两步骤过程。您需要使用replace命令来向Kubernetes提供替换映射。
kubectl replace -f prometheus-config2.yaml
配置映射(configMap)将适用于使用它的所有容器。但是,Prometheus不会自动加载新的配置。在查看Prometheus UI时,将显示旧的配置和作业。-prometheus:30900/config
在中文中将以下内容进行改写:
加载新配置的最简单方法是将副本数减少为零,然后再恢复为1。这将创建新的Pod,但会导致现有数据丢失,当然,所有数据都会发送到Metricfire的图表中。
更新构成页面后,将显示新的作业。在查看目标页面时,还会显示目标和元数据。指标位于kubernetes-pods作业下,并带有节点的前缀。
切换到Metricfire后,节点导出指标的仪表板已经配置好了。如果更新仪表板,这些新的指标将通过Metricfire数据源显示。
总结起来,可以这样说。
-
- namespaceを作成しました
-
- configMapを作成しました
-
- デフォルトのServiceAccountであるClusterRoleを作成し、それらをバインドしました。
-
- Prometheusをデプロイしました
-
- Prometheus UIを公開するノードポートサービスを作成しました
-
- node-exporterデーモンセットをデプロイしました
-
- ノードエクスポーターの新しいジョブでconfigMapを更新
- そして、0にスケーリングして1に戻すことで、Prometheusをリロードしました。
熟悉此设置后,可以添加像cAdvisor这样用于监视容器的其他服务,以及获取有关Kubernetes其他部分的指标的作业。对于每个新服务,只需配置新的抓取作业并更新configMap,然后重新加载到Prometheus即可。非常简单!
作为这篇文章的结束,我将解释一下清理环境的方法。实际上,这非常简单。只需删除命名空间,其中的所有内容都会被删除!
kubectl delete namespace monitoring
请确认一切是否消失或已关闭。
kubectl get all --namespace=monitoring
过一段时间,一切都应该被清理干净。
请问您准备好尝试使用Metricfire的托管Prometheus了吗?如果您希望开始14天的免费试用,或者预约进行演示,并有任何问题需要咨询,欢迎随时联系我们(可使用日语)。
那么,我们下一篇文章再见!