概述

在本文中,我们将会介绍如何使用Prometheus Operator简化在Kubernetes下部署和管理Prmetheus的复杂度。

Prometheus Operator 功能说明

Operator 就是针对管理特定应用程序的,在Kubernetes基本的Resource和Controller的概念上,以扩展Kubernetes api的形式。帮助用户创建,配置和管理复杂的有状态应用程序。从而实现特定应用程序的常见操作以及运维自动化。
Prometheus Operator的架构示意图:
image.png
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 的源码:

  1. git clone https://github.com/coreos/prometheus-operator.git

这里,我们为Promethues Operator创建一个单独的命名空间monitoring:

  1. kubectl create namespace monitoring

由于需要对Prometheus Operator进行RBAC授权,而默认的bundle.yaml中使用了default命名空间,因此,在安装Prometheus Operator之前需要先替换一下bundle.yaml文件中ClusterRoleBinding以及ServiceAccount的namespace定义。
通过运行一下命令安装Prometheus Operator的Deployment实例:

  1. kubectl -n monitoring apply -f bundle.yaml
  2. # clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created
  3. # clusterrole.rbac.authorization.k8s.io/prometheus-operator created
  4. # deployment.apps/prometheus-operator created
  5. # serviceaccount/prometheus-operator created

Prometheus Operator通过Deployment的形式进行部署,为了能够让Prometheus Operator能够监听和管理Kubernetes资源同时也创建了单独的ServiceAccount以及相关的授权动作。

创建Prometheus实例

当集群中已经安装 Prometheus Operator 之后,对于部署 Prometheus Server 实例就变成了声明一个 Prometheus 资源,如下所示,我们在Monitoring命名空间下创建一个Prometheus实例:

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: Prometheus
  3. metadata:
  4. name: inst
  5. namespace: monitoring
  6. spec:
  7. # 支持额外通过 secret 的方式增加 scrape 监控配置
  8. additionalScrapeConfigs:
  9. key: additional-scrape-configs.yaml
  10. name: prometheus-operator-prometheus-scrape-config
  11. # Alert Manage 相关配置
  12. alerting:
  13. alertmanagers:
  14. - apiVersion: v2
  15. name: prometheus-operator-alertmanager
  16. namespace: default
  17. pathPrefix: /
  18. port: web
  19. # 禁用 admin API
  20. enableAdminAPI: false
  21. # 设置 url
  22. externalUrl: http://prometheus-operator-prometheus.default:9090
  23. # 启动本地端口
  24. listenLocal: false
  25. # 日志配置
  26. logFormat: logfmt
  27. logLevel: info
  28. paused: false
  29. # 设置关联全部的 PodMonitor
  30. podMonitorNamespaceSelector: {}
  31. podMonitorSelector:
  32. matchLabels:
  33. release: prometheus-operator
  34. portName: web
  35. # 副本数量
  36. replicas: 2
  37. # 资源限制
  38. resources:
  39. limits:
  40. cpu: "5"
  41. memory: 40Gi
  42. requests:
  43. cpu: "1"
  44. memory: 400Mi
  45. retention: 10d
  46. routePrefix: /
  47. # 设置关联的rule
  48. ruleNamespaceSelector: {}
  49. ruleSelector:
  50. matchLabels:
  51. app: prometheus-operator
  52. release: prometheus-operator
  53. securityContext:
  54. fsGroup: 2000
  55. runAsNonRoot: true
  56. runAsUser: 1000
  57. # 指定资源账户
  58. serviceAccountName: prometheus-operator-prometheus
  59. # 设置关联全部的 serviceMonitor
  60. serviceMonitorNamespaceSelector: {}
  61. serviceMonitorSelector: {}
  62. # 存储声明
  63. storage:
  64. volumeClaimTemplate:
  65. spec:
  66. accessModes:
  67. - ReadWriteOnce
  68. resources:
  69. requests:
  70. storage: 60Gi
  71. storageClassName: local-path

将以上内容保存到prometheus-inst.yaml文件,并通过kubectl进行创建:

  1. kubectl create -f prometheus-inst.yaml
  2. # prometheus.monitoring.coreos.com/inst-1 created

此时,查看default命名空间下的statefulsets资源,可以看到Prometheus Operator自动通过Statefulset创建的Prometheus实例:

  1. kubectl -n monitoring get statefulsets
  2. # NAME DESIRED CURRENT AGE
  3. # prometheus-inst 2 2 1m

添加集群内服务监控

添加监控配置项是 Prometheus 中常用的运维操作之一,为了能够自动化的管理Prometheus的配置,Prometheus Operator使用了自定义资源类型ServiceMonitor来描述监控对象的信息。
这里我们首先在集群中部署一个示例应用,将以下内容保存到 example-app.yaml,并使用kubectl命令行工具创建:

  1. kind: Service
  2. apiVersion: v1
  3. metadata:
  4. name: example-app
  5. labels:
  6. app: example-app
  7. spec:
  8. selector:
  9. app: example-app
  10. ports:
  11. - name: web
  12. port: 8080
  13. ---
  14. apiVersion: apps/v1
  15. kind: Deployment
  16. metadata:
  17. name: example-app
  18. labels:
  19. app: example-app
  20. spec:
  21. replicas: 3
  22. selector:
  23. matchLabels:
  24. app: example-app
  25. template:
  26. metadata:
  27. labels:
  28. app: example-app
  29. spec:
  30. containers:
  31. - name: example-app
  32. image: fabxc/instrumented_app
  33. ports:
  34. - name: web
  35. containerPort: 8080

通过 kubectl 命令行工具来创建:

  1. kubectl apply -f ./example-app.yaml

上述示例应用会通过Deployment创建3个Pod实例,并且通过Service暴露应用访问信息。
此时,我们可以在集群内访问对应的 Service Cluster IP 来调用查询看看:

  1. kubectl get svc
  2. # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. # example-app ClusterIP 10.233.55.121 <none> 8080/TCP 6m19s
  4. curl http://10.233.55.121:8080/metrics
  5. # # HELP codelab_api_http_requests_in_progress The current number of API HTTP requests in progress.
  6. # # TYPE codelab_api_http_requests_in_progress gauge
  7. # codelab_api_http_requests_in_progress 2
  8. # # HELP codelab_api_request_duration_seconds A histogram of the API HTTP request durations in seconds.
  9. # # TYPE codelab_api_request_duration_seconds histogram
  10. # codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0001"} 0
  11. # ...

在Prometheus Operator中,则可以直接声明一个 ServiceMonitor 对象来实现添加监控配置,如下所示:

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: ServiceMonitor
  3. metadata:
  4. name: example-app
  5. namespace: monitoring
  6. labels:
  7. team: frontend
  8. spec:
  9. namespaceSelector:
  10. matchNames:
  11. - default
  12. selector:
  13. matchLabels:
  14. app: example-app
  15. endpoints:
  16. - port: web

通过定义 selector 中的标签定义选择监控目标的 Pod 对象,同时在 endpoints 中指定 port 名称为 web 的端口。默认情况下ServiceMonitor和监控对象必须是在相同Namespace下的。在本示例中由于Prometheus是部署在Monitoring命名空间下,因此为了能够关联default命名空间下的example对象,需要使用namespaceSelector定义让其可以跨命名空间关联ServiceMonitor资源。
保存以上内容到example-app-service-monitor.yaml文件中,并通过kubectl创建:

  1. kubectl create -f example-app-service-monitor.yaml
  2. # servicemonitor.monitoring.coreos.com/example-app created

如果希望ServiceMonitor可以关联任意命名空间下的标签,则通过以下方式定义:

  1. spec:
  2. namespaceSelector:
  3. any: true

如果监控的Target对象启用了BasicAuth认证,那在定义ServiceMonitor对象时,可以使用endpoints配置中定义basicAuth如下所示:

  1. apiVersion: monitoring.coreos.com/v1
  2. kind: ServiceMonitor
  3. metadata:
  4. name: example-app
  5. namespace: monitoring
  6. labels:
  7. team: frontend
  8. spec:
  9. namespaceSelector:
  10. matchNames:
  11. - default
  12. selector:
  13. matchLabels:
  14. app: example-app
  15. endpoints:
  16. - basicAuth:
  17. password:
  18. name: basic-auth
  19. key: password
  20. username:
  21. name: basic-auth
  22. key: user
  23. port: web

其中basicAuth中关联了名为basic-auth的Secret对象,用户需要手动将认证信息保存到Secret中:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: basic-auth
  5. data:
  6. password: dG9vcg== # base64编码后的密码
  7. user: YWRtaW4= # base64编码后的用户名
  8. type: Opaque

添加服务监控后,你可以在 Prometheus 页面查询对应的指标信息等。
image.png

添加集群外实例监控

在上文中,我们已经知道了如何通过 ServiceMonitor 自定义资源对象来添加 K8s 集群内部的 Server 的监控。那么对于集群外部呢?我们应该如何添加对应的监控配置呢?
集群外添加监控时,就需要依赖到我们之前在 Prometheus CR 中设置的 additionalScrapeConfigs 配置了。
我们再来回顾一下当时的配置:

  1. spec:
  2. # 支持额外通过 secret 的方式增加 scrape 监控配置
  3. additionalScrapeConfigs:
  4. key: additional-scrape-configs.yaml
  5. name: prometheus-operator-prometheus-scrape-config

其中:

  • additionalScrapeConfigs 表示需要额外通过 secret 的方式增加 scrape 监控配置。
  • name 对应的是 secret 的名称。
  • additional-scrape-configs.yaml 对应的是 secret 中对应的 key 的名称。

Prometheus Operator 将会从对应的 Secret 中检测到希望的配置被提交到 Prometheus 中生效的。

下面,我们来以一个示例来演示一下。我们创建一个 additional-scrape-configs.yaml 文件,示例如下:

  1. - job_name: linuxbase
  2. scrape_interval: 15s
  3. scrape_timeout: 10s
  4. metrics_path: /metrics
  5. scheme: http
  6. static_configs:
  7. - targets:
  8. - 172.10.0.23:9100

然后,我们创建一个 Secret:

  1. kubectl create secret generic prometheus-operator-prometheus-scrape-config --from-file=additional-scrape-configs.yaml --dry-run=true -o yaml > secret.yaml

提交到 K8s 集群中:

  1. kubectl apply -f secret.yaml

稍等片刻,查看prometheus的target列表即可。

添加告警配置