概述
在本文中,我们将会介绍如何使用Prometheus Operator简化在Kubernetes下部署和管理Prmetheus的复杂度。
Prometheus Operator 功能说明
Operator 就是针对管理特定应用程序的,在Kubernetes基本的Resource和Controller的概念上,以扩展Kubernetes api的形式。帮助用户创建,配置和管理复杂的有状态应用程序。从而实现特定应用程序的常见操作以及运维自动化。
Prometheus Operator的架构示意图:
Prometheus的本职就是一组用户自定义的CRD资源以及Controller的实现,Prometheus Operator负责监听这些自定义资源的变化,并且根据这些资源的定义自动化的完成如Prometheus Server自身以及配置的自动化管理工作。
目前,Prometheus Operator 提供的了 5 类资源:
- Prometheus:声明式创建和管理Prometheus Server实例;
- ServiceMonitor:负责声明式的管理 Service 级别监控配置;
- PodMonitor:负责声明式的管理 Pod 级别监控配置;
- PrometheusRule:负责声明式的管理告警配置;
- Alertmanager:声明式的创建和管理Alertmanager实例。
Operator 安装
下面,我们第一步来安装 Prometheus Operator。
在Kubernetes中安装Prometheus Operator非常简单,用户可以从以下地址中拉取 Prometheus Operator 的源码:
git clone https://github.com/coreos/prometheus-operator.git
这里,我们为Promethues Operator创建一个单独的命名空间monitoring:
kubectl create namespace monitoring
由于需要对Prometheus Operator进行RBAC授权,而默认的bundle.yaml中使用了default命名空间,因此,在安装Prometheus Operator之前需要先替换一下bundle.yaml文件中ClusterRoleBinding以及ServiceAccount的namespace定义。
通过运行一下命令安装Prometheus Operator的Deployment实例:
kubectl -n monitoring apply -f bundle.yaml# clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created# clusterrole.rbac.authorization.k8s.io/prometheus-operator created# deployment.apps/prometheus-operator created# serviceaccount/prometheus-operator created
Prometheus Operator通过Deployment的形式进行部署,为了能够让Prometheus Operator能够监听和管理Kubernetes资源同时也创建了单独的ServiceAccount以及相关的授权动作。
创建Prometheus实例
当集群中已经安装 Prometheus Operator 之后,对于部署 Prometheus Server 实例就变成了声明一个 Prometheus 资源,如下所示,我们在Monitoring命名空间下创建一个Prometheus实例:
apiVersion: monitoring.coreos.com/v1kind: Prometheusmetadata:name: instnamespace: monitoringspec:# 支持额外通过 secret 的方式增加 scrape 监控配置additionalScrapeConfigs:key: additional-scrape-configs.yamlname: prometheus-operator-prometheus-scrape-config# Alert Manage 相关配置alerting:alertmanagers:- apiVersion: v2name: prometheus-operator-alertmanagernamespace: defaultpathPrefix: /port: web# 禁用 admin APIenableAdminAPI: false# 设置 urlexternalUrl: http://prometheus-operator-prometheus.default:9090# 启动本地端口listenLocal: false# 日志配置logFormat: logfmtlogLevel: infopaused: false# 设置关联全部的 PodMonitorpodMonitorNamespaceSelector: {}podMonitorSelector:matchLabels:release: prometheus-operatorportName: web# 副本数量replicas: 2# 资源限制resources:limits:cpu: "5"memory: 40Girequests:cpu: "1"memory: 400Miretention: 10droutePrefix: /# 设置关联的ruleruleNamespaceSelector: {}ruleSelector:matchLabels:app: prometheus-operatorrelease: prometheus-operatorsecurityContext:fsGroup: 2000runAsNonRoot: truerunAsUser: 1000# 指定资源账户serviceAccountName: prometheus-operator-prometheus# 设置关联全部的 serviceMonitorserviceMonitorNamespaceSelector: {}serviceMonitorSelector: {}# 存储声明storage:volumeClaimTemplate:spec:accessModes:- ReadWriteOnceresources:requests:storage: 60GistorageClassName: local-path
将以上内容保存到prometheus-inst.yaml文件,并通过kubectl进行创建:
kubectl create -f prometheus-inst.yaml# prometheus.monitoring.coreos.com/inst-1 created
此时,查看default命名空间下的statefulsets资源,可以看到Prometheus Operator自动通过Statefulset创建的Prometheus实例:
kubectl -n monitoring get statefulsets# NAME DESIRED CURRENT AGE# prometheus-inst 2 2 1m
添加集群内服务监控
添加监控配置项是 Prometheus 中常用的运维操作之一,为了能够自动化的管理Prometheus的配置,Prometheus Operator使用了自定义资源类型ServiceMonitor来描述监控对象的信息。
这里我们首先在集群中部署一个示例应用,将以下内容保存到 example-app.yaml,并使用kubectl命令行工具创建:
kind: ServiceapiVersion: v1metadata:name: example-applabels:app: example-appspec:selector:app: example-appports:- name: webport: 8080---apiVersion: apps/v1kind: Deploymentmetadata:name: example-applabels:app: example-appspec:replicas: 3selector:matchLabels:app: example-apptemplate:metadata:labels:app: example-appspec:containers:- name: example-appimage: fabxc/instrumented_appports:- name: webcontainerPort: 8080
通过 kubectl 命令行工具来创建:
kubectl apply -f ./example-app.yaml
上述示例应用会通过Deployment创建3个Pod实例,并且通过Service暴露应用访问信息。
此时,我们可以在集群内访问对应的 Service Cluster IP 来调用查询看看:
kubectl get svc# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE# example-app ClusterIP 10.233.55.121 <none> 8080/TCP 6m19scurl http://10.233.55.121:8080/metrics# # HELP codelab_api_http_requests_in_progress The current number of API HTTP requests in progress.# # TYPE codelab_api_http_requests_in_progress gauge# codelab_api_http_requests_in_progress 2# # HELP codelab_api_request_duration_seconds A histogram of the API HTTP request durations in seconds.# # TYPE codelab_api_request_duration_seconds histogram# codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0001"} 0# ...
在Prometheus Operator中,则可以直接声明一个 ServiceMonitor 对象来实现添加监控配置,如下所示:
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata:name: example-appnamespace: monitoringlabels:team: frontendspec:namespaceSelector:matchNames:- defaultselector:matchLabels:app: example-appendpoints:- port: web
通过定义 selector 中的标签定义选择监控目标的 Pod 对象,同时在 endpoints 中指定 port 名称为 web 的端口。默认情况下ServiceMonitor和监控对象必须是在相同Namespace下的。在本示例中由于Prometheus是部署在Monitoring命名空间下,因此为了能够关联default命名空间下的example对象,需要使用namespaceSelector定义让其可以跨命名空间关联ServiceMonitor资源。
保存以上内容到example-app-service-monitor.yaml文件中,并通过kubectl创建:
kubectl create -f example-app-service-monitor.yaml# servicemonitor.monitoring.coreos.com/example-app created
如果希望ServiceMonitor可以关联任意命名空间下的标签,则通过以下方式定义:
spec:namespaceSelector:any: true
如果监控的Target对象启用了BasicAuth认证,那在定义ServiceMonitor对象时,可以使用endpoints配置中定义basicAuth如下所示:
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata:name: example-appnamespace: monitoringlabels:team: frontendspec:namespaceSelector:matchNames:- defaultselector:matchLabels:app: example-appendpoints:- basicAuth:password:name: basic-authkey: passwordusername:name: basic-authkey: userport: web
其中basicAuth中关联了名为basic-auth的Secret对象,用户需要手动将认证信息保存到Secret中:
apiVersion: v1kind: Secretmetadata:name: basic-authdata:password: dG9vcg== # base64编码后的密码user: YWRtaW4= # base64编码后的用户名type: Opaque
添加服务监控后,你可以在 Prometheus 页面查询对应的指标信息等。
添加集群外实例监控
在上文中,我们已经知道了如何通过 ServiceMonitor 自定义资源对象来添加 K8s 集群内部的 Server 的监控。那么对于集群外部呢?我们应该如何添加对应的监控配置呢?
集群外添加监控时,就需要依赖到我们之前在 Prometheus CR 中设置的 additionalScrapeConfigs 配置了。
我们再来回顾一下当时的配置:
spec:# 支持额外通过 secret 的方式增加 scrape 监控配置additionalScrapeConfigs:key: additional-scrape-configs.yamlname: prometheus-operator-prometheus-scrape-config
其中:
- additionalScrapeConfigs 表示需要额外通过 secret 的方式增加 scrape 监控配置。
- name 对应的是 secret 的名称。
- additional-scrape-configs.yaml 对应的是 secret 中对应的 key 的名称。
Prometheus Operator 将会从对应的 Secret 中检测到希望的配置被提交到 Prometheus 中生效的。
下面,我们来以一个示例来演示一下。我们创建一个 additional-scrape-configs.yaml 文件,示例如下:
- job_name: linuxbasescrape_interval: 15sscrape_timeout: 10smetrics_path: /metricsscheme: httpstatic_configs:- targets:- 172.10.0.23:9100
然后,我们创建一个 Secret:
kubectl create secret generic prometheus-operator-prometheus-scrape-config --from-file=additional-scrape-configs.yaml --dry-run=true -o yaml > secret.yaml
提交到 K8s 集群中:
kubectl apply -f secret.yaml
稍等片刻,查看prometheus的target列表即可。
