Prometheus监控K8S集群
Prometheus受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Brog系统演变而来),从2012年开始由前Google工程师在Soundcloud以开源软件的形式进行研发,并且于2015年早期对外发布早期版本。2016年5月继Kubernetes之后成为第二个正式加入CNCF基金会的项目,同年6月正式发布1.0版本。2017年底发布了基于全新存储层的2.0版本,能更好地与容器平台、云平台配合。
Prometheus简史
Prometheus作为新一代的云原生监控系统,目前已经有超过650+位贡献者参与到Prometheus的研发工作上,并且超过120+项的第三方集成。
监控的目标
在《SRE: Google运维解密》一书中指出,监控系统需要能够有效的支持白盒监控和黑盒监控。通过白盒能够了解其内部的实际运行状态,通过对监控指标的观察能够预判可能出现的问题,从而对潜在的不确定因素进行优化。而黑盒监控,常见的如HTTP探针,TCP探针等,可以在系统或者服务在发生故障时能够快速通知相关的人员进行处理。通过建立完善的监控体系,从而达到以下目的:
长期趋势分析:
通过对监控样本数据的持续收集和统计,对监控指标进行长期趋势分析。例如,通过对磁盘空间增长率的判断,我们可以提前预测在未来什么时间节点上需要对资源进行扩容。
对照分析:
两个版本的系统运行资源使用情况的差异如何?在不同容量情况下系统的并发和负载变化如何?通过监控能够方便的对系统进行跟踪和比较。
告警:
当系统出现或者即将出现故障时,监控系统需要迅速反应并通知管理员,从而能够对问题进行快速的处理或者提前预防问题的发生,避免出现对业务的影响。
故障分析与定位:
当问题发生后,需要对问题进行调查和处理。通过对不同监控监控以及历史数据的分析,能够找到并解决根源问题。
数据可视化:
通过可视化仪表盘能够直接获取系统的运行状态、资源使用情况、以及服务运行状态等直观的信息。
与常见监控系统比较
对于常用的监控系统,如Nagios、Zabbix的用户而言,往往并不能很好的解决上述问题。这里以Nagios为例,如下图所示是Nagios监控系统的基本架构:
Nagios监控系统
Nagios的主要功能是监控服务和主机。Nagios软件需要安装在一台独立的服务器上运行,该服务器称为监控中心。每一台被监控的硬件主机或者服务都需要运行一个与监控中心服务器进行通信的Nagios软件后台程序,可以理解为Agent或者插件。
Nagios主机监控页面
首先对于Nagios而言,大部分的监控能力都是围绕系统的一些边缘性的问题,主要针对系统服务和资源的状态以及应用程序的可用性。 例如:Nagios通过check_disk插件可以用于检查磁盘空间,check_load用于检查CPU负载等。这些插件会返回4种Nagios可识别的状态,0(OK)表示正常,1(WARNING)表示警告,2(CRITTCAL)表示错误,3(UNKNOWN)表示未知错误,并通过Web UI显示出来。
对于Nagios这类系统而言,其核心是采用了测试和告警(check&alert)的监控系统模型。 对于基于这类模型的监控系统而言往往存在以下问题:
与业务脱离的监控:
监控系统获取到的监控指标与业务本身也是一种分离的关系。好比客户可能关注的是服务的可用性、服务的SLA等级,而监控系统却只能根据系统负载去产生告警;
运维管理难度大:
Nagios这一类监控系统本身运维管理难度就比较大,需要有专业的人员进行安装,配置和管理,而且过程并不简单;
可扩展性低:
监控系统自身难以扩展,以适应监控规模的变化;
问题定位难度大:
当问题产生之后(比如主机负载异常增加)对于用户而言,他们看到的依然是一个黑盒,他们无法了解主机上服务真正的运行情况,因此当故障发生后,这些告警信息并不能有效的支持用户对于故障根源问题的分析和定位。
Prometheus的优势
Prometheus是一个开源的完整监控解决方案,其对传统监控系统的测试和告警模型进行了彻底的颠覆,形成了基于中央化的规则计算、统一分析和告警的新模型。 相比于传统监控系统Prometheus具有以下优点:
易于管理
Prometheus核心部分只有一个单独的二进制文件,不存在任何的第三方依赖(数据库,缓存等等)。唯一需要的就是本地磁盘,因此不会有潜在级联故障的风险。
Prometheus基于Pull模型的架构方式,可以在任何地方(本地电脑,开发环境,测试环境)搭建我们的监控系统。对于一些复杂的情况,还可以使用Prometheus服务发现(Service Discovery)的能力动态管理监控目标。
监控服务的内部运行状态
Pometheus鼓励用户监控服务的内部状态,基于Prometheus丰富的Client库,用户可以轻松的在应用程序中添加对Prometheus的支持,从而让用户可以获取服务和应用内部真正的运行状态。
注意:本实验在K8S集群上部署
本实验K8S集群为1.22,适配的kube-prometheus为v0.10.0
实验
在github上下载kube-prometheus包
wget https://github.com/prometheus-operator/kube-prometheus/archive/refs/tags/v0.10.0.tar.gz
解压包
[root@k8s-master ~]# tar -xf v0.10.0.tar.gz
[root@k8s-master ~]# mv kube-prometheus-0.10.0 kube-prometheus
进入目录
[root@k8s-master ~]# cd kube-prometheus
[root@k8s-master kube-prometheus]# ls
build.sh docs jsonnet manifests
CHANGELOG.md example.jsonnet jsonnetfile.json README.md
code-of-conduct.md examples jsonnetfile.lock.json RELEASE.md
CONTRIBUTING.md experimental kustomization.yaml scripts
DCO go.mod LICENSE sync-to-internal-registry.jsonnet
developer-workspace go.sum Makefile tests
可以看到有个manifests目录这里面是我们所需的yaml
[root@k8s-master kube-prometheus]# cd manifests/
[root@k8s-master manifests]# ls
会看到一个setup的文件夹
我们先执行这个文件夹这个里面会为我们创建命名空间
和一些基础清单
[root@k8s-master manifests]# kubectl create -f setup/
持久化挂载
修改grafana持久化配置
由于 Grafana 是部署模式为 Deployment,所以我们提前为其创建一个 grafana-pvc.yaml 文件,加入下面 PVC 配置。
目录:manifests/grafana-pvc.yaml
完整内容如下:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: grafana
namespace: monitoring #---指定namespace为monitoring
spec:
storageClassName: hostpath #---指定StorageClass
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
接着修改 grafana-deployment.yaml 文件设置持久化配置,应用上面的 PVC(目录:manifests/grafana-deployment.yaml)
修改内容如下:
serviceAccountName: grafana
volumes:
- name: grafana-storage # 新增持久化配置
persistentVolumeClaim:
claimName: grafana # 设置为创建的PVC名称
# - emptyDir: {} # 注释旧的注释
# name: grafana-storage
- name: grafana-datasources
secret:
secretName: grafana-datasources
修改prometheus的yaml文件修改端口暴露为nodeport模式
为了能从外网访问
[root@k8s-master manifests]# vi prometheus-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: prometheus
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 2.32.1
name: prometheus-k8s
namespace: monitoring
spec:
type: NodePort
ports:
- name: web
port: 9090
targetPort: web
nodePort: 30000
selector:
app.kubernetes.io/component: prometheus
app.kubernetes.io/instance: k8s
app.kubernetes.io/name: prometheus
app.kubernetes.io/part-of: kube-prometheus
sessionAffinity: ClientIP
修改grafana的yaml
[root@k8s-master manifests]# vi grafana/grafana-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 8.3.3
name: grafana
namespace: monitoring
spec:
type: NodePort
ports:
- name: http
port: 3000
targetPort: http
nodePort: 31000
selector:
app.kubernetes.io/component: grafana
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: kube-prometheus
修改alertmanager的yaml
[root@k8s-master manifests]# vi alertmanager/alertmanager-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: alert-router
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 0.23.0
name: alertmanager-main
namespace: monitoring
spec:
type: NodePort
ports:
- name: web
port: 9093
targetPort: web
nodePort: 32000
- name: reloader-web
port: 8080
targetPort: reloader-web
selector:
app.kubernetes.io/component: alert-router
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
app.kubernetes.io/part-of: kube-prometheus
sessionAffinity: ClientIP
alertmanger报警配置
[root@k8s-master manifests]# vi alertmanager-secret.yaml
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/component: alert-router
app.kubernetes.io/instance: main
app.kubernetes.io/name: alertmanager
app.kubernetes.io/part-of: kube-prometheus
app.kubernetes.io/version: 0.23.0
name: alertmanager-main
namespace: monitoring
stringData:
alertmanager.yaml: |-
global:
resolve_timeout: 1m # 处理超时时间
smtp_smarthost: 'smtp.qq.com:465' # 邮箱smtp服务器代理
smtp_from: '3327876250@qq.com' # 发送邮箱名称
smtp_auth_username: '3327876250@qq.com' # 邮箱名称
smtp_auth_password: 'xxxxxxxxxx' # 授权密码
smtp_require_tls: false # 不开启tls 默认开启
receivers:
- name: Default
email_configs: # 邮箱配置
- to: "3327876250@qq.com" # 接收警报的email配置
route:
group_interval: 10s # 在发送新警报前的等待时间
group_wait: 10s # 最初即第一次等待多久时间发送一组警报的通知
receiver: Default
repeat_interval: 10s # 发送重复警报的周期
type: Opaque
注意:因为是从外网dockehub拉取镜像,所以有的镜像可能会拉取失败
有两种方式一种是手动上传,一种是修改拉取的源
手动load镜像这是我执行yaml后没有拉取到的镜像
两台都执行
wget http://112.124.71.174:12130/kube-state-metrics_v2.3.0.tar
wget http://112.124.71.174:12130/prometheus-adapter_v0.9.1.tar
docker load -i kube-state-metrics_v2.3.0.tar
docker load -i prometheus-adapter_v0.9.1.tar
或者这样修改拉取的镜像源
[root@work manifests]# sed -i 's|quay.io|quay.mirrors.ustc.edu.cn|g' *.yaml
[root@work manifests]# grep -ir 'image: '
alertmanager-alertmanager.yaml: image: quay.mirrors.ustc.edu.cn/prometheus/alertmanager:v0.23.0
blackboxExporter-deployment.yaml: image: quay.mirrors.ustc.edu.cn/prometheus/blackbox-exporter:v0.19.0
blackboxExporter-deployment.yaml: image: jimmidyson/configmap-reload:v0.5.0
blackboxExporter-deployment.yaml: image: quay.mirrors.ustc.edu.cn/brancz/kube-rbac-proxy:v0.11.0
grafana-deployment.yaml: image: grafana/grafana:8.3.3
kubeStateMetrics-deployment.yaml: image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.3.0
kubeStateMetrics-deployment.yaml: image: quay.mirrors.ustc.edu.cn/brancz/kube-rbac-proxy:v0.11.0
kubeStateMetrics-deployment.yaml: image: quay.mirrors.ustc.edu.cn/brancz/kube-rbac-proxy:v0.11.0
nodeExporter-daemonset.yaml: image: quay.mirrors.ustc.edu.cn/prometheus/node-exporter:v1.3.1
nodeExporter-daemonset.yaml: image: quay.mirrors.ustc.edu.cn/brancz/kube-rbac-proxy:v0.11.0
prometheus-prometheus.yaml: image: quay.mirrors.ustc.edu.cn/prometheus/prometheus:v2.32.1
prometheusAdapter-deployment.yaml: image: k8s.gcr.io/prometheus-adapter/prometheus-adapter:v0.9.1
prometheusOperator-deployment.yaml: image: quay.mirrors.ustc.edu.cn/prometheus-operator/prometheus-operator:v0.53.1
prometheusOperator-deployment.yaml: image: quay.mirrors.ustc.edu.cn/brancz/kube-rbac-proxy:v0.11.0
执行yaml
[root@k8s-master manifests]# kubectl create -f .
新增PrometheusRule资源,定义自己的监控项目
[root@k8s-master manifests]# kubectl edit PrometheusRule kube-prometheus-rules -n monitoring
添加到kube-prometheus-rules
- alert: pod-status
annotations:
message: vv test pod-status
expr: |
kube_pod_container_status_running != 1
for: 1m
labels:
severity: warning
查看所有Pod是否都是Runing状态,所有为Run安装完成
[root@k8s-master manifests]# kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 135m
alertmanager-main-1 2/2 Running 0 135m
alertmanager-main-2 2/2 Running 0 135m
blackbox-exporter-6798fb5bb4-c55f4 3/3 Running 0 137m
grafana-78d8cfccff-hx7zb 1/1 Running 0 136m
kube-state-metrics-5fcb7d6fcb-n8ttf 3/3 Running 0 113m
node-exporter-6prr2 2/2 Running 0 137m
node-exporter-pc6zb 2/2 Running 0 137m
prometheus-adapter-7dc46dd46d-pd8rh 1/1 Running 0 112m
prometheus-adapter-7dc46dd46d-tggtv 1/1 Running 0 112m
prometheus-k8s-0 2/2 Running 0 134m
prometheus-k8s-1 2/2 Running 0 134m
prometheus-operator-7ddc6877d5-vj8tk 2/2 Running 0 137m
登录邮箱查看报警
评论区