在本指南的前几章中,我们介绍了如何安装完整的使用Prometheus监控Kubernetes。 我们最后结束下使用Prometheus Operator框架及其“自定义资源定义”相对于手动添加度量标准目标的优势
这次我们将部署类似的环境,但将更加自动化和灵活。
什么是Kubernetes Operator?
Operator是Kubernetes专用的应用程序(pod),可自动配置,管理和优化其他Kubernetes部署。它们被实现为自定义控制器。
Kubernetes Operator封装了部署和扩展应用程序的专有技术,并直接执行与API通信的算法决策。
Kubernetes operotor可能能够:
根据Kubernetes集群的规格安装并提供合理的初始配置和规模来进行部署。
执行部署和Pod的实时重新加载,以适应用户请求的任何参数修改(热配置重新加载)。
根据性能指标自动放大或缩小。
执行备份,完整性检查或任何其他维护任务。
基本上,任何可以由人类管理员表示为代码的东西都可以在Kubernetes Operator内部自动执行。
Kubernetes操作员广泛使用自定义资源定义(或CRD)来创建特定于上下文的实体和对象,这些实体和对象将像其他任何Kubernetes API资源一样被访问。例如,在下一节中,将能够与“ Prometheus” Kubernetes API对象进行交互,该对象定义Prometheus服务器部署的初始配置和规模。Operator可以读取,写入和更新CRD,以将服务配置持久保存在群集中。
Prometheus Operator
用于Kubernetes的Prometheus Operator为Kubernetes服务以及Prometheus实例的部署和管理提供了简单的监视定义。
我们将使用Prometheus Operator:
执行完整的Kubernetes-Prometheus的初始安装和配置
Prometheus服务器
alertmanager
grafna
主机node_exporter
kube-state-metrics
使用ServiceMonitor实体定义度量标准endpoint自动配置
使用操作员CRD和ConfigMap自定义和扩展服务,使我们的配置具有完全可移植性和声明性
操作员根据以下自定义资源定义(CRD)进行操作:
Prometheus,它定义了所需的Prometheus部署。操作员始终确保与资源定义匹配的部署正在运行。
ServiceMonitor,以声明方式指定应如何监视服务组。操作员根据定义自动生成Prometheus scrape 配置。
PrometheusRule,它定义了所需的Prometheus规则文件,可以由包含Prometheus警报和记录规则的Prometheus实例加载。
Alertmanager,它定义了所需的Alertmanager部署。操作员始终确保与资源定义匹配的部署正在运行。
Operator信息库中的kube-prometheus目录包含默认服务和配置,因此不仅可以获取Prometheus Operator本身,还可以获取一个完整的设置,可以从一开始就开始使用和自定义。
Prometheus-Operator组件架构图
以下是我们打算构建的Kubernetes监视系统的组件图:
可以看到该图与第2部分中的图类似,在第2部分中我们手动安装了Prometheus组件。 但是,有两个重要的区别:
不同的Prometheus部署将监视不同的资源:
一组Prometheus服务器(1到N,具体取决于要监控的规模)将监视Kubernetes的内部组件和状态。
另一组Prometheus服务器将监视群集中部署的任何其他应用程序。
与直接创建部署和服务不同,我们将使用CRD向操作员提供指标源。 在上面的示例中,我们有一个带有两个数据源的Grafana服务,但是由于Prometheus Operator,我们将展示如何以声明性的方式重新排列组件图。
Prometheus Operator –快速安装
Prometheus-monitoring-guide存储库包含一些基本的yaml文件和我们将使用的示例定制。 首先,克隆存储库(如果尚未完成的话):
1 2 |
git clone https://github.com/coreos/prometheus-operator.git git clone https://github.com/mateobur/prometheus-monitoring-guide.git |
确保本地kubectl指向正在运行的kubernetes集群。 我们可能希望使用可以轻松丢弃并重新创建的测试平台群集,以便可以试验不同的配置。
要使用默认值安装kube-prometheus,只需要:
1 |
kubectl create -f prometheus-operator/contrib/kube-prometheus/manifests/ |
默认部署了许多组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
kubectl get pods -n monitoring NAME READY STATUS RESTARTS AGE alertmanager-main-0 2/2 Running 0 7m alertmanager-main-1 2/2 Running 0 7m alertmanager-main-2 2/2 Running 0 6m grafana-5568b65944-nwbct 1/1 Running 0 8m kube-state-metrics-76bdcb8ff9-77t52 4/4 Running 0 6m node-exporter-224sh 2/2 Running 0 7m node-exporter-2s89j 2/2 Running 0 7m node-exporter-x8w8b 2/2 Running 0 7m prometheus-k8s-0 3/3 Running 1 7m prometheus-k8s-1 3/3 Running 1 6m prometheus-operator-cdccdb8db-vcvhx 1/1 Running 0 8m |
可以看到:
Prometheus-operator pod是核心,负责管理其他部署,例如Prometheus服务器或Alertmanager服务器
每个物理主机的节点导出器容器(在此示例中为3)
一个kube-state-metrics导出器
默认的Prometheus服务器部署prometheus-k8s(副本:2)
默认的Alertmanager部署alertmanager-main(副本:3)
Grafana部署grafana(副本:1)
访问Prometheus Operator的接口
要快速了解刚刚部署的接口,可以使用kubectl的端口转发功能。
1 |
kubectl port-forward grafana-5568b65944-nwbct -n monitoring 3000:3000 |
现在,将Web浏览器指向http:// localhost:3000,将访问Grafana界面,该界面已经填充了一些有用的仪表板!
但是,如果要部署生产Kubernetes监视,则需要使用入口控制器并以适当的安全性正确公开这些接口:HTTPS证书和身份验证。
通过CRD对象与Prometheus Operator进行交互
要修改此Prometheus部署,而不是像在Kubernetes中期望的那样修改每个组件Deployment或StatefulSet,将直接自定义抽象定义并让操作员为处理业务流程。
让我们从一个简单的示例开始:假设3个Alertmanager在这种情况下太多了,我们只想要一个。
首先,我们将探讨alertmanager CRD:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
kubectl get alertmanager main -n monitoring -o yaml apiVersion: monitoring.coreos.com/v1 kind: Alertmanager metadata: clusterName: "" creationTimestamp: 2018-08-28T09:15:25Z labels: alertmanager: main name: main namespace: monitoring resourceVersion: "1401" selfLink: /apis/monitoring.coreos.com/v1/namespaces/monitoring/alertmanagers/main uid: e5d335aa-aaa2-11e8-8cf2-42010a800113 spec: baseImage: quay.io/prometheus/alertmanager nodeSelector: beta.kubernetes.io/os: linux replicas: 3 serviceAccountName: alertmanager-main version: v0.15.2 |
在这里,可以修改Pod标签,serviceAccount,nodeSelector以及我们要寻找的内容:副本数。
将副本参数更改为“ 1”,以修补API对象(可以在prometheus-monitoring-guide存储库中找到修补的版本):
1 |
kubectl create -f prometheus-monitoring-guide/operator/alertmanager.yaml --dry-run -o yaml | kubectl apply -f - |
如果再次在监视名称空间中列出Pod,将在Prometheus Operator本身的日志中仅看到一个Alertmanager Pod和resize事件:
1 2 |
kubectl logs prometheus-operator-cdccdb8db-vcvhx -n monitoring | tail -n 1 level=info ts=2018-08-28T09:47:20.523662127Z caller=operator.go:402 component=alertmanageroperator msg="sync alertmanager" key=monitoring/main |
Prometheus Operator端点可取消自动配置
下一步是在此配置的基础上开始监视群集中部署的所有其他服务。
此过程涉及两个自定义资源:
普罗米修斯CRD
定义Prometheus服务器Pod元数据
定义Prometheus服务器副本数
定义Alertmanager端点以发送触发的警报规则
为将由此Prometheus服务器部署应用的ServiceMonitor CRD定义标签和名称空间过滤器
ServiceMonitor对象将提供动态目标端点配置
ServiceMonitor CRD
按名称空间,标签等过滤端点
定义不同的抓取端口
定义所有其他抓取参数,例如抓取间隔,要使用的协议,TLS凭证,重新标记策略等。
Prometheus对象过滤并选择了N个ServiceMonitor对象,后者又过滤并选择了N个Prometheus度量标准端点。
如果有一个符合ServiceMonitor标准的新指标终结点,则此目标将自动添加到选择该ServiceMonitor的所有Prometheus服务器。
如在上图中所看到的,ServiceMonitor以Kubernetes服务为目标,而不是Pod直接暴露的端点。
我们已经有一个Prometheus部署来监视所有Kubernetes内部指标(kube-state-metrics,node-exporter,Kubernetes API等),但是现在我们需要一个单独的部署来监视在群集顶部运行的任何其他应用程序。
为了进行此新部署,首先让我们先看一下此Prometheus CRD,然后再将其应用于集群(可以在存储库中找到此文件,如下所示):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
us/prometheus logLevel: info paused: false replicas: 2 retention: 2d routePrefix: / ruleSelector: matchLabels: prometheus: service-prometheus role: alert-rules serviceAccountName: prometheus-k8s serviceMonitorSelector: matchExpressions: - key: serviceapp operator: Exists |
为了简洁起见,我们将重用在另一个部署中找到的alertmanager和serviceAccount配置。
在此Prometheus服务器配置文件中,我们可以找到:
使用此配置的Prometheus副本数(2)
将动态配置警报规则的ruleSelector
Alertmanager部署(可以有多个Pod,以实现冗余),将接收触发的警报
ServiceMonitorSelector,这是决定是否使用给定serviceMonitor来配置此Prometheus服务器的过滤器。
对于此示例,我们已决定,如果serviceMonitor在其元数据中包含标签serviceapp,则它将与此Prometheus部署相关联。
调整好需求后,我们可以直接从存储库中应用新配置:
1 |
kubectl create -f prometheus-monitoring-guide/operator/service-prometheus.yaml |
在这里,Prometheus Operator将注意到新的API对象并创建所需的部署:
1 2 |
prometheus-service-prometheus-0 3/3 Running 1 12m prometheus-service-prometheus-1 3/3 Running 1 12m |
如果连接到任何一个pod的接口,则会注意到我们还没有任何指标目标。 我们需要一项服务来抓取。 如果已经安装了某些东西并想使用它,那就太好了! 否则,我们可以使用Helm快速运行一个应用程序。
CoreDNS是快速,灵活的DNS服务器,是Cloud Native Computing Foundation的孵化级项目。 因此,如果对集群进行了helm设置,请运行:
1 2 |
kubectl create ns coredns helm install --name coredns --namespace=coredns stable/coredns |
CoreDNS可以立即使用Prometheus指标(使用端口9153):
1 2 3 |
kubectl get svc -n coredns NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coredns-coredns ClusterIP 10.11.253.94 <none> 53/UDP,53/TCP,9153/TCP 3m |
现在,可以使用ServiceMonitor将此新服务与Services Prometheus部署连接(可以在存储库中找到此文件,如下所示):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: serviceapp: coredns-servicemonitor name: coredns-servicemonitor namespace: monitoring spec: endpoints: - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token interval: 15s port: metrics namespaceSelector: matchNames: - coredns selector: matchLabels: release: coredns |
应用:
1 |
kubectl create -f prometheus-monitoring-guide/operator/servicemonitor-coredns.yaml |
几秒钟后,如果查看Prometheus界面内的抓取目标,将看到配置是如何自动更新的,并且正在从该目标接收指标:
现在,如果我们增加此CoreDNS部署的服务Pod(并因此增加指标端点)的数量,请执行以下操作:
1 |
helm upgrade coredns stable/coredns --set replicaCount=3 |
ServiceTarget会自动检测每个目标,并在Prometheus配置中注册:
Prometheus Operator-如何配置警报规则
我们可以使用与ServiceMonitor非常相似的概念PrometheusRule CRD在Prometheus部署中配置Kubernetes监视警报。
当我们定义Prometheus部署时,有一个配置块可以过滤和匹配这些对象:
1 2 3 4 |
ruleSelector: matchLabels: prometheus: service-prometheus role: alert-rules |
如果定义的对象包含所需的PromQL规则并匹配所需的元数据,则它们将自动添加到Prometheus服务器的配置中(可以在存储库中找到此文件,如下所示)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: labels: prometheus: service-prometheus role: alert-rules name: prometheus-service-rules namespace: monitoring spec: groups: - name: general.rules rules: - alert: TargetDown-serviceprom annotations: description: '{{ $value }}% of {{ $labels.job }} targets are down.' summary: Targets are down expr: 100 * (count(up == 0) BY (job) / count(up) BY (job)) > 10 for: 10m labels: severity: warning - alert: DeadMansSwitch-serviceprom annotations: description: This is a DeadMansSwitch meant to ensure that the entire Alerting pipeline is functional. summary: Alerting DeadMansSwitch expr: vector(1) labels: severity: none |
从存储库中申请:
1 |
kubectl create -f prometheus-monitoring-guide/operator/prometheusrules.yaml |
我们将能够立即从服务方法界面检查这些警报。 如果不想配置外部入口,请使用本地端口转发:
1 |
kubectl port-forward prometheus-service-prometheus-0 -n monitoring 9090:9090 |
访问Prometheus服务器界面中的“警报”选项卡:
DeadManSwitch是始终触发的警报的通用名称(它的触发条件始终评估为true),并且在那里可以检查警报管道是否按预期工作。 加载此条件几秒钟后,应该在浅红色背景上看到警报名称(firing),如上图所示。
如果现在打开Alertmanager界面(端口9093),则可以看到来自此Prometheus部署的警报。 如果不想配置外部入口,请使用本地端口转发:
1 |
kubectl port-forward alertmanager-main-0 -n monitoring 9093:9093 |
Prometheus Operator–定义Grafana仪表盘
到今天为止,Prometheus Operator中没有针对Grafana组件的自定义资源定义。 为了管理Grafana配置,我们将使用Kubernetes secret和ConfigMap,包括新的数据源和新的仪表板。
当使用通过Prometheus Operator部署的Grafana时,数据源定义为使用Grafana从Kubernetes secret中读取的base64编码的数据结构。
如果解码当前的机密数据,则应该看到类似以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
kubectl get secret grafana-datasources -n monitoring -o jsonpath --template '{.data.prometheus.yaml}' | base64 -d { "apiVersion": 1, "datasources": [{ "access": "proxy", "editable": false, "name": "prometheus", "orgId": 1, "type": "prometheus", "url": "http://prometheus-k8s.monitoring.svc:9090", "version": 1 }] } |
我们只需要使用相同的JSON格式附加新的数据源,将secret数据重新编码为base64并更新。
让我们创建这个新文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "apiVersion": 1, "datasources": [ { "access": "proxy", "editable": false, "name": "prometheus", "orgId": 1, "type": "prometheus", "url": "http://prometheus-k8s.monitoring.svc:9090", "version": 1 }, { "access": "proxy", "editable": false, "name": "service-prometheus", "orgId": 1, "type": "prometheus", "url": "http://service-prometheus.monitoring.svc:9090", "version": 1 } ] } |
将其封装在一个secret对象中(可以使用自己的文件,也可以使用存储库中的文件,如下所示):
1 |
kubectl create secret generic grafana-datasources -n monitoring --from-file=./prometheus-monitoring-guide/operator/grafana/prometheus.yaml --dry-run -o yaml > grafana-datasources.yaml |
并在API中修补Grafana密码:
1 |
kubectl patch secret grafana-datasources -n monitoring --patch "$(cat grafana-datasources.yaml)" |
请注意,数据源指向服务而不是Prometheus Pod,必须使用以下文件创建service-prometheus.monitoring.svc服务:
1 |
kubectl create -f prometheus-monitoring-guide/operator/prometheus-svc.yaml |
最终,重启grafna:
1 |
kubectl delete pod grafana-5568b65944-szhx4 -n monitoring |
并转到用户界面中的“数据源”选项卡(如有必要,再次使用端口转发,端口3000),应该将这两个Prometheus部署都视为数据源:
使用Prometheus Operator,只需在Kubernetes ConfigMap中对Dashboard JSON数据进行编码即可从外部加载Grafana仪表板:
1 2 3 4 5 6 7 |
kubectl get cm -n monitoring NAME DATA AGE grafana-dashboard-k8s-cluster-rsrc-use 1 20d grafana-dashboard-k8s-node-rsrc-use 1 20d grafana-dashboard-k8s-resources-cluster 1 20d grafana-dashboard-k8s-resources-namespace 1 20d grafana-dashboard-k8s-resources-pod 1 20d |
这些ConfigMap被显式地安装在Grafana部署定义中:
1 2 3 4 5 6 7 8 9 |
kubectl get deployments grafana -n monitoring -o yaml ... - mountPath: /grafana-dashboard-definitions/0/pods name: grafana-dashboard-pods ... - configMap: defaultMode: 420 name: grafana-dashboard-pods name: grafana-dashboard-pods |
可以为每个仪表板创建一个新的ConfigMap,并在管理Grafana pod的部署定义中添加相应的条目。
另一个也许更灵活的选择是使用Grafana Helm Chart,该图表将自动完成仪表板配置升级,如本指南第2部分所述。
总结
使用Prometheus Operator,我们可以以声明性和可复制性更高的方式轻松构建Kubernetes监视堆栈,这也更易于扩展,修改或迁移到另一组主机。
到目前为止,我们一直在讨论使用Prometheus技术堆栈监视Kubernetes集群的功能,优势和令人信服的可能性。但是,在进行大型部署之前,还需要了解其缺点或警告,例如:
长期存储:如前所述,Prometheus提取了长期指标存储(以及与备份,数据冗余,趋势分析,数据挖掘密切相关的问题)。本指南的第2部分介绍了最小的Rook部署,它将提供完整存储解决方案的基本构建块。
授权和身份验证:如项目文档中所指出,Prometheus及其组件不提供任何服务器端身份验证,授权或加密。没有具有不同访问级别或任何其他RBAC框架的用户组。
垂直和水平可伸缩性:与其说是缺点,不如说是一个弊端,我们需要预先计划该方面,以便对目标容量做出明智的决策。
Kubernetes monitoring with Prometheus – Prometheus operator tutorial (part 3).