微信公众号搜索 DevOps和k8s全栈技术 ,关注之后,在后台回复 k8s视频,还可获取k8s免费视频和文档,也可扫描文章最后的二维码关注公众号。
prometheus完整视频如下:
https://edu.51cto.com/sd/76993
什么是Prometheus Operator?
为了在Kubernetes中能够方便管理和部署Prometheus,我们使用ConfigMap管理Prometheus配置文件。每次对Prometheus配置文件进行升级时,我们需要手动移除已经运行的Pod实例,从而让Kubernetes可以使用最新的配置文件创建Prometheus。而如果当应用实例的数量更多时,通过手动的方式部署和升级Prometheus过程繁琐并且效率低下。从本质上来讲Prometheus属于是典型的有状态应用,而其有包含了一些自身特有的运维管理和配置管理方式。而这些都无法通过Kubernetes原生提供的应用管理概念实现自动化。为了简化这类应用程序的管理复杂度,CoreOS率先引入了Operator的概念,并且首先推出了针对在Kubernetes下运行和管理Etcd的Etcd Operator。并随后推出了Prometheus 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能做什么,其实就是要了解Prometheus Operator为我们提供了哪些自定义的Kubernetes资源,列出了Prometheus Operator目前提供的️4类资源:
Prometheus:声明式创建和管理Prometheus Server实例;
ServiceMonitor:负责声明式的管理监控配置;
PrometheusRule:负责声明式的管理告警配置;
Alertmanager:声明式的创建和管理Alertmanager实例。
简言之,Prometheus Operator能够帮助用户自动化的创建以及管理Prometheus Server以及其相应的配置。
在k8s集群中部署Prometheus Operator
以下步骤均在k8s的master节点操作
在Kubernetes中安装Prometheus Operator非常简单,用户可以从以下地址中过去Prometheus Operator的源码:
git clone https://github.com/coreos/prometheus-operator.git
上面git下来的是一个文件夹prometheus-operator,这个我已经打包成了一个压缩包,压缩包含有之后实验的所有文件,大家可以在百度网盘下载,然后上传到自己的k8s master节点,解压,参考下即可,压缩包在百度网盘地址如下:
链接:https://pan.baidu.com/s/10klyCGya4bQxrmtpxqnyHQ
提取码:cd33
这里,我们为Promethues Operator创建一个单独的命名空间monitoring:
kubectl create namespace monitoring
由于需要对Prometheus Operator进行RBAC授权,而默认的bundle.yaml中使用了default命名空间,因此,在安装Prometheus Operator之前需要先替换一下bundle.yaml文件中所有namespace定义,由default修改为monitoring。通过运行一下命令安装Prometheus Operator的Deployment实例:
cd prometheus-operator/
kubectl -n monitoring apply -f bundle.yaml
Prometheus Operator通过Deployment的形式进行部署,为了能够让Prometheus Operator能够监听和管理Kubernetes资源同时也创建了单独的ServiceAccount以及相关的授权动作。
查看Prometheus Operator部署状态,以确保已正常运行:
kubectl -n monitoring get pods
显示如下,说明pod部署成功:
NAME READY STATUS RESTARTS AGE
prometheus-operator-5974fc7c56-7zr88 1/1 Running 0 63s
注:如果报错ImagePullBackOff,表示不能拉取prometheus-operator镜像,可以把prometheus-operator.tar.gz压缩包上传到k8s的node节点,手动解压即可
docker load -i prometheus-operator.tar.gz
镜像所在的百度网盘地址如下:
链接:https://pan.baidu.com/s/1zCFuQXVGrF3sdy8XiDGQMQ
提取码:5hdu
然后再执行如下即可
kubectl -n monitoring delete -f bundle.yaml
kubectl -n monitoring apply -f bundle.yaml
创建Prometheus实例
当集群中已经安装Prometheus Operator之后,对于部署Prometheus Server实例就变成了声明一个Prometheus资源,如下所示,我们在Monitoring命名空间下创建一个Prometheus实例:
cat prometheus-inst.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: inst
namespace: monitoring
spec:
resources:
requests:
memory: 400Mi
将以上内容保存到prometheus-inst.yaml文件,并通过kubectl进行创建:
kubectl apply -f prometheus-inst.yaml
此时,查看monitoring命名空间下的statefulsets资源,可以看到Prometheus Operator自动通过Statefulset创建的Prometheus实例:
kubectl -n monitoring get statefulset
显示如下,说明部署成功了:
NAME READY AGE
prometheus-inst 1/1 56s 50m
查看pod实例:
kubectl -n monitoring get pods
显示如下,说明部署成功了:
NAME READY STATUS RESTARTS AGE
prometheus-inst-0 3/3 Running 1 2m
prometheus-operator-5974fc7c56-7zr88 1/1 Running 0 50m
注:如果报错ErrImagePull,表示不能拉取prometheus镜像,可以把镜像压缩包prometheus-v2_17_2.tar.gz、prometheus-config-reloader_v0_39_0.tar.gz、configmap-reload_v0_3_0.tar.gz上传到k8s的node节点,手动解压:
docker load -i prometheus-v2_17_2.tar.gz
docker load -i prometheus-config-reloader_v0_39_0.tar.gz
docker load -i configmap-reload_v0_3_0.tar.gz
镜像所在的百度网盘地址如下:
链接:https://pan.baidu.com/s/1zCFuQXVGrF3sdy8XiDGQMQ
提取码:5hdu
然后再执行如下即可
kubectl delete -f prometheus-inst.yaml
kubectl apply -f prometheus-inst.yaml
为prometheus实例创建service,以便在浏览器访问:
cat prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: prometheus-operator
name: prometheus-operator-svc
namespace: monitoring
spec:
ports:
- name: operator
port: 9090
protocol: TCP
targetPort: 9090
selector:
app: prometheus
prometheus: inst
sessionAffinity: None
type: NodePort
更新yaml文件:
kubectl apply -f prometheus-service.yaml
查看service详细信息:
kubectl get svc -n monitoring
显示如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
prometheus-operated ClusterIP None 9090/TCP 77m
prometheus-operator ClusterIP None 8080/TCP 126m
prometheus-operator-svc NodePort 10.108.151.60 9090:31535/TCP 35s
看到最后一行prometheus-operator-svc的type类型是NodePort,在宿主机暴露的端口是31535,我们通过浏览器访问k8s的master ip:31535即可访问到prometheus ui界面,我这里k8s的master节点ip是192.168.0.6,所以在浏览器访问http://192.168.0.6:31535/config,可以看到目前Operator创建了只包含基本配置的Prometheus实例:
使用ServiceMonitor管理监控配置
修改监控配置项也是Prometheus下常用的运维操作之一,为了能够自动化的管理Prometheus的配置,Prometheus Operator使用了自定义资源类型ServiceMonitor来描述监控对象的信息。这里我们首先在集群中部署一个示例应用,将以下内容保存到example-app.yaml,并使用kubectl命令行工具创建:
cat example-app.yaml
kind: Service
apiVersion: v1
metadata:
name: example-app
labels:
app: example-app
spec:
selector:
app: example-app
ports:
- name: web
port: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
spec:
selector:
matchLabels:
app: example-app
replicas: 3
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: fabxc/instrumented_app
ports:
- name: web
containerPort: 8080
更新yaml文件:
kubectl apply -f example-app.yaml
示例应用会通过Deployment创建3个Pod实例,并且通过Service暴露应用访问信息。
kubectl get pods
显示如下:
NAME READY STATUS RESTARTS AGE
example-app-bb759dfcc-7njwm 1/1 Running 0 110s
example-app-bb759dfcc-8sl77 1/1 Running 0 110s
example-app-bb759dfcc-ckjqf 1/1 Running 0 110s
在本地通过port-forward访问任意Pod实例
kubectl port-forward deployments/example-app 8080:8080
访问本地的http://localhost:8080/metrics实例应用程序会返回以下样本数据:
curl localhost: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 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
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00015000000000000001"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00022500000000000002"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0003375"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.00050625"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.000759375"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0011390624999999999"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0017085937499999998"} 0
codelab_api_request_duration_seconds_bucket{method="GET",path="/api/bar",status="200",le="0.0025628906249999996"} 0
为了能够让Prometheus能够采集部署在Kubernetes下应用的监控数据,在原生的Prometheus配置方式中,我们在Prometheus配置文件中定义单独的Job,同时使用kubernetes_sd定义整个服务发现过程。而在Prometheus Operator中,则可以直接声明一个ServiceMonitor对象,如下所示:
cat example-app-service-monitor.yaml
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可以关联任意命名空间下的标签,则通过以下方式定义:
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
关联Promethues与ServiceMonitor
Prometheus与ServiceMonitor之间的关联关系使用serviceMonitorSelector定义,在Prometheus中通过标签选择当前需要监控的ServiceMonitor对象。修改prometheus-inst.yaml中Prometheus的定义如下所示: 为了能够让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
此时,在浏览http://192.168.0.6:31535/config查看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
honor_timestamps: true
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 \"system:serviceaccount:monitoring:default\" cannot list endpoints in the namespace \"default\""
自定义ServiceAccount
由于默认创建的Prometheus实例使用的是monitoring命名空间下的default账号,该账号并没有权限能够获取default命名空间下的任何资源信息。
为了修复这个问题,我们需要在Monitoring命名空间下为创建一个名为Prometheus的ServiceAccount,并且为该账号赋予相应的集群访问权限。
cat prometheus-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources:
- configmaps
verbs: ["get"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
将以上内容保存到prometheus-rbac.yaml文件中,并且通过kubectl创建相应资源:
kubectl -n monitoring apply -f prometheus-rbac.yaml
在完成ServiceAccount创建后,修改prometheus-inst.yaml,并添加ServiceAccount如下所示:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: inst
namespace: monitoring
spec:
serviceAccountName: prometheus
serviceMonitorSelector:
matchLabels:
team: frontend
resources:
requests:
memory: 400Mi
保存Prometheus变更到集群中:
kubectl -n monitoring apply -f prometheus-inst.yaml
等待Prometheus Operator完成相关配置变更后,此时查看Prometheus,我们就能看到当前Prometheus已经能够正常的采集实例应用的相关监控数据了。
往期精彩文章
kubernetes全栈技术+企业案例演示【带你快速掌握和使用k8s】
kubernetes面试题汇总
DevOps视频和资料免费领取
kubernetes技术分享-可用于企业内部培训
谈谈我的IT发展之路
kubernetes系列文章第一篇-k8s基本介绍
kubernetes系列文章第二篇-kubectl
了解pod和pod的生命周期-这一篇文章就够了
Kubernetes中部署MySQL高可用集群
Prometheus+Grafana+Alertmanager搭建全方位的监控告警系统-超详细文档
k8s1.18多master节点高可用集群安装-超详细中文官方文档
k8s中蓝绿部署、金丝雀发布、滚动更新汇总
运维常见问题汇总-tomcat篇
关于linux内核参数的调优,你需要知道
测试通过storageclass动态生成pv
kubernetes持久化存储volume
kubernetes挂载ceph rbd和cephfs
报警神器Alertmanager发送报警到多个渠道
jenkins+kubernetes+harbor+gitlab构建企业级devops平台
Prometheus监控Redis
Prometheus监控MySQL
Prometheus监控Tomcat
kubernetes网络插件-flannel篇
kubernetes网络插件-calico篇
kubernetes认证、授权、准入控制
限制不同的用户操作k8s的资源
面试真题&技术资料免费领取-覆盖面超全~
linux面试题汇总
通过编写k8s的资源清单yaml文件部署gitlab服务
helm安装和使用-通过helm部署k8s应用
扫码加群????
微信:luckylucky421302
长按指纹关注公众号????
点击在看少个 bug????