- 01 引言
- 02 初识Prometheus Operator
- 2.1 什么是Prometheus Operator?
- 2.2 Prometheus Operator能做什么?
- 03 在Kubernetes集群中部署Prometheus Operator
- 3.1 下载
- 3.2 配置
- 04 Prometheus Operator的使用
- 4.1 Operator管理Prometheus
- 4.1.1 创建Prometheus实例
- 4.1.2 使用ServiceMonitor管理监控配置
- 4.1.3 关联Promethues与ServiceMonitor
- 4.1.4 自定义ServiceAccount
- 4.2 Operator管理监控配置
- 4.2.1 使用Prometheus Rule定义告警规则
- 4.2.2 使用Operator管理Alertmanager实例
- 4.3 在Operator中使用自定义配置
- 05 文末
为了在Kubernetes
能够方便的管理和部署Prometheus
,我们使用ConfigMap
管理Prometheus
配置文件。
如果每次对Prometheus
配置文件进行升级时,我们需要手动移除已经运行的Pod
实例,从而让Kubernetes
可以使用最新的配置文件创建Prometheus
,当应用实例的数量更多时,通过手动的方式部署和升级Prometheus
过程繁琐并且效率低下。
问题:从本质上来讲Prometheus
属于是典型的有状态应用,而其有包含了一些自身特有的运维管理和配置管理方式,而这些都无法通过Kubernetes
原生提供的应用管理概念实现自动化。
解决方案:为了简化这类应用程序的管理复杂度,CoreOS
率先引入了Operator
的概念,并且首先推出了针对在Kubernetes
下运行和管理Etcd
的Etcd Operator
,并随后推出了Prometheus Operator
。
Operator
:就是针对管理特定应用程序的,在Kubernetes
基本的Resource
和Controller
的概念上,以扩展Kubernetes api
的形式,帮助用户创建,配置和管理复杂的有状态应用程序,从而实现特定应用程序的常见操作以及运维自动化。
在Kubernetes
中我们使用:
Deployment、DamenSet,StatefulSet
来管理应用Workload
;- 使用
Service,Ingress
来管理应用的访问方式; - 使用
ConfigMap
和Secret
来管理应用配置; - 在集群中对这些资源的创建,更新,删除的动作都会被转换为事件(
Event
),Kubernetes
的Controller Manager
负责监听这些事件并触发相应的任务来满足用户的期望。这种方式我们成为声明式,用户只需要关心应用程序的最终状态,其它的都通过Kubernetes
来帮助我们完成,通过这种方式可以大大简化应用的配置管理复杂度。
实现核心点:除了这些原生的Resource
资源以外,Kubernetes
还允许用户添加自己的自定义资源(Custom Resource
),并且通过实现自定义Controller
来实现对Kubernetes
的扩展。
如下所示,是Prometheus Operator
的架构示意图: 上图有两个概念:
- Prometheus:本质就是一组用户自定义的
CRD
资源以及Controller
的实现。 - Prometheus Operator负责监听这些自定义资源的变化,并且根据这些资源的定义自动化的完成如
Prometheus Server
自身以及配置的自动化管理工作。
要了解Prometheus Operator
能做什么,其实就是要了解Prometheus Operator
为我们提供了哪些自定义的Kubernetes
资源,列出了Prometheus Operator
目前提供的️4类资源:
- Prometheus:声明式创建和管理
Prometheus Server
实例; - ServiceMonitor:负责声明式的管理监控配置;
- PrometheusRule:负责声明式的管理告警配置;
- Alertmanager:声明式的创建和管理
Alertmanager
实例。
简言之,Prometheus Operator
能够帮助用户自动化的创建以及管理Prometheus Server
以及其相应的配置。
在Kubernetes
中安装Prometheus Operator
非常简单,用户可以从以下地址中过去Prometheus Operator
的源码:
git clone https://github.com/coreos/prometheus-operator.git
3.2 配置
这里,我们为Promethues Operator
创建一个单独的命名空间monitoring
:
kubectl create namespace monitoring
由于需要对Prometheus Operator
进行RBAC
授权,而默认的bundle.yaml
中使用了default
命名空间,因此,在安装Prometheus Operator
之前需要先替换一下bundle.yaml
文件中所有namespace
定义,由default
修改为monitoring
,通过运行以下命令安装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
service/prometheus-operator created
Prometheus Operator
通过Deployment
的形式进行部署,目的是让Prometheus Operator
能够监听和管理Kubernetes
资源同时也创建了单独的ServiceAccount
以及相关的授权动作。
查看Prometheus Operator
部署状态,以确保已正常运行:
$ kubectl -n monitoring get pods
NAME READY STATUS RESTARTS AGE
prometheus-operator-6db8dbb7dd-2hz55 1/1 Running 0 19s
04 Prometheus Operator的使用
4.1 Operator管理Prometheus
4.1.1 创建Prometheus实例
当集群中已经安装Prometheus Operator
之后,对于部署Prometheus Server
实例就变成了声明一个Prometheus
资源,如下所示,我们在Monitoring
命名空间下创建一个Prometheus
实例:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: inst
namespace: monitoring
spec:
resources:
requests:
memory: 400Mi
将以上内容保存到prometheus-inst.yaml
文件,并通过kubectl
进行创建:
$ kubectl create -f prometheus-inst.yaml
prometheus.monitoring.coreos.com/inst-1 created
此时,查看monitoring
命名空间下的statefulsets
资源,可以看到Prometheus Operator
自动通过Statefulset
创建的Prometheus
实例:
$ kubectl -n monitoring get statefulsets
NAME DESIRED CURRENT AGE
prometheus-inst 1 1 1m
查看Pod实例:
$ kubectl -n monitoring get pods
NAME READY STATUS RESTARTS AGE
prometheus-inst-0 3/3 Running 1 1m
prometheus-operator-6db8dbb7dd-2hz55 1/1 Running 0 45m
通过port-forward
访问Prometheus
实例:
$ kubectl -n monitoring port-forward statefulsets/prometheus-inst 9090:9090
通过http://localhost:9090可以在本地直接打开Prometheus Operator
创建的Prometheus
实例,查看配置信息,可以看到目前Operator
创建了只包含基本配置的Prometheus
实例:
修改监控配置项也是Prometheus
下常用的运维操作之一,为了能够自动化的管理Prometheus
的配置,Prometheus Operator
使用了 自定义资源类型ServiceMonitor
来描述监控对象的信息。
这里我们首先在集群中部署一个示例应用,将以下内容保存到example-app.yaml
,并使用kubectl
命令行工具创建:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: example-app
spec:
replicas: 3
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: fabxc/instrumented_app
ports:
- name: web
containerPort: 8080
示例应用会通过Deployment
创建3个Pod
实例:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
example-app-94c8bc8-l27vx 2/2 Running 0 1m
example-app-94c8bc8-lcsrm 2/2 Running 0 1m
example-app-94c8bc8-n6wp5 2/2 Running 0 1m
实例对象通过Service
暴露应用访问信息
kind: Service
apiVersion: v1
metadata:
name: example-app
labels:
app: example-app
spec:
selector:
app: example-app
ports:
- name: web
port: 8080
在本地同样通过port-forward
访问任意Pod
实例:
$ kubectl port-forward deployments/example-app 8080:8080
访问本地的http://localhost:8080/metrics实例应用程序会返回以下样本数据:
# TYPE codelab_api_http_requests_in_progress gauge
codelab_api_http_requests_in_progress 3
# 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
能够采集部署在Kubernetes
下应用的监控数据,在原生的Prometheus
配置方式中,我们在Prometheus
配置文件中定义单独的Job
,同时使用kubernetes_sd
定义整个服务发现过程。
而在Prometheus Operator
中,则可以直接声明一个ServiceMonitor
对象,如下所示:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example-app
namespace: monitoring
labels:
team: frontend
spec:
namespaceSelector:
matchNames:
- default
selector:
matchLabels:
app: example-app
endpoints:
- 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/v1
kind: ServiceMonitor
metadata:
name: example-app
namespace: monitoring
labels:
team: frontend
spec:
namespaceSelector:
matchNames:
- default
selector:
matchLabels:
app: example-app
endpoints:
- basicAuth:
password:
name: basic-auth
key: password
username:
name: basic-auth
key: user
port: web
其中basicAuth
中关联了名为basic-auth
的Secret
对象,用户需要手动将认证信息保存到Secret
中:
apiVersion: v1
kind: Secret
metadata:
name: basic-auth
data:
password: dG9vcg== # base64编码后的密码
user: YWRtaW4= # base64编码后的用户名
type: Opaque
4.1.3 关联Promethues与ServiceMonitor
为了能够让Prometheus
关联到ServiceMonitor
,需要在Pormtheus
定义中使用serviceMonitorSelector
,我们可以通过标签选择当前Prometheus
需要监控的ServiceMonitor
对象,修改prometheus-inst.yaml
中Prometheus
的定义如下所示:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: inst
namespace: monitoring
spec:
serviceMonitorSelector:
matchLabels:
team: frontend
resources:
requests:
memory: 400Mi
将对Prometheus
的变更应用到集群中:
$ kubectl -n monitoring apply -f prometheus-inst.yaml
此时,如果查看Prometheus
配置信息,我们会惊喜的发现Prometheus
中配置文件自动包含了一条名为monitoring/example-app/0
的Job
配置:
global:
scrape_interval: 30s
scrape_timeout: 10s
evaluation_interval: 30s
external_labels:
prometheus: monitoring/inst
prometheus_replica: prometheus-inst-0
alerting:
alert_relabel_configs:
- separator: ;
regex: prometheus_replica
replacement: $1
action: labeldrop
rule_files:
- /etc/prometheus/rules/prometheus-inst-rulefiles-0/*.yaml
scrape_configs:
- job_name: monitoring/example-app/0
scrape_interval: 30s
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
kubernetes_sd_configs:
- role: endpoints
namespaces:
names:
- default
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_app]
separator: ;
regex: example-app
replacement: $1
action: keep
- source_labels: [__meta_kubernetes_endpoint_port_name]
separator: ;
regex: web
replacement: $1
action: keep
- source_labels: [__meta_kubernetes_endpoint_address_target_kind, __meta_kubernetes_endpoint_address_target_name]
separator: ;
regex: Node;(.*)
target_label: node
replacement: ${1}
action: replace
- source_labels: [__meta_kubernetes_endpoint_address_target_kind, __meta_kubernetes_endpoint_address_target_name]
separator: ;
regex: Pod;(.*)
target_label: pod
replacement: ${1}
action: replace
- source_labels: [__meta_kubernetes_namespace]
separator: ;
regex: (.*)
target_label: namespace
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_service_name]
separator: ;
regex: (.*)
target_label: service
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_pod_name]
separator: ;
regex: (.*)
target_label: pod
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_service_name]
separator: ;
regex: (.*)
target_label: job
replacement: ${1}
action: replace
- separator: ;
regex: (.*)
target_label: endpoint
replacement: web
action: replace
不过,如果细心的读者可能会发现,虽然Job
配置有了,但是Prometheus
的Target
中并没包含任何的监控对象。查看Prometheus
的Pod
实例日志,可以看到如下信息:
level=error ts=2018-12-15T12:52:48.452108433Z caller=main.go:240 component=k8s_client_runtime err="github.com/prometheus/prometheus/discovery/kubernetes/kubernetes.go:300: Failed to list *v1.Endpoints: endpoints is forbidden: User
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?