云原生k8s11 监控与告警实战(mysql,haproxy,nginx,Ingress-Controller,kafka,etcd), blackbox_exporter, Alertmanager各种告警规则参考及告警模板告警通知, 告警抑制与静默, 监控K8S核心组件:master节点api-server,controller-manager,kube-scheduler指标
监控案例:Prometheus监控MySQL
二进制部署mysql并基于mysql_exporter实现指标采集
#安装mysql: root@prometheus-server2:~# apt install mariadb-server root@prometheus-server2:~# vim /etc/mysql/mariadb.conf.d/50-server.cnf bind-address = 0.0.0.0 root@prometheus-server2:~# systemctl restart mysqld.service #授权监控账户权限: (从本机访问,收集指标信息) root@prometheus-server2:~# mysql MariaDB [(none)]> CREATE USER 'mysql_exporter'@'localhost' IDENTIFIED BY 'imnot007*'; MariaDB [(none)]> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'mysql_exporter'@'localhost'; MariaDB [(none)]> flush privileges; #验证权限: root@prometheus-server2:~# mysql -umysql_exporter -pimnot007* -hlocalhost #准备mysqld_exporter环境: #官方下载地址,mysqld_exporter-0.19.0.linux-amd64.tar.gz官方编译好的二进制,可以直接拿来用 https://github.com/prometheus/mysqld_exporter/releases #确保可以执行 mysqld_exporter --help root@prometheus-server2:/usr/local/src# tar xvf mysqld_exporter-0.19.0.linux-amd64.tar.gz root@prometheus-server2:/usr/local/src# mv mysqld_exporter-0.19.0.linux-amd64/mysqld_exporter /usr/local/bin/ #配置mysqld_exporter 免密码登录mysql配置,让mysqld_exporter连接mysql: root@prometheus-server2:/usr/local/src# vim /root/.my.cnf [client] user=mysql_exporter password=imnot007* #启动命令: (启动后会收集mysql指标,收集的指标事固定的;要改指标要修改源码,重新编译) #/usr/local/bin/mysqld_exporter --config.my-cnf=/root/.my.cnf #访问9104端口可以看到收集的指标 #编写mysql_exporter service文件: root@prometheus-server2:~# vim /etc/systemd/system/mysqld_exporter.service [Unit] Description=Prometheus Node Exporter After=network.target [Service] ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/root/.my.cnf [Install] WantedBy=multi-user.target root@prometheus-server2:~# systemctl daemon-reload && systemctl restart mysqld_exporter && systemctl enable mysqld_exporter #prometheus采集数据: root@prometheus-server1:/apps/prometheus# vim prometheus.yml - job_name: mysql-monitor-172.31.2.182 static_configs: - targets: ['172.31.2.182:9104'] root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #导入grafana 模板验证 grafana导入模板:11323 grafana导入模板:13106
#这里准备一个干净的k8s环境 #创建存储类sc root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql/0.storageclass# ls 1-rbac.yaml 2-storageclass.yaml 3-nfs-provisioner.yaml root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql/0.storageclass# vim 3-nfs-provisioner.yaml ... env: - name: PROVISIONER_NAME value: k8s-sigs.io/nfs-subdir-external-provisioner - name: NFS_SERVER value: 10.0.0.107 - name: NFS_PATH value: /data/volumes volumes: - name: nfs-client-root nfs: server: 10.0.0.107 path: /data/volumes #看下nfs环境有没有 root@k8s-ha1:~# vim /etc/exports /data/k8sdata *(rw,no_root_squash) /data/volumes *(rw,no_root_squash) root@k8s-ha1:~# ll /data/volumes/ root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql/0.storageclass# kubectl apply -f 1-rbac.yaml -f 2-storageclass.yaml -f 3-nfs-provisioner.yaml #创建mysql,其中要在mysql-statefulset.yaml追加mysql-exporter root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# vim 5.mysql-statefulset.yaml ... containers: #追加mysql-exporter,它就是连到mysql收集容器中mysql指标 ...#一个pod3个容器,mysql,xtrabackup,mysql-exporter - name: mysql-exporter #只收集当前mysql容器,如果多副本,每个exporter收集自己的 image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/mysqld-exporter:v0.15.1 args: - "--mysqld.username=mysql_exporter" #使用哪个账号连到库上 - "--mysqld.address=localhost:3306" #库的地址 - "--web.listen-address=:9104" #监听端口 - "--config.my-cnf=/data/.my.cnf" #认证配置文件 volumeMounts: - name: mysql-exporter-configmap mountPath: /data/ volumes: - name: conf emptyDir: {} - name: config-map configMap: name: mysql - name: mysql-exporter-configmap configMap: name: mysql-exporter-configmap items: - key: mysql-exporter-map path: .my.cnf #上面指定的.my.cnf内容 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# vim 4.mysql-exporter-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: mysql-exporter-configmap namespace: magedu labels: app: mysql-exporter-configmap data: mysql-exporter-map: | [client] user=mysql_exporter password=imnot007* root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# kubectl create ns magedu root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# kubectl apply -f 1.mysql-configmap.yaml -f 2.mysql-services.yaml -f 3.mysql-secret.yaml -f 4.mysql-exporter-configmap.yaml root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# kubectl apply -f 5.mysql-statefulset.yaml #进入mysql授权监控账户权限: #注意,要在主库里操作 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/3.mysql# kubectl exec -it mysql-0 bash -n magedu -c mysql -- bash root@mysql-0:/# mysql -uroot -p12345678 MariaDB [(none)]> CREATE USER 'mysql_exporter'@'localhost' IDENTIFIED BY 'imnot007*'; MariaDB [(none)]> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'mysql_exporter'@'localhost'; mysql> create database myserver; #验证权限: root@mysql-0:/# mysql -umysql_exporter -pimnot007* -hlocalhost mysql> show databases; #测试查看主、副mysql对应pod的监控指标 #curl 10.200.195.4:9104/metrics #把cadvisor,node-exporter装好 root@ubuntu101:~/1.prometheus-case-files# kubectl apply -f case1-daemonset-deploy-cadvisor.yaml -f case2-daemonset-deploy-node-exporter.yaml #转Prometheus,要做下账号赋权 #创建监控账号 root@ubuntu101:~/1.prometheus-case-files# kubectl create serviceaccount monitor -n monitoring #对 monitoring 账号授权 root@ubuntu101:~/1.prometheus-case-files# kubectl create clusterrolebinding monitor-clusterrolebinding -n monitoring --clusterrole=cluster-admin --serviceaccount=monitoring:monitor root@ubuntu101:~/1.prometheus-case-files# kubectl apply -f case3-1-prometheus-cfg.yaml -f case3-2-prometheus-deployment.yaml -f case3-3-prometheus-svc.yaml #登录Prometheus地址 http://10.0.0.101:39090/targets #在target health中service-endpoints可以看到mysql(mysql的statefulset没配,svc中配置了自动发现,所以通过endpoints可以看到) #部署grafana root@ubuntu101:~/1.prometheus-case-files# vim case5-grafana.yaml root@ubuntu101:~/1.prometheus-case-files# kubectl apply -f case5-grafana.yaml root@ubuntu101:~/1.prometheus-case-files# kubectl apply -f case6-kube-state-metrics-deploy.yaml #访问grafana admin/admin http://10.0.0.101:33000/login #导入grafana 模板验证 grafana导入模板:11323 grafana导入模板:13106
监控案例:Prometheus监控HAProxy;
通过haproxy_exporter监控haproxy (haproxy_exporter通过haproxy状态页抓指标)
https://github.com/prometheus/haproxy_exporter
部署haproxy:
root@k8s-ha1:~# apt-cache madison haproxy root@k8s-ha1:~# apt install haproxy #开启状态页 (如果是采集本机,可使用sock监控,sock文件地址在配置中) root@k8s-ha1:~# vim /etc/haproxy/haproxy.cfg listen stats bind :8899 stats enable #stats hide-version stats uri /haproxy-status #状态页路径 stats realm HAPorxy\ Stats\ Page #状态页面 stats auth haadmin:123456 #登录认证,自己设置(登录就是管理员,不支持详细权限控制) stats auth admin:123456 root@k8s-ha1:~# systemctl restart haproxy.service #测试登录状态页 admin:123456(账号密码配的两个都可以) 172.31.7.109:8899/haproxy-status
监控Haproxy:
#部署haproxy_exporter: #官网下载二进制文件 root@k8s-ha1:/usr/local/src# tar xvf haproxy_exporter-0.15.0.linux-amd64.tar.gz root@k8s-ha1:/usr/local/src# mv haproxy_exporter-0.15.0.linux-amd64/haproxy_exporter /usr/local/bin/ #测试 root@k8s-ha1:/usr/local/src# haproxy_exporter --help #监听地址9101,暴露地址 /metrics #获取指标 1.启动方式一:#sock文件路径在haproxy.cfg配置中,用于本机获取指标 root@k8s-ha1:/usr/local/src# haproxy_exporter --haproxy.scrape-uri=unix:/run/haproxy/admin.sock #访问收集指标测试下: 172.31.7.109:9191/metrics 2.启动方式二:#通过url,uri前面是账号密码,状态页地址;后表示抓取csv格式,&:终端后台运行 root@k8s-ha1:/usr/local/src# haproxy_exporter --haproxy.scrape-uri="http://haadmin:123456@127.0.0.1:8899/haproxy-status;csv" &
prometheus添加job:
root@prometheus-server1:/apps/prometheus# vim prometheus.yml - job_name: 'haproxy-monitor-metrics' static_configs: - targets: ['172.31.7.109:9101'] root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service grafana导入模版12030 grafana导入模版367
1.在云主机编译安装nginx,然后通过prometheus实现监控
2.自定义nginx容器镜像、并基于kubernetes运行nginx,然后通过prometheus实现监控
nginx显示的状态页不是Prometheus支持的格式,所以中间要个exporter序列化成Prometheus格式,但nginx在0.17版本开始,内部的nginx-module-vts模块直接支持Prometheus的指标了(exporter方式还能用)

nginx-module-vts这个模块要在编译nginx的时候打进去
监控单机, docker 环境Nginx:
配置流程: 编译安装nginx、添加nginx-module-vts模块 编辑nginx配置并验证指标数据 安装nginx exporter并验证数据 配置prometheus收集nginx指标数据 grafana导入模板验证数据 通过prometheus监控nginx: 需要在编译安装nginx的时候添加nginx-module-vts模块,github地址:https://github.com/vozlt/nginx-module-vts root@prometheus-node2:~# cd /usr/local/src/ #下载内核源码,克隆或下载,后解压,后续以模块形式加载到nginx中 root@prometheus-node2:/usr/local/src# git clone https://github.com/vozlt/nginx-module-vts.git root@prometheus-node2:/usr/local/src# unzip nginx-module-vts-0.2.5.zip #下载nginx源码,重新编译下 root@prometheus-node2:/usr/local/src# wget https://nginx.org/download/nginx-1.30.0.tar.gz root@prometheus-node2:/usr/local/src# apt install iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev gcc openssh-server iotop unzip zip make root@prometheus-node2:/usr/local/src# tar xvf nginx-1.30.0.tar.gz && cd nginx-1.30.0/ #编译nginx root@prometheus-server2:/usr/local/src/nginx-1.24.0# ./configure --prefix=/apps/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-file-aio \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --add-module=/usr/local/src/nginx-module-vts-0.2.5 #要加入,否则不支持 root@prometheus-node2:/usr/local/src/nginx-1.22.1# make && make install 编辑nginx配置文件: root@prometheus-node2:/usr/local/src/nginx-1.24.0# vim /apps/nginx/conf/nginx.conf http { ... #gzip on; vhost_traffic_status_zone; #启用状态页(改后nginx -t验证配置有没有问题) ... server { ... location /status { #追加状态页 vhost_traffic_status_display; vhost_traffic_status_display_format html; } } #检测下语法 root@prometheus-node2:/# /apps/nginx/sbin/nginx -t #启动(之前启动就 nginx -s reload) root@prometheus-node2:/# /apps/nginx/sbin/nginx #访问nginx和statues页面 172.31.2.182/status #json格式输出 172.31.2.182/status/json #支持prometheus格式输出(所以直接让prometheus收集这个路径也行) 172.31.2.182/status/format/prometheus
部署nginx-vts-exporter:
root@prometheus-node2:/usr/local/src# wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz root@prometheus-node2:/usr/local/src# tar xvf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz root@prometheus-node2:/usr/local/src# cp nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter /usr/local/bin/ #指定nginx状态页地址,一定要json格式才行,就会收集指标 root@prometheus-node2:/usr/local/src# nginx-vts-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json #这时访问9913就可以看到指标 172.31.2.182:9913/metrics #写个service文件,一直收集 root@prometheus-server2:/usr/local/src# cat /etc/systemd/system/nginx-vts-exporter.service [Unit] Description=nginx-vts-exporter After=network.target [Service] ExecStart=/usr/local/bin/nginx-vts-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json [Install] WantedBy=multi-user.target #验证nginx-vts-exporter数据: root@prometheus-server2:/usr/local/src# systemctl start nginx-vts-exporter.service && systemctl enable nginx-vts-exporter.service
prometheus配置数据采集:
root@prometheus-server1:/apps/prometheus# vim prometheus.yml - job_name: 'nginx-metrics static_configs: - targets: ['172.31.2.182:9913'] root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #grafana导入模板 2949
#先打镜像 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/1.nginx-image# vim Dockerfile #FROM ubuntu:22.04 FROM registry.cn-hangzhou.aliyuncs.com/myhubregistry/ubuntu:24.04.3-base LABEL maintainer="Jack <2973707860@qq..com>" \ version="1.0" \ description="This is a myserver project image" #换源 ADD ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources ARG NGINX_VERSION=1.30.0 #生成环境变量 ADD nginx-${NGINX_VERSION}.tar.gz /usr/local/src/ #加入源码包 #后面不用nginx-vtx-exporter也行 ADD nginx-vtx-exporter_0.10.8_linux_amd64/nginx-vtx-exporter /usr/local/bin/ ADD nginx-module-vts-0.2.5 /usr/local/src/nginx-module-vts-0.2.5 #RUN apt update && apt install -y iproute2 gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make RUN apt update && apt install -y openssl libssl-dev iproute2 tzdata locales fonts-noto-cjk wget unzip telnet net-tools gcc iotop zip make iputils-ping libpcre3 libpcre3-dev procps fonts-noto-cjk curl vim libpcre2-dev zlib1g-dev && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #用普通用户启动nginx,这个普通用户可加可不加 RUN groupadd -r -g 2088 user1 && useradd -r -m -s /sbin/nologin -u 2088 -g 2088 user1 #编译 WORKDIR /usr/local/src/ RUN cd nginx-${NGINX_VERSION}/ && ./configure --prefix=/apps/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-file-aio \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --add-module=/usr/local/src/nginx-module-vts-0.2.5 && make && make install #做软连接,把日志做标准输出和错误输出,直接logs就能看见 RUN ln -sf /dev/stdout /apps/nginx/logs/access.log && ln -sf /dev/stderr /apps/nginx/logs/error.log RUN echo "alias ll='ls -l'" >> ~/.bashrc && localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 && dpkg-reconfigure -f noninteractive tzdata ENV LANG=zh_CN.utf8 WORKDIR /root ADD docker-entrypoint.sh /usr/local/bin/ RUN ln -s /usr/local/bin/docker-entrypoint.sh /entrypoint.sh # ADD nginx.conf /apps/nginx/conf/nginx.conf #加入配置文件 EXPOSE 80 443 ENTRYPOINT ["docker-entrypoint.sh"] #启动,先把nginx拉起来,再把exporter跑起来 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/1.nginx-image# vim docker-entrypoint.sh #!/bin/bash /apps/nginx/sbin/nginx #/usr/local/bin/nginx-vts-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json /usr/local/bin/nginx-vtx-exporter -nginx.scrape_uri http://127.0.0.1/status/format/json root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/1.nginx-image# cat build-command.sh #!/bin/bash #docker build -t harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.22.1 . nerdctl build -t harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.30.0 . #docker push harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.22.1 nerdctl push harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.30.0 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/1.nginx-image# bash build-command.sh #测试下能不能跑起来 root@ubuntu101:~/#nerdctl run -p 80:80 -it --rm harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.30.0 #部署 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/2.nginx-yaml# vim 1.nginx-deployment.yaml kind: Deployment apiVersion: apps/v1 metadata: labels: app: magedu-nginx-deployment-label name: magedu-nginx-deployment namespace: magedu spec: replicas: 2 selector: matchLabels: app: magedu-nginx-selector template: metadata: labels: app: magedu-nginx-selector project: python spec: containers: - name: magedu-nginx-container image: harbor.myarchitect.online/magedu/nginx-vts-exporter:v1.30.0 #imagePullPolicy: IfNotPresent imagePullPolicy: Always ports: - containerPort: 80 protocol: TCP name: http - containerPort: 443 protocol: TCP name: https root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/2.nginx-yaml# kubectl apply -f 1.nginx-deployment.yaml
收集指标
#上面deployment中pod没加Prometheus注解,所以发现不了,这里在service中加入注解 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/2.nginx-yaml# vim 2.nginx-svc.yaml kind: Service apiVersion: v1 metadata: labels: app: magedu-nginx-service-label name: magedu-nginx-service namespace: magedu annotations: prometheus.io/scrape: 'true' prometheus.io/port: "9913" spec: type: NodePort ports: - name: http port: 80 protocol: TCP targetPort: 80 nodePort: 30014 - name: https port: 443 protocol: TCP targetPort: 443 nodePort: 30453 - name: metrics port: 9913 protocol: TCP targetPort: 9913 nodePort: 39913 selector: app: magedu-nginx-selector root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/4.nginx-vts-exporter/2.nginx-yaml# kubectl apply -f 2.nginx-svc.yaml #grafana中导入模板 2949
#先部署ingress(有deployment和daemonset两种,若业务环境量不大,deployment部署即可) root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/5.ingress-case/1.1-ingress-nginx-1.8.2_deploy-yaml-k8s-v1.27.4# ls 1.ingress-nginx-controller-v1.8.2_daemonset.yaml 1.ingress-nginx-controller-v1.8.2_deployment.yaml #如果部署deployment,最好节点反亲和 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/5.ingress-case/1.1-ingress-nginx-1.8.2_deploy-yaml-k8s-v1.27.4# vim 1.ingress-nginx-controller-v1.8.2_deployment.yaml ... apiVersion: v1 kind: Service metadata: labels: ... name: ingress-nginx-controller namespace: ingress-nginx annotations: #追加,让Prometheus发现ingress controller prometheus.io/scrape: 'true' prometheus.io/port: "10254" root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/5.ingress-case/1.1-ingress-nginx-1.8.2_deploy-yaml-k8s-v1.27.4# kubectl apply -f 1.ingress-nginx-controller-v1.8.2_deployment.yaml #把ingress contrller的端口40080配置到haproxy中(没有https,这里用http) root@k8s-ha1:~# vim /etc/haproxy/haproxy.cfg listen myserver-nginx bind 10.0.0.189:80 mode tcp server k8s-node1 10.0.0.104:40080 check inter 3s fall 3 rise 5 root@k8s-ha1:~# systemctl restart haproxy.service #测试ingress的指标地址,会直接暴露指标。上面指标端口配的是10254 curl ingress对应pod的ip:10254/metrics #查看k8s的Prometheus,能直接发现ingress http://10.0.0.101:39090/targets #grafana导入模板 9614 http://10.0.0.101:33000 #目前还没有数据,ingress后面部署服务既有数据了 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/5.ingress-case# kubectl apply -f tomcat-app1.yaml -f tomcat-app2.yaml #创建ingress规则(通过ingress访问pod来看ingress监控图标) #移动端 root@ubuntu101:~/1.prometheus-case-files/app-monitor-case/5.ingress-case# vim 2.1.ingress_single-mobile.yaml #apiVersion: networking.k8s.io/v1beta1 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: mobile.jiege.com #规则名称 namespace: magedu annotations: kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型 #spec.ingressClassName: "nginx" ##指定Ingress Controller的类型 nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式 nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s nginx.ingress.kubernetes.io/proxy-body-size: "50m" ##客户端上传文件,最大大小,默认为20m #nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写 nginx.ingress.kubernetes.io/app-root: /index.html spec: ingressClassName: nginx rules: - host: mobile.jiege.com http: paths: - pathType: Prefix path: "/" backend: service: name: magedu-tomcat-app2-service port: number: 80

如果有个Prometheus在外面,可以把k8s里面的Prometheus当成联邦节点。外面的Prometheus去采集k8s里面的Prometheus,
再重新展示也行
监控kafka
这里有个项目,容器里面有kafka和exporter,通过kafka exporter收集的kafka指标
#docker-compose文件 version: '3' services: zookeeper-server: container_name: zookeeper-container image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/zookeeper:v3.7.0 restart: always ports: - "2181:2181" volumes: - /etc/localtime:/etc/localtime - zookeeper_vol:/data - zookeeper_vol:/datalog - zookeeper_vol:/logs kafka-server: container_name: kafka-container image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/kafka:2.13-2.8.1 ports: - "9092:9092" environment: #KAFKA_ADVERTISED_HOST_NAME: "172.31.4.3" KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://172.31.4.3:9092 #宿主机ip KAFKA_ADVERTISED_HOST_NAME: 0.0.0.0 KAFKA_ZOOKEEPER_CONNECT: "zookeeper-server:2181" KAFKA_LOG_DIRS: "/kafka/logs" volumes: - /etc/localtime:/etc/localtime - kafka_vol:/kafka restart: always links: - zookeeper-server depends_on: - zookeeper-server kafka_manager: image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/kafka-manager container_name: kafka-manager-container ports: - "9000:9000" environment: ZK_HOSTS: "zookeeper-server:2181" restart: always volumes: - /etc/localtime:/etc/localtime links: - zookeeper-server depends_on: - zookeeper-server - kafka-server kafka-exporter: image: registry.cn-hangzhou.aliyuncs.com/zhangshijie/kafka-exporter:v1.7.0 container_name: kafka-exporter-container volumes: - /etc/localtime:/etc/localtime ports: - "9308:9308" restart: always links:#为exporter服务创建指向kafka-server服务的网络别名,容器内可通过kafka直接访问 - kafka-server:kafka depends_on: - zookeeper-server - kafka-server volumes: zookeeper_vol: kafka_vol: #通过docker-compose部署kafka并通过kafka-exporter实现kafka指标采集: root@k8s-deploy:~# cd /opt/ root@k8s-deploy:/opt# git clone https://gitee.com/jiege-gitee/kafka.git root@k8s-deploy:/opt/kafka# docker-compose pull #如果第一次部署出错了,要注意把zookeeper的卷(zookeeper_vol)和kafka的卷(kafka_vol)删掉,否则影响后面第二次部署 root@k8s-deploy:/opt/kafka# docker-compose up -d #修改kafka监听地址 #docker-compose文件修改,地址改成部署的本机地址,不改起不来 environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://172.31.4.3:9092 #宿主机ip #会创建两个本地卷(zookeeper_vol和kafka_vol,第二次部署要删掉) root@k8s-deploy:/opt/kafka# docker volume ls #如果重新部署删除卷 #docker volume rm kafka_kafka_vol #docker volume rm kafka_zookeeper_vol #起来后,访问kafka管理端kafka_manager,端口号9000 #第一次登录,先添加kafka

#采集kafka通过kafka-exporter,端口好9308 #grafana导入模板 21708

监控etcd
etcd 集群监控:Prometheus 自定义监控 etcd 集群的指标配置与实践(含关键指标解析)
#etcd上有两个证书文件,一个私钥,一个公钥 #指标是etcd自带的,不用使用etcd exporter #要把证书给Prometheus,才能让Prometheus去采集 #验证通过证书可以访问 root@k8s-etcd1:~# curl -k --cert /etc/kubernetes/ssl/etcd.pem --key /etc/kubernetes/ssl/etcd-key.pem https://172.31.7.106:2379/metrics #在Prometheus服务器上,证书分发到prometheus(若Prometheus在k8s里面,可把证书创建成secret) #这里是k8s以外的Prometheus root@prometheus-server1:~# mkdir /data/etcd/certs -p #把etcd证书拷贝过去 root@k8s-etcd1:~# scp /etc/kubernetes/ssl/etcd.pem /etc/kubernetes/ssl/etcd-key.pem 172.31.2.101:/data/etcd/certs #拷贝ca公钥,ca公钥在master上 root@k8s-master2:~# scp /etc/kubernetes/ssl/ca.pem 172.31.2.101:/data/etcd/certs/ #如果是k8s Prometheus环境里,要把这三个证书创建成secret #prometheus配置: root@prometheus-server1:~# vim /apps/prometheus/prometheus.yml - job_name: 'etcd-cluster' metrics_path: /metrics scheme: https #协议 tls_config: #证书配置 ca_file: /data/etcd/certs/ca.pem cert_file: /data/etcd/certs/etcd.pem key_file: /data/etcd/certs/etcd-key.pem static_configs: #地址 - targets: ['172.31.7.106:2379','172.31.7.107:2379','172.31.7.108:2379'] #grafana导入模板 15308, 22236
blackbox_exporter是Prometheus 官方提供的一个exporter,可以监控 HTTP、 HTTPS、DNS、 TCP 、ICMP等目标实例,从而实现对被监控节点进行监控和数据采集。 HTTP/HTPPS:URL/API可用性检测 TCP:端口监听检测 ICMP:主机存活检测 DNS:域名可用 #promethues定义要监控的目标(比如ip通不通), 把监控(要调哪个模块)发给blackbox_exporter。blackbox_exporter根据Prometheus传递的目标和要使用的模块,进行抓取

#部署blackbox_exporter #去promethus.io官网下载blackbox_exporter blackbox_exporter-0.28.0.linux-amd64.tar.gz root@Prometheus-server2:/apps# tar xvf blackbox_exporter-0.28.0.linux-amd64.tar.gz root@Prometheus-server2:/apps# ln -sv /apps/blackbox_exporter-0.28.0.linux-amd64 /apps/blackbox_exporter #写service文件 root@Prometheus-server2:/apps# vim /etc/systemd/system/blackbox-exporter.service [Unit] Description=PrometheusBlackboxExporter After=network.target [Service] Type=simple User=root Group=root ExecStart=/apps/blackbox_exporter/blackbox_exporter\ --config.file=/apps/blackbox_exporter/blackbox.yml\ #配置文件不用改,内有模块名称 --web.listen-address=:9115 Restart=on-failure [Install] WantedBy=multi-user.target #启动后 root@Prometheus-server2:/apps# systemctl start blackbox-exporter.service && systemctl enable blackbox-exporter.service #blackbox-exporter启动后,可以通过9115端口查看
实现URL监控:
#监控http网站(如果Prometheus是k8s的,要修改configmap) root@prometheus-server1:/apps/prometheus# vim /apps/prometheus/prometheus.yml # 网站状态指标采集 - job_name: 'http_status' metrics_path: /probe #指标路径(Prometheus获取指标路径),metric是它自己的指标 params: module: [http_2xx] #模块名称 static_configs: - targets: ['http://www.xiaomi.com', 'http://www.magedu.com'] labels: #自己定义,会把标签加到指标里(可用于后期告警规则) instance: http_status group: web relabel_configs: #标签重写 - source_labels: [__address__] #将__address__(当前监控目标URL地址的标签)修改为__param_target,用于传递给blackbox_exporter target_label: __param_target #标签key为__param_target、value为www.xiaomi.com。key为__param_target、value为www.magedu.com - source_labels: [__address__] #非必须,新添加一个标签,key为url,value来自于__address__的值,用于绘图显示不同的http目标(url) target_label: url #将监控目标的值与url创建一个label - target_label: __address__ #新添加一个目标__address__,指向blackbox_exporter服务器地址,用于将监控请求发送给指定的blackbox_exporter服务器 replacement: 172.31.2.102:9115 #指定blackbox_exporter服务器地址 root@prometheus-server1:/apps/prometheus# ./promtool check config ./prometheus.yml root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #重启后,它就会把目标发给blackbox exporter #在blackbox exporter:9115端口页面可以看到抓取结果,每个域名都有log,包含抓取指标值 #里面包含证书过期时间 probe_ssl_earliest_cert_expiry (秒)
prometheus验证指标抓取状态

blackbox exporter界面验证数据

实现ICMP监控:
root@prometheus-server1:/apps/prometheus# vim /apps/prometheus/prometheus.yml # icmp 指标采集 - job_name: 'ping_status' metrics_path: /probe params: module: [icmp] #模块名 static_configs: - targets: ['172.31.0.2',"223.6.6.6"] #监控目标(若为公有云要放开) labels: instance: 'ping_status' group: 'icmp' relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__address__] #用于grafana显示采集目标 target_label: ip - target_label: __address__ replacement: 172.31.2.102:9115 root@prometheus-server1:/apps/prometheus# ./promtool check config ./prometheus.yml root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #重启后,它就会把目标发给blackbox exporter
#监控端口通不通 root@prometheus-server1:/apps/prometheus# vim /apps/prometheus/prometheus.yml # 端口指标采集 - job_name: 'port_status' metrics_path: /probe params: module: [tcp_connect] static_configs: - targets: ['172.31.2.101:9100', '172.31.2.102:9090','172.31.7.101:22'] labels: instance: 'port_status' group: 'port' relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__address__] #用于grafana显示采集目标 target_label: ip - target_label: __address__ replacement: 172.31.2.102:9115 root@prometheus-server1:/apps/prometheus# ./promtool check config ./prometheus.yml root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #重启后,它就会把目标发给blackbox exporter #grafana导入模版 9965
有个国产告警组件 PrometheusAlert, 比Alertmanager做的好。支持各种告警源和通知对象
prometheus触发一条告警的过程:
prometheus--->指标触发rule中的阈值--->超出持续时间--->alertmanager--->分组|抑制|静默--->媒体类型--->邮件|钉钉|微信等。 分组(group):将类似性质的警报发送给指定的收件人,比如网络通知发给网络工程师、数据库通知发送给 数据库工程师。 静默/沉默(silences):是一种简单的特定时间静音的机制,例如:服务器要升级维护可以先设置这个时间段告警静默。 抑制(inhibition):当警报发出后,停止重复发送由此警报引发的其他警报即合并一个故障引起的多个报警事件,可以消除冗余告警

安装alertermanager:
root@prometheus-server3:/apps# pwd /apps root@prometheus-server3:/apps# wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz root@prometheus-server3:/apps#tar xvf alertmanager-0.26.0.linux-amd64.tar.gz root@prometheus-server3:/apps#ln -sv /apps/alertmanager-0.26.0.linux-amd64 /apps/alertmanager '/apps/alertmanager'->'/apps/alertmanager-0.26.0.linux-amd64' root@prometheus-server3:/apps#vim/etc/systemd/system/alertmanager.service [Unit] Description=Prometheusalertmanager After=network.target [Service] ExecStart=/apps/alertmanager/alertmanager --config.file="/apps/alertmanager/alertmanager.yml" [Install] WantedBy=multi-user.target root@prometheus-server3:/apps#systemctl daemon-reload &&systemctl restart alertmanager&&systemctl enable alertmanager #会监听9093端口,可以登录alertmanager网页,展示当前状态,有没有告警,静默信息 #默认配置文件发不出告警,要自己调整匹配 #如果用docker启动,就用配置文件映射进去。如果k8s启动的话,就写configmap
5.1:邮件通知:
成本低,几乎没有成本,适合有专人值班
https://prometheus.io/docs/alerting/configuration/ #官方配置文档
#操作过程: 1.配置Prometheus的rule 2.配置Prometheus告警时发给谁,发给alertmanager,指定地址 3.配置alertmanager媒介,以什么样的方式发送给谁
# vim /apps/alertmanager/alertmanager.yml global: smtp_from: #发件人邮箱地址 smtp_smarthost: #邮箱 smtp 地址。 smtp_auth_username: #发件人的登陆用户名,默认和发件人地址一致。 smtp_auth_password: #发件人的登陆密码,有时候是授权码。 smtp_require_tls: #是否需要 tls 协议。默认是 true。 wechart_api_url: #企业微信 API 地址。 wechart_api_secret: #企业微信 API secret wechat_api_corp_id: #企业微信 corp id 信息。 resolve_timeout: 60s #当一个告警在 Alertmanager 持续多长时间未接收到新告警后就标记告警状态为resolved(已解决/已恢复)、在收件配置中结合 send_resolved: true 实现恢复通知
配置详解:
global: resolve_timeout: 2m smtp_smarthost: 'smtp.qq.com:465' #现在一般都是ssl,465端口 smtp_from: '2973707860@qq.com' smtp_auth_username: '2973707860@qq.com' #一般也是邮箱地址 smtp_auth_password: 'ptiizujqboiydejf' #密码或授权码 smtp_hello: '@qq.com' smtp_require_tls: false #一般是false route: #route 用来设置报警的分发策略 group_by: [alertname] #采用哪个标签来作为分组依据,通过alertname告警名称(一般是这个) group_wait: 10s #一组告警第一次发送之前等待的延迟时间,即产生告警后延迟10秒钟将组内新产生的消息一起合并发送(一般设置为0)。 group_interval: 10s #一组已发送过初始通知的告警接收到新告警后,下次发送通知前等待的延迟时间(一般设置为 5 分钟或更多)。 repeat_interval: 2m #一条成功发送的告警,在最终发送通知之前等待的时间(通常设置为 3 小时或更长时间)。 #间隔示例: #group_wait: 10s #第一次产生告警,等待 10s,组内有告警就一起发出,没有其它告警就单独发出。 #group_interval: 2m #第二次产生告警,先等待 2 分钟,2 分钟后还没有恢复就进入 repeat_interval。 #repeat_interval: 5m #在最终发送消息前再等待 5 分钟,5 分钟后还没有恢复就发送第二次告警。 receiver: default-receiver #其它的告警发送给 default-receiver (这里是非critical等级) routes: #将 critical(严重的)的报警发送给 myalertname - receiver: myalertname group_wait: 10s match_re: severity: critical #告警等级要在Prometheus的rule中定义 receivers: #定义多接收者 - name: 'default-receiver' email_configs: - to: 'rooroot@aliyun.com' send_resolved: true #通知已经恢复的告警 - name: myalertname #钉钉 webhook_configs: - url: 'http://172.30.7.101:8060/dingtalk/alertname/send' send_resolved: true #通知已经恢复的告警
#规则文件放哪个路径无所谓,只要Prometheus启动能加载进去就行 root@prometheus-server1:/apps/prometheus# mkdir rules root@prometheus-server1:/apps/prometheus# vim rules/server_rules.yaml groups: - name: alertmanager_pod.rules rules: - alert: Pod_all_cpu_usage 警告 expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 20 for: 2m labels: #用于alertmanager去匹配这些告警源 severity: warning service: pods project: myserver annotations: #description类似告警信息,$labels.name为容器名称(内置变量) description: 容器 {{ $labels.name }} CPU 资源利用率大于 20% , (current value is {{ $value }}) summary: Pod CPU 利用率超过 20% - alert: Pod_all_cpu_usage 严重 expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 30 for: 2m labels: severity: critical service: pods project: myserver annotations: description: 容器 {{ $labels.name }} CPU 资源利用率大于 10% , (current value is {{ $value }}) summary: Pod CPU 利用率超过 30% - alert: Pod_all_memory_usage #expr: sort_desc(avg by(name)(irate(container_memory_usage_bytes{name!=""}[5m]))*100) > 10 #内存大于10% expr: sort_desc(avg by(name)(irate(node_memory_MemFree_bytes {name!=""}[5m]))) > 2 #内存大于2G for: 2m labels: severity: critical project: myserver annotations: description: 容器 {{ $labels.name }} Memory 资源利用率大于 2G , (current value is {{ $value }}) summary: Dev Memory 负载告警 - alert: Pod_all_network_receive_usage expr: sum by (name)(irate(container_network_receive_bytes_total{container_label_io_kubernetes_pod_name!=""}[1m])) > 50*1024*1024 for: 1m labels: severity: critical project: myserver annotations: description: 容器 {{ $labels.name }} network_receive 资源利用率大于 50M , (current value is {{ $value }}) - alert: node 内存可用大小 expr: node_memory_MemFree_bytes < 42949672960 #故意写错的,写成4个g for: 1m labels: #severity: critical #标签如果被基于严重等级的告警规则匹配成功后,则不在发送 project 规则的告警,即告警只会被一个规则匹配一次 project: node annotations: description: 容器可用内存小于 4G - name: ssl_expiry rules: - alert: Ssl Cert Will Expire in 30 days expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30 for: 1m labels: severity: warning annotations: summary: "SSL certificate will expire soon on (instance {{ $labels.instance }})" description: "https 证书还剩 30 days\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
root@prometheus-server1:/apps/prometheus# vim prometheus.yml # Alertmanager configuration alerting: #告警发给谁 alertmanagers: -static_configs: -targets: -172.31.2.103:9093 #alertmanager地址(生产环境可能是alertmanger的负载均衡器或service) rule_files: - "/apps/prometheus/rules/server_rules.yaml" #指定规则文件 # - "second_rules.yml" root@prometheus-server1:/apps/prometheus# systemctl restart prometheus.service #在Prometheus网页上可以看到Alerts #注意这里Prometheus要收集k8s的pod指标,要收集cadvisor指标(前提保证cadvisor装上了) root@prometheus-server1:/apps/prometheus# vim prometheus.yml ... - job_name: "cadivisor" static_configs - targets: ["172.31.7.111:8080","172.31.7.112:8080","172.31.7.113:8080"] #3个node

root@prometheus-server3:/apps# vim /apps/alertmanager/alertmanager.yml global: resolve_timeout: 2m #2分钟没有收到新的告警就恢复(根据配置是否发通知) smtp_smarthost: 'smtp.qq.com:465' smtp_from: '2973707860@qq.com' smtp_auth_username: '2973707860@qq smtp_auth_password: 'udwthyyxtstcdhcj' smtp_hello: '@qq.com' smtp_require_tls: false route: #route 用来设置报警的分发策略 group_by: ['alertname'] #采用哪个标签来作为分组依据 group_wait: 10s group_interval: 10s repeat_interval: 2m receiver: 'web.hook' #设置接收人 receivers: - name: 'web.hook' #webhook_configs: #- url: 'http://127.0.0.1:5001/' email_configs: - to: '2973707860@qq.com' send_resolved: true #是否发送已恢复的通知(一般发下) inhibit_rules: #抑制的规则(一般这块不用动) - source_match: #源匹配级别,当匹配成功发出通知,但是其它'alertname', 'dev', 'instance'产生的 warning级别的告警通知将被抑制 severity: 'critical' #报警的事件级别 target_match: severity: 'warning' #调用 source_match 的 severity 即如果已经有'critical' 级别的报警,那么将匹配目标为新产生的告警级别为'warning' 的将被抑制 equal: ['alertname', 'dev', 'instance'] #匹配那些对象的告警 root@prometheus-server3:/apps# systemctl restart alertmanager.service #有告警时,alertmanager页面(9093端口)会显示
先在钉钉,群里添加机器人, 通过webhook接入自定义服务

安全设置必须选一个:ip地址; 加签就是请求里要带个token; 关键字就是请求内容里要有关键字(可写alertname,name等只要消息里有就行)
钉钉认证-关键字-python 脚本:
root@dingding-server:~# vim /data/scripts/dingding-keywords.py #!/usr/bin/python3 import sys import requests import json #钉钉告警: def info(msg): url = 'https://oapi.dingtalk.com/robot/send?access_token=65cbfef3732b87f78a200973bbbed0d06f73ed38ae0ff04667fa1fec580faa41' headers = {'Content-Type': 'application/json;charset=utf-8'} formdata = { "msgtype": "text", "text": {"content":str(msg)}} #print(formdata) requests.post(url=url, data=json.dumps(formdata),headers=headers) info(sys.argv[1]) #测试: root@dingding-server:~# python3 /data/scripts/dingding-keywords.py "namespace=default\npod=pod1\ncpu=87%\n 持续时间=4.5m\nalertname=pod"
alertmanager可以使用prometheus-webhook-dingtalk发告警, 专门对接钉钉的
5.2.1.4:部署 webhook-dingtalk:
root@dingding-server:/apps# tar xvf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz root@dingding-server:/apps# ln -sv /apps/prometheus-webhook-dingtalk-1.4.0.linux-amd64 /apps/prometheus-webhook-dingtalk #测试启动 ding.profile后面跟机器人的关键字alertname,后面加告警url # ./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="alertname=https://oapi.dingtalk.com/robot/send?access_token=65cbfef3732b87f78a200973bbbe d0d06f73ed38ae0ff04667fa1fec580faa41 #修改alertmanager配置,让它把告警发给webhook-dingtalk root@prometheus-server3:/apps/alertmanager# cat alertmanager.yml ... route: group_by: [alertname] group_wait: 10s group_interval: 10s repeat_interval: 10m # receiver: default-receiver receiver: dingding receivers: #加上新的收件人 ... - name: dingding webhook_configs: - url: 'http://172.31.2.120:8060/dingtalk/alertname/send' #后面地址时固定的 send_resolved: true root@prometheus-node1:/apps/alertmanager# systemctl restart alertmanager.service #测试告警如果发出后,可以配置service文件启动: root@dingding-server:/apps# cat /etc/systemd/system/prometheus-webhook-dingtalk.service [Unit] Description=Prometheus Server Documentation=https://prometheus.io/docs/introduction/overview/ After=network.target [Service] Restart=on-failure WorkingDirectory=/apps/prometheus-webhook-dingtalk/ ExecStart=/apps/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="alertname=https://oapi.dingtalk.com/robot/send?access_token=ba76276cd923a4e5dcd653ffabe4b71c4a23e8c4eb8e91446840d527c8d9cd4e" [Install] WantedBy=multi-user.target
5.2:钉钉消息模板:
消息模板定义在 dingtalk:
5.2.1:创建模板:
#下面的2006-01-02 15:04:05指的是时间格式,而不是指定这一天 root@dingding-server:/apps/prometheus-webhook-dingtalk# vim template1.yaml {{ define "dingding.to.message1" }} {{- if gt (len .Alerts.Firing) 0 -}} {{- range $index, $alert := .Alerts -}} ========= **监控告警** ========= **告警程序:** Alertmanager **告警类型:** {{ $alert.Labels.alertname }} **告警级别:** {{ $alert.Labels.severity }} 1 级 **告警状态:** {{ .Status }} **故障主机:** {{ $alert.Labels.instance }} {{ $alert.Labels.device }} **告警主题:** {{ .Annotations.summary }} **告警详情:** {{ $alert.Annotations.message }}{{ $alert.Annotations.description}} **主机标签:** {{ range .Labels.SortedPairs }} </br> [{{ .Name }}: {{ .Value | markdown | html }} ] {{- end }} </br> **故障时间:** {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} ========= = end = ========= {{- end }} {{- end }} {{- if gt (len .Alerts.Resolved) 0 -}} {{- range $index, $alert := .Alerts -}} ========= 告警恢复 ========= **告警程序:** Alertmanager **告警主题:** {{ $alert.Annotations.summary }} **告警主机:** {{ .Labels.instance }} **告警类型:** {{ .Labels.alertname }} **告警级别:** {{ $alert.Labels.severity }} 1 级 **告警状态:** {{ .Status }} **告警详情:** {{ $alert.Annotations.message }}{{ $alert.Annotations.description}} **故障时间:** {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} **恢复时间:** {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} ========= = **end** = ========= {{- end }} {{- end }} {{- end }}
#若在k8s中,提供configmap root@dingding-server:/apps/prometheus-webhook-dingtalk# cp config.example.yml config.yml root@dingding-server:/apps/prometheus-webhook-dingtalk# vim config.yml ## Request timeout # timeout: 5s ## Customizable templates path templates: - /apps/prometheus-webhook-dingtalk/template1.yaml #- /apps/prometheus-webhook-dingtalk/template2.yaml #- /apps/prometheus-webhook-dingtalk/template3.yaml targets: alertname: url: https://oapi.dingtalk.com/robot/send?access_token=ac24b5bb7206c63fc95545eb44976b599ab423ca34c53f01890fed1c3c50553e # secret for signature #钉钉加签内容,用就打开 #secret: SEC76ae7c57db5e95d8a858f478dc2355aed4c36ae6836cbf1292cffad50c6a3f4b message: # Use legacy template text: '{{ template "dingding.to.message1" . }}' #通过模板的 define 定义目标模板名称区分不同的模板,https://github.com/timonwong/prometheus-webhook-dingtalk/issues/16
#直接加载配置文件 root@dingding-server:/apps/prometheus-webhook-dingtalk-1.4.0.linux-amd64# ./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --web.enable-ui --config.file="config.yml" #收到消息就会发给钉钉,消息会被序列化 #可以登录webhook-dingtalk网页,端口8060,可以测试消息序列化成模板样式 172.31.2.120:8060/ui/playground
5.3:企业微信通知:
打开企业微信官网注册账号,使用自己的手机号进行注册。
自 2022 年 6 月 20 号之后创建的机器人必须进行可信 IP 认证。
https://baijiahao.baidu.com/s?id=1745200188617297898&wfr=spider&for=pc
登录企业微信官网,创建应用(机器人)

创建完后可以获取 AgentID 和 Secret, 可在企业微信上点击发消息测试
AgentID 和 Secret 会在发送微信报警信息的时候调用

查看企业id

5.3.13:prometheus 配置:
prometheus 和之前的配置一致,无需修改
5.3.14:alertermanager配置:
root@prometheus-server3:/apps/alertmanager# vim alertmanager.yml ... route: group_by: [alertname] group_wait: 10s group_interval: 10s repeat_interval: 10m # receiver: default-receiver receiver: wechat #设置接收人为wechat receivers: #加个收件人信息,企业微信 ... - name: 'wechat' wechat_configs: - corp_id: ww4c893118fbf4d07c #企业id #to_user: '@all' #发给所有人 to_party: 2 #部门id agent_id: 1000004 #agent id要换 api_secret: STd8cpSsa2RAxH16WpnL6ZiOvVXulbh-XBh2_1kAnAU send_resolved: true #是不是要发送恢复信息 root@prometheus-server3:/apps/alertmanager# systemctl restart alertmanager.service

5.5:自定义企业微信消息模板:
默认的消息内容需要调整、而且消息是连接在一起的。
5.5.1:定义模板:
#下面的变量都可以在官网找到 root@prometheus-server3:/apps/alertmanager# vim /apps/alertmanager/message_template.templ {{ define "wechat.default.message" }} {{ range $i, $alert :=.Alerts }} ===alertmanager 监控报警=== 告警状态:{{ .Status }} 告警级别:{{ $alert.Labels.severity }} 告警类型:{{ $alert.Labels.alertname }} 告警应用:{{ $alert.Annotations.summary }} 故障主机: {{ $alert.Labels.instance }} 告警主题: {{ $alert.Annotations.summary }} 触发阀值:{{ $alert.Annotations.value }} 告警详情: {{ $alert.Annotations.description }} 触发时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }} ===========end============ {{ end }} {{ end } #然后在alertmanager中引用模板 root@prometheus-server3:/apps/alertmanager# vim alertmanager.yml ... templates: #在空白的地方加上这个 - '/apps/alertmanager-0.24.0.linux-amd64/message_template.templ' #alertermanager 引用模板
根据消息中的属性信息设置规则,将消息分类发送,目的如下:
1.将 node 的告警发给给 7x24 值班的企业微信群 labels: #severity: critical #标签如果被基于严重等级的告警规则匹配成功后,则不在发送 project 规则的告警,即告警只会被一个规则匹配一次 project: node 2.将 myserver 项目处于 warning 级别的告警发钉钉群 severity: warning project: myserver 3.将 myserver 项目处于 critical 级别的告警发送到 leader 的企业微信群,与指标的通过部门 ID 区分 labels: severity: critical project: myserver 4.其它没有匹配的告警默认通知类型为邮件
#首先要在promethues里给需要发送给更高收件人的告警加上label,要把他们筛出来 root@prometheus-server1:/apps/prometheus# vim rules/server_rule.yaml groups: - name: alertmanager_pod.rules rules: - alert:Pod all cpu usage警告for: 2mlabels: expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100)> 20 severity: warning service:pods project:myserver annotations: description: 容器{{ $labels.name }} cPU 资源利用率大于 20%,(current value is {{ $value }}) summary: Pod CPU利用率超过20% - alert: Pod_all_cpu_usage严重 expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100)> 30 for:2m labels: severity: critical service: pods project: myserve annotations: description: 容器{{$labels.name }}CPu 资源利用率大于 10%,(current value is {{ $value })) summary: Pod CPU利用率超过30% ... #在alertmanager里对这些告警进行匹配 root@prometheus-server3:/apps/alertmanager# vim alertmanager.yml ... route: #route 用来设置报警的分发策略 group_by: ['alertname'] #采用哪个标签来作为分组依据 group_wait: 10s group_interval: 10s repeat_interval: 2m receiver: 'email' #默认告警方式为邮件(正常应该发给wechat-365) #添加消息路由 routes: - receiver: 'wechat-365' #宿主机告警通过企业微信发送给监控组 group_wait: 10s match_re: project: node #匹配 node 告警 - receiver: 'dingding' #warning 级别的发送到钉钉群或邮件 group_wait: 10s match_re: #写多个是and的关系,要同时满足 severity: warning #匹配 warning 等级告警 project: myserver - receiver: 'wechat-leader' #warning 级别的发送到 leader 的企业微信群 group_wait: 1s match_re: severity: critical #匹配 critical 等级告警 project: myserve receivers: - name: 'email' email_configs: - to: 'rooroot@aliyun.com' send_resolved: true - name: dingding webhook_configs: - url: 'http://172.31.2.120:8060/dingtalk/alertname/send' send_resolved: true - name: 'wechat-365' wechat_configs: - corp_id: ww4c893118fbf4d07c #to_user: '@all' to_party: 2 agent_id: 1000004 api_secret: STd8cpSsa2RAxH16WpnL6ZiOvVXulbh-XBh2_1kAnAU #值班告警机器人 send_resolved: true - name: 'wechat-leader' wechat_configs: - corp_id: ww4c893118fbf4d07c #to_user: '@all' to_party: 14 agent_id: 1000007 api_secret: _nQiWd4cGHVDaFRoew5khHupHX3hHkcx43HPMIEsgGA #leader 告警机器人 send_resolved: true root@prometheus-server3:/apps/alertmanager# systemctl restart alertmanager.service
验证效果

各种告警规则参考
https://samber.github.io/awesome-prometheus-alerts/rules/
5.6:告警抑制与静默:
静默
若在特定时间段不想发告警,可以在alertmanager控制台上创建个Silence(静默规则),不让它发告警了;也可以直接把告警也关了

图中,创建silence中 #以前的版本没有Matchers这个选项,选好静默时间直接提交就行 #注意时间格式,要早8小时 Matchers:匹配通过告警label匹配 # 要写,如:project="myserver",写完点下+号 Creator: 这个silence的创建者 # 要写

查看当前所有silence,可以点Expire强制过期
抑制
基于告警规则,超过80%就不在发60%的告警,即由60%的表达式触发的告警被 抑制了。
同一个规则,如果有高的告警条件和低的告警条件。就会把低的规则抑制,不会发
root@prometheus-server1:/apps/prometheus# cat rules/server_rules.yaml groups: - name: alertmanager_pod.rules rules: - alert: 磁盘容量 expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes{fstype=~"ext4|xfs"}*100) > 80 #磁盘容量利用率大于 80% for: 2s labels: severity: critical annotations: summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!" description: "{{$labels.mountpoint }} 磁盘分区使用大于 80%(目前使用:{{$value}}%)" - alert: 磁盘容量 expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes{fstype=~"ext4|xfs"}*100) > 60 #磁盘容量利用率大于 60% for: 2s labels: severity: warning annotations: summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!" description: "{{$labels.mountpoint }} 磁盘分区使用大于 80%(目前使用:{{$value}}%)"
5.7:alertermanager 高可用:
alertermanager高可用很少用,单机够用了。告警其实是http调用也没有消耗多少资源
5.7.1:单机:


5.7.3:基于 Gossip 机制:
官方的高可用机制
Alertmanager 引入了 Gossip 机制。Gossip 机制为多个 Alertmanager 之间提供了信息传递的机制。确保即使 在多个 Alertmanager 分别接收到相同告警信息的情况下,并且只有一个告警通知被发送给 Receiver。 集群环境搭建: 为了能够让 Alertmanager 节点之间进行通讯,需要在 Alertmanager 启动时设置相应的参数。其中主要的参 数包括: --cluster.listen-address string: 当前实例集群服务监听地址 --cluster.peer value: 初始化时关联的其它实例的集群服务地址

5.8:国产告警组件 PrometheusAlert:
比起alertermanager,在公司更推荐用PrometheusAlert,功能更强大,支持的告警信息更完善。支持更多云厂商的告警,图形功能更完善
PrometheusAlert 是开源的运维告警中心消息转发系统,支持主流的监控系统 Prometheus、Zabbix,日志系 统 Graylog2,Graylog3、数据可视化系统 Grafana、SonarQube,阿里云-云监控,以及所有支持 WebHook 接 口的系统发出的预警消息,支持将收到的这些消息发送到钉钉,微信,email,飞书,腾讯短信,腾讯电话, 阿里云短信,阿里云电话,华为短信,百度云短信,容联云电话,七陌短信,七陌语音,TG,百度 Hi(如流)等。
https://github.com/feiyu563/PrometheusAlert
7.K8S 核心组件监控:master 节点 api-server、controller-manager、kube-scheduler 指标采集与配置
使用k8s里面的Prometheus
#加上apiserver,做了服务发现(这是二进制装的(kubeasz),如果是kubeadm装的,有些发现配置不一样) root@ubuntu101:~/1.prometheus-case-files# vim case3-1-prometheus-cfg.yaml - job_name: 'kubernetes-apiserver' kubernetes_sd_configs: - role: endpoints scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] action: keep regex: default;kubernetes;https #删除54-57 - job_name: 'kube-controller-manager' #控制器,控制pod副本,资源限制 scrape_interval: 10s scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: endpoints namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] separator: ; regex: default;kubernetes;https replacement: $1 action: keep - source_labels: [__address__] regex: '(.*):6443' #发现节点,下面把节点替换成10257(10257是kube-controller-manager的指标端口) replacement: '${1}:10257' #通过10257拿到kube-controller-manager的指标 target_label: __address__ action: replace - action: labelmap regex: __meta_kubernetes_node_label_(.+) - job_name: 'kube-scheduler' #做资源调度 scrape_interval: 10s scrape_timeout: 10s metrics_path: /metrics scheme: https kubernetes_sd_configs: - api_server: null role: endpoints namespaces: names: [] bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] separator: ; regex: default;kubernetes;https replacement: $1 action: keep - source_labels: [__address__] regex: '(.*):6443' #发现后端口替换为10259 replacement: '${1}:10259' #指标端口为10259 target_label: __address__ action: replace - action: labelmap regex: __meta_kubernetes_node_label_(.+) #加上后Prometheus开始采集k8s这些组件的指标(promethues重启下),promethues网页上看下开始收集了没 #grafana导入模板 #grafana导入模板 15761 #apiserver #可以从装好的kube-Prometheus中装好的Prometheus环境中导出模板,那边模板是最全的。这里从网上直接搜的 #grafana导入模板 12122 #kube-controller-manager #grafana导入模板 24353 #kube-scheduler(如果指标不对,要在Prometheus页面查下对应指标什么样,改Prometheus或者改grafana展示语句) 修改下面grafana查询语句 component 为 job sum by(name) (increase(workqueue_work_duration_seconds_bucket{job="kube-scheduler", cluster=~"$cluster"}[5m])> 8)
如果Prometheus要配置第三方存储,就配置remote_write,这样数据远程写入到其他地方,不写入本地了
可以让Prometheus把数据远程写入到 VictoriaMetrics 中
如果往里写的话,grafana就不向Prometheus查数据了,直接向 VictoriaMetrics 查数据
如果加上远程读,grafana还向Prometheus读数据,但promethues本地就不存了。读数据还是要向VictoriaMetrics去读
浙公网安备 33010602011771号