diff --git a/README.md b/README.md
index e75e192..6fcc0a6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,92 @@
-# ansible_tools
+# Ansible 示例
+## prometheus
+使用 ansible 部署 Prometheus 监控组件
+
-ansible 脚本工具
\ No newline at end of file
+**参数说明:**
+`e` :配置文件/配置项
+ `cmd` :
+ - `install` :安装
+ - `remove` :卸载
+`t` :Tag标签
+ - `all` :全部服务
+ - `server` :Prometheus Server 相关服务,含:Prometheus Server、Grafana、Alertmanager、Prometheus Alert、Prometheus Webhook Dingtalk、Loki
+ - `exporter` :Prometheus Exporter 相关服务,含:Node Exporter、CAdvisor、Mysqld Exporter、Mongodb Exporter、Redis Exporter、Rabbitmq Exporter、Rocketmq Exporter、Elasticsearch Exporter、Zookeeper Exporter、JMX Exporter、Nginx Prometheus Exporter、Blackbox Exporter、Grafana Promtail
+ - `dockerce` :Docker 服务
+ - `node` :Prometheus Node Exporter
+ - `docker` :Prometheus CAdvisor
+ - `mysql` :Prometheus Mysqld Exporter
+ - `mongodb` :Prometheus Mongodb Exporter
+ - `redis` :Prometheus Redis Exporter
+ - `rabbitmq` :Prometheus Rabbitmq Exporter
+ - `rocketmq` :Prometheus Rocketmq Exporter
+ - `elasticsearch` :Prometheus Elasticsearch Exporter
+ - `zookeeper` :Prometheus Zookeeper Exporter
+ - `jmx` :Prometheus JMX Exporter
+ - `nginx` :Nginx Prometheus Exporter
+ - `blackbox` :Prometheus Blackbox Exporter
+ - `promtail` :Grafana Promtail
+
+
+
+**安装:**
+**安装全部组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t all
+```
+**仅安装 server 相关组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t server
+```
+**仅安装 exporter 相关组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t exporter
+```
+**安装自定义组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t 组件名称(名单见上方说明)
+```
+示例:安装 server 和 node exporter、cadvisor、blackbox exporter、promtail
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t server,node,docker,blackbox,promtail
+```
+**仅安装 Docker 服务:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=install -t dockerce
+```
+**卸载:**
+**卸载全部组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t all
+```
+**仅卸载 server 相关组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t server
+```
+**仅卸载 exporter 相关组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t exporter
+```
+**卸载自定义组件:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t 组件名称(名单见上方说明)
+```
+示例:卸载 server 和 node exporter、cadvisor、blackbox exporter、promtail
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t server,node,docker,blackbox,promtail
+```
+**卸载 Docker 服务:**
+```shell
+ansible-playbook /etc/ansible/roles/role.yml -e @/etc/ansible/roles/conf/extend.yml -e cmd=remove -t dockerce
+```
+**注意:**
+1. 当前仅测试部署 Server 相关、Node Exporter、cAdvisor
+2. Prometheus Alert、Prometheus Mongodb Exporter、Prometheus Rocketmq Exporter、Prometheus JMX Exporter、Prometheus Zookeeper Exporter 仅支持 x86_64 架构处理器,故当服务器 CPU 架构不为 x86_64 时,对应的服务不会安装,tag 也无效。
+3. 当主机已经安装 Docker 服务时,需要先创建对应的 Docker 网络,然后再执行脚本
+```bash
+docker network create Docker网络名称 --subnet Docker网络网段
+```
+示例如下:
+```bash
+docker network create --driver bridge --opt encrypted:'true' --subnet 10.21.22.0/24 prometheus
+```
diff --git a/prometheus/hosts b/prometheus/hosts
new file mode 100644
index 0000000..56746f5
--- /dev/null
+++ b/prometheus/hosts
@@ -0,0 +1,87 @@
+# This is the default ansible 'hosts' file.
+#
+# It should live in /etc/ansible/hosts
+#
+# - Comments begin with the '#' character
+# - Blank lines are ignored
+# - Groups of hosts are delimited by [header] elements
+# - You can enter hostnames or ip addresses
+# - A hostname/ip can be a member of multiple groups
+
+# Ex 1: Ungrouped hosts, specify before any group headers.
+
+## green.example.com
+## blue.example.com
+## 192.168.100.1
+## 192.168.100.10
+
+# Ex 2: A collection of hosts belonging to the 'webservers' group
+
+## [webservers]
+## alpha.example.org
+## beta.example.org
+## 192.168.1.100
+## 192.168.1.110
+
+# If you have multiple hosts following a pattern you can specify
+# them like this:
+
+## www[001:006].example.com
+
+# Ex 3: A collection of database servers in the 'dbservers' group
+
+## [dbservers]
+##
+## db01.intranet.mydomain.net
+## db02.intranet.mydomain.net
+## 10.25.1.56
+## 10.25.1.57
+
+# Here's another example of host ranges, this time there are no
+# leading 0s:
+
+## db-[99:101]-node.example.com
+[dockerce]
+127.0.0.1
+
+[server]
+127.0.0.1
+
+[node]
+127.0.0.1
+
+[docker]
+127.0.0.1
+
+[blackbox]
+127.0.0.1
+
+[mysql]
+127.0.0.1
+
+[mongodb]
+127.0.0.1
+
+[redis]
+127.0.0.1
+
+[rabbitmq]
+127.0.0.1
+
+[rocketmq]
+127.0.0.1
+
+[elasticsearch]
+127.0.0.1
+
+[zookeeper]
+127.0.0.1
+
+[jmx]
+127.0.0.1
+
+[nginx]
+127.0.0.1
+
+[promtail]
+127.0.0.1
diff --git a/prometheus/roles/alertmanager/defaults/main.yml b/prometheus/roles/alertmanager/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/alertmanager/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/alertmanager/tasks/main.yml b/prometheus/roles/alertmanager/tasks/main.yml
new file mode 100644
index 0000000..3d4d73b
--- /dev/null
+++ b/prometheus/roles/alertmanager/tasks/main.yml
@@ -0,0 +1,71 @@
+---
+# 校验 Alertmanager 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Alertmanager 是否安装'
+ stat:
+ path: '{{ flag }}'
+ register: ret
+
+# 安装 Alertmanager
+- block:
+ - name: '<{{ cmd | upper }}> | 创建 Alertmanager 相关目录'
+ file:
+ path: '{{ item.value }}'
+ state: directory
+ loop: '{{ alertmanager.dir | dict2items }}'
+
+ - name: '<{{ cmd | upper }}> | 安装 Alertmanager'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ loop:
+ - src: docker-compose.yml.j2
+ dest: '{{ alertmanager.dir.main }}/docker-compose.yml'
+ - src: conf/alertmanager.yml.j2
+ dest: '{{ alertmanager.dir.conf }}/alertmanager.yml'
+
+ - name: '<{{ cmd | upper }}> | 初始化 Alertmanager 模板文件'
+ copy:
+ src: '{{ item }}'
+ dest: '{{ alertmanager.dir.template }}'
+ with_fileglob: 'files/template/*'
+
+ - name: '<{{ cmd | upper }}> | 启动 Alertmanager 容器'
+ shell: |
+ . /etc/profile
+ chown -R 65534.65534 {{ alertmanager.dir.conf }} {{ alertmanager.dir.template }}
+ cd {{ alertmanager.dir.main }}
+ docker-compose down
+ docker-compose up -d
+
+ - name: '<{{ cmd | upper }}> | 等待 Alertmanager 服务启动'
+ wait_for:
+ port: '{{ alertmanager.port }}'
+
+ - name: '<{{ cmd | upper }}> | 创建 Alertmanager 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - cmd == "install"
+ - not ret.stat.exists
+ - alertmanager.enable
+
+# 卸载 Alertmanager
+- block:
+ - name: '<{{ cmd | upper }}> | 卸载 Alertmanager'
+ shell: |
+ . /etc/profile
+ cd {{ alertmanager.dir.main }}
+ docker-compose down
+
+ - name: '<{{ cmd | upper }}> | 清除 Alertmanager 相关文件'
+ shell: |
+ rm -rf {{ alertmanager.dir.main }}
+ rm -rf {{ flag }}
+
+ when:
+ - cmd == "remove"
+ - ret.stat.exists
+ - alertmanager.enable
diff --git a/prometheus/roles/alertmanager/templates/conf/alertmanager.yml.j2 b/prometheus/roles/alertmanager/templates/conf/alertmanager.yml.j2
new file mode 100644
index 0000000..89da919
--- /dev/null
+++ b/prometheus/roles/alertmanager/templates/conf/alertmanager.yml.j2
@@ -0,0 +1,42 @@
+global:
+ resolve_timeout: 5m
+
+route:
+ group_by: ['env','app','type','name']
+ group_wait: 30s
+ group_interval: 30s
+ repeat_interval: 1h
+ receiver: 'dingtalk'
+{% if prometheus_alert.enable %}
+ routes:
+ - receiver: 'message'
+ continue: true
+ match:
+ severity: emergency
+ - receiver: 'dingtalk'
+ continue: true
+ match_re:
+ severity: critical|warning
+{% endif %}
+
+receivers:
+{% if prometheus_alert.enable %}
+- name: 'dingtalk'
+ webhook_configs:
+ - url: 'http://{{ groups.server.0 }}:{{ prometheus_alert.port }}/prometheusalert?type=dd&tpl=prometheus-dd&ddurl=https://oapi.dingtalk.com/robot/send?access_token={{ alert.dingtalk.access_token }}'
+- name: 'message'
+ webhook_configs:
+ - url: 'http://{{ groups.server.0 }}:{{ prometheus_alert.port }}/prometheusalert?type={{ alert.message.type }}dx&tpl=prometheus-dx&phone={{ alert.message.phone }}'
+{% elif prometheus_webhook_dingtalk.enable -%}
+- name: 'dingtalk'
+ webhook_configs:
+ - url: 'http://{{ groups.server.0 }}:{{ prometheus_webhook_dingtalk.port }}/dingtalk/webhook_legacy/send'
+ send_resolved: true
+{% endif %}
+
+inhibit_rules:
+ - source_match:
+ severity: 'critical'
+ target_match:
+ severity: 'warning'
+ equal: ['env','app','type','name']
diff --git a/prometheus/roles/alertmanager/templates/docker-compose.yml.j2 b/prometheus/roles/alertmanager/templates/docker-compose.yml.j2
new file mode 100644
index 0000000..6204061
--- /dev/null
+++ b/prometheus/roles/alertmanager/templates/docker-compose.yml.j2
@@ -0,0 +1,21 @@
+version: "3.9"
+
+services:
+ alertmanager:
+ image: {{ alertmanager.image }}
+ container_name: {{ docker.network.name }}-alertmanager
+ hostname: alertmanager
+ restart: always
+ volumes:
+ - /etc/localtime:/etc/localtime:ro
+ - {{ alertmanager.dir.conf }}/alertmanager.yml:/etc/alertmanager/alertmanager.yml
+ - {{ alertmanager.dir.template }}:/etc/alertmanager/template
+ networks:
+ - {{ docker.network.name }}
+ ports:
+ - {{ alertmanager.port }}:9093
+
+networks:
+ {{ docker.network.name }}:
+ external: true
+ name: {{ docker.network.name }}
diff --git a/prometheus/roles/blackbox_exporter/defaults/main.yml b/prometheus/roles/blackbox_exporter/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/blackbox_exporter/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/blackbox_exporter/tasks/main.yml b/prometheus/roles/blackbox_exporter/tasks/main.yml
new file mode 100644
index 0000000..f8bdf67
--- /dev/null
+++ b/prometheus/roles/blackbox_exporter/tasks/main.yml
@@ -0,0 +1,63 @@
+---
+# 校验 Blackbox Exporter 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Blackbox Exporter 是否安装'
+ stat:
+ path: '{{ flag }}'
+ register: ret
+
+# 安装 Blackbox Exporter
+- block:
+ - name: '<{{ cmd | upper }}> | 创建 Blackbox Exporter 相关目录'
+ file:
+ path: '{{ item.value }}'
+ state: directory
+ loop: '{{ blackbox_exporter.dir | dict2items }}'
+
+ - name: '<{{ cmd | upper }}> | 安装 Blackbox Exporter'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ loop:
+ - src: docker-compose.yml.j2
+ dest: '{{ blackbox_exporter.dir.main }}/docker-compose.yml'
+ - src: conf/blackbox.yml.j2
+ dest: '{{ blackbox_exporter.dir.conf }}/blackbox.yml'
+
+ - name: '<{{ cmd | upper }}> | 启动 Blackbox Exporter 容器'
+ shell: |
+ . /etc/profile
+ chown -R 65534.65534 {{ blackbox_exporter.dir.conf }}
+ cd {{ blackbox_exporter.dir.main }}
+ docker-compose down
+ docker-compose up -d
+
+ - name: '<{{ cmd | upper }}> | 等待 Blackbox Exporter 服务启动'
+ wait_for:
+ port: '{{ blackbox_exporter.port }}'
+
+ - name: '<{{ cmd | upper }}> | 创建 Blackbox Exporter 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - cmd == "install"
+ - not ret.stat.exists
+
+# 卸载 Blackbox Exporter
+- block:
+ - name: '<{{ cmd | upper }}> | 卸载 Blackbox Exporter'
+ shell: |
+ . /etc/profile
+ cd {{ blackbox_exporter.dir.main }}
+ docker-compose down
+
+ - name: '<{{ cmd | upper }}> | 清除 Blackbox Exporter 相关文件'
+ shell: |
+ rm -rf {{ blackbox_exporter.dir.main }}
+ rm -rf {{ flag }}
+
+ when:
+ - cmd == "remove"
+ - ret.stat.exists
diff --git a/prometheus/roles/blackbox_exporter/templates/conf/blackbox.yml.j2 b/prometheus/roles/blackbox_exporter/templates/conf/blackbox.yml.j2
new file mode 100644
index 0000000..a37e9ee
--- /dev/null
+++ b/prometheus/roles/blackbox_exporter/templates/conf/blackbox.yml.j2
@@ -0,0 +1,50 @@
+modules:
+ http_2xx:
+ prober: http
+ timeout: 10s
+ http_post_2xx:
+ prober: http
+ http:
+ method: POST
+ tcp_connect:
+ prober: tcp
+ pop3s_banner:
+ prober: tcp
+ tcp:
+ query_response:
+ - expect: "^+OK"
+ tls: true
+ tls_config:
+ insecure_skip_verify: false
+ grpc:
+ prober: grpc
+ grpc:
+ tls: true
+ preferred_ip_protocol: "ip4"
+ grpc_plain:
+ prober: grpc
+ grpc:
+ tls: false
+ service: "service1"
+ ssh_banner:
+ prober: tcp
+ tcp:
+ query_response:
+ - expect: "^SSH-2.0-"
+ - send: "SSH-2.0-blackbox-ssh-check"
+ irc_banner:
+ prober: tcp
+ tcp:
+ query_response:
+ - send: "NICK prober"
+ - send: "USER prober prober prober :prober"
+ - expect: "PING :([^ ]+)"
+ send: "PONG ${1}"
+ - expect: "^:[^ ]+ 001"
+ icmp:
+ prober: icmp
+ icmp_ttl5:
+ prober: icmp
+ timeout: 5s
+ icmp:
+ ttl: 5
diff --git a/prometheus/roles/blackbox_exporter/templates/docker-compose.yml.j2 b/prometheus/roles/blackbox_exporter/templates/docker-compose.yml.j2
new file mode 100644
index 0000000..f71283b
--- /dev/null
+++ b/prometheus/roles/blackbox_exporter/templates/docker-compose.yml.j2
@@ -0,0 +1,22 @@
+version: "3.9"
+
+services:
+ blackbox-exporter:
+ image: {{ blackbox_exporter.image }}
+ container_name: {{ docker.network.name }}-blackbox-exporter
+ hostname: blackbox-exporter
+ restart: always
+ volumes:
+ - /etc/localtime:/etc/localtime:ro
+ - {{ blackbox_exporter.dir.conf }}/blackbox.yml:/etc/blackbox_exporter/config/blackbox.yml:ro
+ networks:
+ - {{ docker.network.name }}
+ ports:
+ - {{ blackbox_exporter.port }}:9115
+ environment:
+ - config.file=/etc/blackbox_exporter/config/blackbox.yml
+
+networks:
+ {{ docker.network.name }}:
+ external: true
+ name: {{ docker.network.name }}
diff --git a/prometheus/roles/cadvisor/defaults/main.yml b/prometheus/roles/cadvisor/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/cadvisor/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/cadvisor/tasks/main.yml b/prometheus/roles/cadvisor/tasks/main.yml
new file mode 100644
index 0000000..7c7f32d
--- /dev/null
+++ b/prometheus/roles/cadvisor/tasks/main.yml
@@ -0,0 +1,65 @@
+---
+# 校验 cAdvisor 是否安装
+- name: '<{{ cmd | upper }}> | 校验 cAdvisor 是否安装'
+ stat:
+ path: '{{ flag }}'
+ register: ret
+
+# 安装 cAdvisor
+- block:
+ - name: '<{{ cmd | upper }}> | 创建 cAdvisor 相关目录'
+ file:
+ path: '{{ cadvisor.dir }}'
+ state: directory
+
+ - name: '<{{ cmd | upper }}> | 安装 cAdvisor'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ loop:
+ - src: docker-compose.yml.j2
+ dest: '{{ cadvisor.dir }}/docker-compose.yml'
+
+ - name: '<{{ cmd | upper }}> | 配置部署主机'
+ shell: |
+ mount -o remount,rw '/sys/fs/cgroup'
+ sudo ln -s /sys/fs/cgroup/cpu,cpuacct /sys/fs/cgroup/cpuacct,cpu
+ ignore_errors: true
+
+ - name: '<{{ cmd | upper }}> | 启动 cAdvisor 容器'
+ shell: |
+ . /etc/profile
+ cd {{ cadvisor.dir }}
+ docker-compose down
+ docker-compose up -d
+
+ - name: '<{{ cmd | upper }}> | 等待 cAdvisor 服务启动'
+ wait_for:
+ port: '{{ cadvisor.port }}'
+
+ - name: '<{{ cmd | upper }}> | 创建 cAdvisor 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - cmd == "install"
+ - not ret.stat.exists
+
+# 卸载 cAdvisor
+- block:
+ - name: '<{{ cmd | upper }}> | 卸载 cAdvisor'
+ shell: |
+ . /etc/profile
+ cd {{ cadvisor.dir }}
+ docker-compose down
+
+ - name: '<{{ cmd | upper }}> | 清除 cAdvisor 相关文件'
+ shell: |
+ rm -rf {{ cadvisor.dir }}
+ rm -rf {{ flag }}
+
+ when:
+ - cmd == "remove"
+ - ret.stat.exists
diff --git a/prometheus/roles/cadvisor/templates/docker-compose.yml.j2 b/prometheus/roles/cadvisor/templates/docker-compose.yml.j2
new file mode 100644
index 0000000..59ea69c
--- /dev/null
+++ b/prometheus/roles/cadvisor/templates/docker-compose.yml.j2
@@ -0,0 +1,24 @@
+version: "3.9"
+
+services:
+ cadvisor:
+ image: {{ cadvisor.image }}
+ container_name: {{ docker.network.name }}-cadvisor
+ hostname: cadvisor
+ restart: always
+ privileged: true
+ volumes:
+ - /etc/localtime:/etc/localtime:ro
+ - /:/rootfs:ro
+ - /var/run:/var/run:rw
+ - /sys:/sys:ro
+ - /var/lib/docker/:/var/lib/docker:ro
+ networks:
+ - {{ docker.network.name }}
+ ports:
+ - {{ cadvisor.port }}:8080
+
+networks:
+ {{ docker.network.name }}:
+ external: true
+ name: {{ docker.network.name }}
diff --git a/prometheus/roles/conf/.extend.yml.swp b/prometheus/roles/conf/.extend.yml.swp
new file mode 100644
index 0000000..a60f922
Binary files /dev/null and b/prometheus/roles/conf/.extend.yml.swp differ
diff --git a/prometheus/roles/conf/extend.yml b/prometheus/roles/conf/extend.yml
new file mode 100644
index 0000000..d90bb67
--- /dev/null
+++ b/prometheus/roles/conf/extend.yml
@@ -0,0 +1,408 @@
+---
+# 部署目录(部署时会在此目录下生成各服务的子目录)
+base_dir: /opt
+
+# Docker 配置
+docker:
+ ## Docker Engine 安装包名称
+ package: docker-24.0.7.tgz
+ ## Docker 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/docker'
+ ### 可执行文件目录
+ bin: '{{ base_dir }}/docker/bin'
+ ### 数据目录
+ data: '{{ base_dir }}/docker/data'
+ ## 部署 Prometheus 相关组件时使用的网络
+ network:
+ name: prometheus
+ subnet: 10.21.22.0/24
+
+# Prometheus Server 配置
+prometheus:
+ ## 镜像
+ image: prom/prometheus:v2.48.0
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/prometheus'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/prometheus/conf'
+ ### 告警规则文件目录
+ rules: '{{ base_dir }}/prometheus/rules'
+ ### 数据目录
+ data: '{{ base_dir }}/prometheus/data'
+ ## 端口号
+ port: 9090
+
+# Grafana 配置
+grafana:
+ ## 是否部署 Grafana
+ enable: true
+ ## 镜像
+ image: grafana/grafana:10.2.2
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/grafana'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/grafana/conf'
+ ### 数据目录
+ data: '{{ base_dir }}/grafana/data'
+ ## 端口号
+ port: 3000
+
+# Alertmanager 配置
+alertmanager:
+ ## 是否部署 Alertmanager
+ enable: true
+ ## 镜像
+ image: prom/alertmanager:v0.26.0
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/alertmanager'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/alertmanager/conf'
+ ### 模板目录
+ template: '{{ base_dir }}/alertmanager/template'
+ ## 端口号
+ port: 9093
+
+# Prometheus Alert 配置 ( Prometheus Alert 和 Prometheus Webhook Dingtalk 只能开启其中一个,不能同时开启)
+prometheus_alert:
+ ## 是否启用 Prometheus Alert
+ enable: true
+ ## 镜像
+ image: feiyu563/prometheus-alert:v4.9
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/prometheus-alert'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/prometheus-alert/conf'
+ ### 数据库目录
+ db: '{{ base_dir }}/prometheus-alert/db'
+ ### 数据文件目录
+ logs: '{{ base_dir }}/prometheus-alert/logs'
+ ## 端口号
+ port: 9080 #8080
+ ## 用户名
+ user: 'admin'
+ ## 密码
+ password: '123456'
+ ## 标题
+ title: 'PrometheusAlert'
+ ## 访问 URL
+ url: 'https://alert.hty1024.com'
+
+# Prometheus Webhook Dingtalk 配置 ( Prometheus Alert 和 Prometheus Webhook Dingtalk 只能开启其中一个,不能同时开启)
+prometheus_webhook_dingtalk:
+ ## 是否启用 Prometheus Webhook Dingtalk
+ enable: false
+ ## 镜像
+ image: timonwong/prometheus-webhook-dingtalk:v2.1.0
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/prometheus-webhook-dingtalk'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/prometheus-webhook-dingtalk/conf'
+ ### 模板文件目录
+ template: '{{ base_dir }}/prometheus-webhook-dingtalk/template'
+ ## 端口号
+ port: 9060 #8060
+
+# 告警配置
+alert:
+ ## 钉钉机器人
+ dingtalk:
+ access_token: '123456789'
+ ## 短信
+ message:
+ type: 'tx'
+ phone: '12300001111'
+ ### 注意:部署完成之后,需要手动将 prometheus-webhook-dingtalk/conf/config.yml 文件的 “【【” 替换为 “{{”,将 “】】” 替换为 “}}”
+ title: '【【 template "legacy.title" . 】】'
+ text: '【【 template "email.to.message" . 】】'
+
+# Loki 配置
+loki:
+ ## 是否启用 Loki
+ enable: true
+ ## 镜像
+ image: grafana/loki:2.9.2
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/loki'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/loki/conf'
+ ## 端口号
+ port: 3100
+
+# Node Exporter 配置
+node_exporter:
+ ## 是否启用 Node Exporter
+ enable: true
+ ## 镜像
+ image: prom/node-exporter:v1.7.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/node-exporter'
+ ## 端口号
+ port: 9100
+
+# CAdvisor 配置
+cadvisor:
+ ## 是否启用 CAdvisor
+ enable: true
+ ## 镜像
+ image: zcube/cadvisor:v0.45.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/cadvisor'
+ ## 端口号
+ port: 9180 #8088
+
+# Blackbox Exporter 配置
+blackbox_exporter:
+ ## 是否启用 Blackbox Exporter
+ enable: true
+ ## 镜像
+ image: prom/blackbox-exporter:v0.24.0
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/exporter/blackbox'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/exporter/blackbox/conf'
+ ## 端口号
+ port: 9115
+ ## 探测 URL
+ targets:
+ - https://hty1024.com
+ - https://www.hty1024.com
+ - https://wiki.hty1024.com
+ - https://git.hty1024.com
+
+# Mysqld Exporter 配置
+mysqld_exporter:
+ ## 镜像
+ image: prom/mysqld-exporter:v0.15.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/mysqld-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Mysqld Exporter 端口号
+ port: 9104
+ ### MySQL URL
+ url: 127.0.0.1:3306
+ ### MySQL 用户名
+ user: exporter
+ ### MySQL 密码
+ password: 123456
+ ### MySQL 数据库
+ database:
+ - host: 192.168.1.1
+ port: 9104
+ url: 192.168.1.1
+ user: exporter
+ password: 123456
+ database:
+
+# MongoDB Exporter 配置
+mongodb_exporter:
+ ## 镜像
+ image: bitnami/mongodb-exporter:0.40.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/mongodb-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### MongoDB Exporter 端口号
+ port: 9126
+ ### MongoDB URL
+ url: 127.0.0.1:27017
+ - host: 192.168.1.1
+ port: 9126
+ url: 192.168.1.1:27017
+
+# Redis Exporter 配置
+redis_exporter:
+ ## 镜像
+ image: oliver006/redis_exporter:v1.55.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/redis-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Redis Exporter 端口号
+ port: 9121
+ ### Redis URL
+ url: 127.0.0.1:6379
+ ### Redis 密码
+ password: 123456
+ - host: 192.168.1.1
+ port: 9121
+ url: 127.0.0.1:6379
+ password: 123456
+
+# Rabbitmq Exporter 配置
+rabbitmq_exporter:
+ ## 镜像
+ image: kbudde/rabbitmq-exporter:1.0.0-RC19
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/rabbitmq-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Rabbitmq Exporter 端口号
+ port: 9419
+ ### RabbitMQ URL
+ url: 127.0.0.1:15672
+ ### RabbitMQ 用户名
+ user: root
+ ### RabbitMQ 密码
+ password: 123456
+ - host: 192.168.1.1
+ port: 9419
+ url: 127.0.0.1:15672
+ user: root
+ password: 123456
+
+# Rocketmq Exporter 配置
+rocketmq_exporter:
+ ## 镜像
+ image: bitnami/java:1.8.392-9
+ ## jar 包名称
+ jar: rocketmq-exporter-0.0.2-SNAPSHOT.jar
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/rocketmq-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Rocketmq Exporter 端口号
+ port: 5557
+ ### Rocketmq URL
+ url: 127.0.0.1:9876
+ ### Rocketmq 版本号
+ version: V4_9_4
+ - host: 192.168.1.1
+ port: 5557
+ url: 127.0.0.1:9876
+ version: V4_9_4
+
+# Elasticsearch Exporter 配置
+elasticsearch_exporter:
+ ## 镜像
+ image: prometheuscommunity/elasticsearch-exporter:v1.6.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/elasticsearch-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Elasticsearch Exporter 端口号
+ port: 9114
+ ### Elasticsearch URL
+ url: 127.0.0.1:9200
+ - host: 192.168.1.1
+ port: 9114
+ url: 127.0.0.1:9200
+
+# Zookeeper Exporter 配置
+zookeeper_exporter:
+ ## 镜像
+ image: dabealu/zookeeper-exporter:v0.1.13
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/zookeeper-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Zookeeper Exporter 端口号
+ port: 9141
+ ### Zookeeper URL
+ url: 127.0.0.1:2181
+ - host: 192.168.1.1
+ port: 9141
+ url: 127.0.0.1:2181
+
+# JMX Exporter 配置
+jmx_exporter:
+ ## 运行模式( javaagent:Java Agent 模式运行;httpserver:HTTP Server 模式运行)
+ model: httpserver
+ ## 镜像
+ image: bitnami/java:1.8.392-9
+ ## jar 包名称
+ jar: jmx_prometheus_httpserver-0.17.2.jar
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/exporter/jmx-exporter'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/exporter/jmx-exporter/conf'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### JMX Exporter 端口号
+ port: 9151
+ ### JMX Exporter URL
+ url: localhost:8080
+ - host: 192.168.1.1
+ port: 9151
+ url: localhost:8080
+
+# Nginx Prometheus Exporter 配置
+nginx_prometheus_exporter:
+ ## 镜像
+ image: nginx/nginx-prometheus-exporter:0.11.0
+ ## 部署目录
+ dir: '{{ base_dir }}/exporter/nginx-prometheus-exporter'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Nginx Prometheus Exporter 端口号
+ port: 9113
+ ### Nginx URL
+ url: http://127.0.0.1/nginx_status
+ - host: 192.168.1.1
+ port: 9113
+ url: http://127.0.0.1/nginx_status
+
+# Promtail 配置
+promtail:
+ ## 镜像
+ image: grafana/promtail:2.9.2
+ ## 部署目录
+ dir:
+ ### 主目录
+ main: '{{ base_dir }}/exporter/promtail'
+ ### 配置文件目录
+ conf: '{{ base_dir }}/exporter/promtail/conf'
+ ## 采集节点
+ nodes:
+ ### 主机
+ - host: 127.0.0.1
+ ### Promtail 端口号
+ port: 9188
+ ### 需要收集的日志目录
+ targets:
+ #### 名称
+ - name: system
+ #### 路径
+ path: /var/log
+ - host: 192.168.1.1
+ port: 9188
+ targets:
+ - name: system
+ path: /var/log
+
diff --git a/prometheus/roles/docker/defaults/main.yml b/prometheus/roles/docker/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/docker/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/docker/files/aarch64/docker-24.0.7.tgz b/prometheus/roles/docker/files/aarch64/docker-24.0.7.tgz
new file mode 100644
index 0000000..1647d5b
Binary files /dev/null and b/prometheus/roles/docker/files/aarch64/docker-24.0.7.tgz differ
diff --git a/prometheus/roles/docker/files/aarch64/docker-compose b/prometheus/roles/docker/files/aarch64/docker-compose
new file mode 100755
index 0000000..44d4a03
Binary files /dev/null and b/prometheus/roles/docker/files/aarch64/docker-compose differ
diff --git a/prometheus/roles/docker/files/x86_64/docker-24.0.7.tgz b/prometheus/roles/docker/files/x86_64/docker-24.0.7.tgz
new file mode 100644
index 0000000..d724d56
Binary files /dev/null and b/prometheus/roles/docker/files/x86_64/docker-24.0.7.tgz differ
diff --git a/prometheus/roles/docker/files/x86_64/docker-compose b/prometheus/roles/docker/files/x86_64/docker-compose
new file mode 100755
index 0000000..bf829e0
Binary files /dev/null and b/prometheus/roles/docker/files/x86_64/docker-compose differ
diff --git a/prometheus/roles/docker/tasks/main.yml b/prometheus/roles/docker/tasks/main.yml
new file mode 100644
index 0000000..3486d5e
--- /dev/null
+++ b/prometheus/roles/docker/tasks/main.yml
@@ -0,0 +1,159 @@
+---
+# 校验 Docker Engine 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Docker Engine 是否安装'
+ shell: |
+ . /etc/profile
+ docker info
+ register: docker_ret
+ ignore_errors: true
+
+# 校验 Docker Compose 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Docker Compose 是否安装'
+ shell: |
+ . /etc/profile
+ docker-compose version
+ register: compose_ret
+ ignore_errors: true
+
+# 安装 Docker Engine
+- block:
+ - name: '<{{ cmd | upper }}> | 编辑 ~/.bashrc 文件环境变量'
+ blockinfile:
+ path: ~/.bashrc
+ block: |
+ export DOCKER_HOME={{ docker.dir.bin }}
+ export PATH=$PATH:$DOCKER_HOME
+ marker: '#{mark} DOCKER Environment'
+ insertbefore: 'BOF'
+
+ - name: '<{{ cmd | upper }}> | 编辑 /etc/profile 文件环境变量'
+ blockinfile:
+ path: /etc/profile
+ block: |
+ export DOCKER_HOME={{ docker.dir.bin }}
+ export PATH=$PATH:$DOCKER_HOME
+ marker: '#{mark} DOCKER Environment'
+ insertafter: 'EOF'
+
+ - name: '<{{ cmd | upper }}> | 创建 Docker 用户组'
+ shell:
+ groupadd -r docker
+ ignore_errors: yes
+
+ - name: '<{{ cmd | upper }}> | 创建 Docker 相关目录并更新系统配置'
+ shell: |
+ source /etc/profile
+ mkdir -p {{ docker.dir.main }}
+ mkdir -p {{ docker.dir.bin }}
+ mkdir -p {{ docker.dir.data }}
+ mkdir -p /etc/docker
+ if [[ -e /etc/docker/daemon.json ]];then
+ cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
+ fi
+ modprobe br_netfilter
+ echo 'net.bridge.bridge-nf-call-ip6tables = 1' > /etc/sysctl.d/docker.conf
+ echo 'net.bridge.bridge-nf-call-iptables = 1' >> /etc/sysctl.d/docker.conf
+ echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/docker.conf
+ sysctl --system
+
+ - name: '<{{ cmd | upper }}> | 安装 Docker Engine'
+ unarchive:
+ src: 'files/{{ ansible_architecture }}/{{ docker.package }}'
+ dest: '{{ docker.dir.bin }}'
+ mode: 0755
+# extra_opts:
+# - --strip-components 1
+
+ - name: '<{{ cmd | upper }}> | 删除 Docker 临时文件'
+ shell: |
+ mv {{ docker.dir.bin }}/docker {{ docker.dir.bin }}/docker-tmp
+ mv -f {{ docker.dir.bin }}/docker-tmp/* {{ docker.dir.bin }}
+ rm -rf {{ docker.dir.bin }}/docker-tmp
+
+ - name: '<{{ cmd | upper }}> | 初始化 Docker 相关配置文件'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ group: docker
+ loop:
+ - src: docker.service.j2
+ dest: /lib/systemd/system/docker.service
+ - src: docker.socket.j2
+ dest: /lib/systemd/system/docker.socket
+ - src: daemon.json.j2
+ dest: /etc/docker/daemon.json
+
+ - name: '<{{ cmd | upper }}> | 启动 Docker 服务'
+ systemd:
+ daemon_reload: yes
+ state: restarted
+ name: docker.service
+ enabled: yes
+
+ - name: '<{{ cmd | upper }}> | 创建 Docker 网络'
+ shell: |
+ . /etc/profile
+ if docker network ls | grep -q {{ docker.network.name }} ; then
+ docker network ls
+ else
+ docker network create {{ docker.network.name }} --subnet {{ docker.network.subnet }}
+ fi
+
+ - name: '<{{ cmd | upper }}> | 添加 Docker 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - docker_ret.failed
+ - cmd == "install"
+
+# 安装 Docker Compose
+- block:
+ - name: '<{{ cmd | upper }}> | 安装 Docker Compose'
+ copy:
+ src: files/{{ ansible_architecture }}/docker-compose
+ dest: '{{ docker.dir.bin }}/docker-compose'
+ mode: 0755
+
+ when:
+ - compose_ret.failed
+ - cmd == "install"
+
+# 卸载 Docker Compose 和 Docker Engine
+- block:
+ - name: '<{{ cmd | upper }}> | 删除 Docker 网络'
+ shell: |
+ docker network rm {{ docker.network.name }}
+
+ - name: '<{{ cmd | upper }}> | 停止 Docker 服务'
+ systemd:
+ state: stopped
+ name: docker.service
+ enabled: no
+
+ - name: '<{{ cmd | upper }}> | 清除 Docker 环境变量'
+ blockinfile:
+ path: '{{ item }}'
+ marker: '#{mark} DOCKER Environment'
+ state: absent
+ backup: yes
+ loop:
+ - ~/.bashrc
+ - /etc/profile
+
+ - name: '<{{ cmd | upper }}> | 卸载 Docker Engine 和 Docker Compose'
+ file:
+ path: '{{ item }}'
+ state: absent
+ loop:
+ - /lib/systemd/system/docker.service
+ - /lib/systemd/system/docker.socket
+ - '{{ docker.dir.bin }}'
+ - '{{ docker.dir.data }}'
+ - '{{ flag }}'
+
+ when:
+ - cmd == "remove"
+ - not docker_ret.failed
diff --git a/prometheus/roles/docker/templates/daemon.json.j2 b/prometheus/roles/docker/templates/daemon.json.j2
new file mode 100644
index 0000000..e27f0fa
--- /dev/null
+++ b/prometheus/roles/docker/templates/daemon.json.j2
@@ -0,0 +1,16 @@
+{
+ "exec-opts" : ["native.cgroupdriver=systemd"],
+ "log-level": "warn",
+ "log-driver": "json-file",
+ "log-opts": {
+ "max-size": "100m",
+ "max-file": "5"
+ },
+ "registry-mirrors": [
+ "https://dockerproxy.com",
+ "https://hub-mirror.c.163.com"
+ ],
+ "bip": "10.21.21.1/24",
+ "data-root": "{{ docker.dir.data }}",
+ "live-restore": true
+}
diff --git a/prometheus/roles/docker/templates/docker.service.j2 b/prometheus/roles/docker/templates/docker.service.j2
new file mode 100644
index 0000000..e1dc33b
--- /dev/null
+++ b/prometheus/roles/docker/templates/docker.service.j2
@@ -0,0 +1,36 @@
+[Unit]
+Description=Docker Application Container Engine
+Documentation=https://docs.docker.com
+After=network-online.target firewalld.service
+Wants=network-online.target
+Requires=docker.socket
+
+[Service]
+Type=notify
+Environment=PATH={{ docker.dir.bin }}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+# the default is not to use systemd for cgroups because the delegate issues still
+# exists and systemd currently does not support the cgroup feature set required
+# for containers run by docker
+ExecStart={{ docker.dir.bin }}/dockerd -H unix://var/run/docker.sock
+ExecReload=/bin/kill -s HUP
+# Having non-zero Limit*s causes performance problems due to accounting overhead
+# in the kernel. We recommend using cgroups to do container-local accounting.
+LimitNOFILE=infinity
+LimitNPROC=infinity
+LimitCORE=infinity
+# Uncomment TasksMax if your systemd version supports it.
+# Only systemd 226 and above support this version.
+#TasksMax=infinity
+TimeoutStartSec=0
+# set delegate yes so that systemd does not reset the cgroups of docker containers
+Delegate=yes
+# kill only the docker process, not all processes in the cgroup
+KillMode=process
+# restart the docker process if it exits prematurely
+Restart=on-failure
+StartLimitBurst=3
+StartLimitInterval=60s
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/prometheus/roles/docker/templates/docker.socket.j2 b/prometheus/roles/docker/templates/docker.socket.j2
new file mode 100644
index 0000000..53133c4
--- /dev/null
+++ b/prometheus/roles/docker/templates/docker.socket.j2
@@ -0,0 +1,13 @@
+[Unit]
+Description=Docker Socket for the API
+PartOf=docker.service
+
+[Socket]
+ListenStream=/var/run/docker.sock
+SocketMode=0660
+SocketUser=root
+SocketGroup=docker
+
+[Install]
+WantedBy=sockets.target
+
diff --git a/prometheus/roles/elasticsearch_exporter/defaults/main.yml b/prometheus/roles/elasticsearch_exporter/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/elasticsearch_exporter/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/elasticsearch_exporter/tasks/main.yml b/prometheus/roles/elasticsearch_exporter/tasks/main.yml
new file mode 100644
index 0000000..8f957d2
--- /dev/null
+++ b/prometheus/roles/elasticsearch_exporter/tasks/main.yml
@@ -0,0 +1,59 @@
+---
+# 校验 Elasticsearch Exporter 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Elasticsearch Exporter 是否安装'
+ stat:
+ path: '{{ flag }}'
+ register: ret
+
+# 安装 Elasticsearch Exporter
+- block:
+ - name: '<{{ cmd | upper }}> | 创建 Elasticsearch Exporter 相关目录'
+ file:
+ path: '{{ elasticsearch_exporter.dir }}'
+ state: directory
+
+ - name: '<{{ cmd | upper }}> | 安装 Elasticsearch Exporter'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ loop:
+ - src: docker-compose.yml.j2
+ dest: '{{ elasticsearch_exporter.dir }}/docker-compose.yml'
+
+ - name: '<{{ cmd | upper }}> | 启动 Elasticsearch Exporter 容器'
+ shell: |
+ . /etc/profile
+ cd {{ elasticsearch_exporter.dir }}
+ docker-compose down
+ docker-compose up -d
+
+# - name: '<{{ cmd | upper }}> | 等待 Elasticsearch Exporter 服务启动'
+# wait_for:
+# port: '{{ elasticsearch_exporter.port }}'
+
+ - name: '<{{ cmd | upper }}> | 创建 Elasticsearch Exporter 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - cmd == "install"
+ - not ret.stat.exists
+
+# 卸载 Elasticsearch Exporter
+- block:
+ - name: '<{{ cmd | upper }}> | 卸载 Elasticsearch Exporter'
+ shell: |
+ . /etc/profile
+ cd {{ elasticsearch_exporter.dir }}
+ docker-compose down
+
+ - name: '<{{ cmd | upper }}> | 清除 Elasticsearch Exporter 相关文件'
+ shell: |
+ rm -rf {{ elasticsearch_exporter.dir }}
+ rm -rf {{ flag }}
+
+ when:
+ - cmd == "remove"
+ - ret.stat.exists
diff --git a/prometheus/roles/elasticsearch_exporter/templates/docker-compose.yml.j2 b/prometheus/roles/elasticsearch_exporter/templates/docker-compose.yml.j2
new file mode 100644
index 0000000..a8be3e5
--- /dev/null
+++ b/prometheus/roles/elasticsearch_exporter/templates/docker-compose.yml.j2
@@ -0,0 +1,23 @@
+version: "3.9"
+
+services:
+ elasticsearch-exporter:
+ image: {{ elasticsearch_exporter.image }}
+ container_name: {{ docker.network.name }}-elasticsearch-exporter
+ hostname: elasticsearch-exporter
+ restart: always
+ networks:
+ - {{ docker.network.name }}
+ {% for node in elasticsearch_exporter.nodes -%}
+ {% if node.host == inventory_hostname -%}
+ ports:
+ - {{ node.port }}:9114
+ command:
+ - "--es.uri=http://{{ node.url }}"
+ {% endif %}
+ {% endfor %}
+
+networks:
+ {{ docker.network.name }}:
+ external: true
+ name: {{ docker.network.name }}
diff --git a/prometheus/roles/grafana/defaults/main.yml b/prometheus/roles/grafana/defaults/main.yml
new file mode 100644
index 0000000..5da49ac
--- /dev/null
+++ b/prometheus/roles/grafana/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+flag: ~/.flag/{{ role_name }}
diff --git a/prometheus/roles/grafana/tasks/main.yml b/prometheus/roles/grafana/tasks/main.yml
new file mode 100644
index 0000000..da8d2c5
--- /dev/null
+++ b/prometheus/roles/grafana/tasks/main.yml
@@ -0,0 +1,66 @@
+---
+# 校验 Grafana 是否安装
+- name: '<{{ cmd | upper }}> | 校验 Grafana 是否安装'
+ stat:
+ path: '{{ flag }}'
+ register: ret
+
+# 安装 Grafana
+- block:
+ - name: '<{{ cmd | upper }}> | 创建 Grafana 相关目录'
+ file:
+ path: '{{ item.value }}'
+ state: directory
+ loop: '{{ grafana.dir | dict2items }}'
+
+ - name: '<{{ cmd | upper }}> | 安装 Grafana'
+ template:
+ src: '{{ item.src }}'
+ dest: '{{ item.dest }}'
+ loop:
+ - src: docker-compose.yml.j2
+ dest: '{{ grafana.dir.main }}/docker-compose.yml'
+ - src: conf/grafana.ini.j2
+ dest: '{{ grafana.dir.conf }}/grafana.ini'
+
+ - name: '<{{ cmd | upper }}> | 启动 Grafana 容器'
+ shell: |
+ . /etc/profile
+ chown -R 472.472 {{ grafana.dir.data }} {{ grafana.dir.conf }}
+ cd {{ grafana.dir.main }}
+ docker-compose down
+ rm -rf data/*
+ docker-compose up -d
+
+ - name: '<{{ cmd | upper }}> | 等待 Grafana 服务启动'
+ wait_for:
+ port: '{{ grafana.port }}'
+
+ - name: '<{{ cmd | upper }}> | 创建 Grafana 安装标记'
+ shell: |
+ set -ex
+ mkdir -p ~/.flag
+ touch {{ flag }}
+
+ when:
+ - cmd == "install"
+ - not ret.stat.exists
+ - grafana.enable
+
+# 卸载 Grafana
+- block:
+ - name: '<{{ cmd | upper }}> | 卸载 Grafana'
+ shell: |
+ . /etc/profile
+ cd {{ grafana.dir.main }}
+ docker-compose down
+
+ - name: '<{{ cmd | upper }}> | 清除 Grafana 相关文件'
+ shell: |
+ rm -rf {{ grafana.dir.main }}
+ rm -rf {{ flag }}
+
+ when:
+ - cmd == "remove"
+ - ret.stat.exists
+ - grafana.enable
diff --git a/prometheus/roles/grafana/templates/conf/grafana.ini.j2 b/prometheus/roles/grafana/templates/conf/grafana.ini.j2
new file mode 100644
index 0000000..b86667d
--- /dev/null
+++ b/prometheus/roles/grafana/templates/conf/grafana.ini.j2
@@ -0,0 +1,1170 @@
+##################### Grafana Configuration Example #####################
+#
+# Everything has defaults so you only need to uncomment things you want to
+# change
+
+# possible values : production, development
+;app_mode = production
+
+# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
+;instance_name = ${HOSTNAME}
+
+# force migration will run migrations that might cause dataloss
+;force_migration = false
+
+#################################### Paths ####################################
+[paths]
+# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
+;data = /var/lib/grafana
+
+# Temporary files in `data` directory older than given duration will be removed
+;temp_data_lifetime = 24h
+
+# Directory where grafana can store logs
+;logs = /var/log/grafana
+
+# Directory where grafana will automatically scan and look for plugins
+;plugins = /var/lib/grafana/plugins
+
+# folder that contains provisioning config files that grafana will apply on startup and while running.
+;provisioning = conf/provisioning
+
+#################################### Server ####################################
+[server]
+# Protocol (http, https, h2, socket)
+;protocol = http
+
+# The ip address to bind to, empty will bind to all interfaces
+;http_addr =
+
+# The http port to use
+;http_port = 3000
+
+# The public facing domain name used to access grafana from a browser
+;domain = localhost
+
+# Redirect to correct domain if host header does not match domain
+# Prevents DNS rebinding attacks
+;enforce_domain = false
+
+# The full public facing url you use in browser, used for redirects and emails
+# If you use reverse proxy and sub path specify full url (with sub path)
+root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana
+
+# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
+serve_from_sub_path = true
+
+# Log web requests
+;router_logging = false
+
+# the path relative working path
+;static_root_path = public
+
+# enable gzip
+;enable_gzip = false
+
+# https certs & key file
+;cert_file =
+;cert_key =
+
+# Unix socket path
+;socket =
+
+# CDN Url
+;cdn_url =
+
+# Sets the maximum time using a duration format (5s/5m/5ms) before timing out read of an incoming request and closing idle connections.
+# `0` means there is no timeout for reading the request.
+;read_timeout = 0
+
+#################################### Database ####################################
+[database]
+# You can configure the database connection by specifying type, host, name, user and password
+# as separate properties or as on string using the url properties.
+
+# Either "mysql", "postgres" or "sqlite3", it's your choice
+;type = sqlite3
+;host = 127.0.0.1:3306
+;name = grafana
+;user = root
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+;password =
+
+# Use either URL or the previous fields to configure the database
+# Example: mysql://user:secret@host:port/database
+;url =
+
+# For "postgres" only, either "disable", "require" or "verify-full"
+;ssl_mode = disable
+
+# Database drivers may support different transaction isolation levels.
+# Currently, only "mysql" driver supports isolation levels.
+# If the value is empty - driver's default isolation level is applied.
+# For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE".
+;isolation_level =
+
+;ca_cert_path =
+;client_key_path =
+;client_cert_path =
+;server_cert_name =
+
+# For "sqlite3" only, path relative to data_path setting
+;path = grafana.db
+
+# Max idle conn setting default is 2
+;max_idle_conn = 2
+
+# Max conn setting default is 0 (mean not set)
+;max_open_conn =
+
+# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
+;conn_max_lifetime = 14400
+
+# Set to true to log the sql calls and execution times.
+;log_queries =
+
+# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared)
+;cache_mode = private
+
+# For "mysql" only if migrationLocking feature toggle is set. How many seconds to wait before failing to lock the database for the migrations, default is 0.
+;locking_attempt_timeout_sec = 0
+
+################################### Data sources #########################
+[datasources]
+# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
+;datasource_limit = 5000
+
+#################################### Cache server #############################
+[remote_cache]
+# Either "redis", "memcached" or "database" default is "database"
+;type = database
+
+# cache connectionstring options
+# database: will use Grafana primary database.
+# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
+# memcache: 127.0.0.1:11211
+;connstr =
+
+#################################### Data proxy ###########################
+[dataproxy]
+
+# This enables data proxy logging, default is false
+;logging = false
+
+# How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds.
+# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
+;timeout = 30
+
+# How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds.
+;dialTimeout = 10
+
+# How many seconds the data proxy waits before sending a keepalive probe request.
+;keep_alive_seconds = 30
+
+# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
+;tls_handshake_timeout_seconds = 10
+
+# How many seconds the data proxy will wait for a server's first response headers after
+# fully writing the request headers if the request has an "Expect: 100-continue"
+# header. A value of 0 will result in the body being sent immediately, without
+# waiting for the server to approve.
+;expect_continue_timeout_seconds = 1
+
+# Optionally limits the total number of connections per host, including connections in the dialing,
+# active, and idle states. On limit violation, dials will block.
+# A value of zero (0) means no limit.
+;max_conns_per_host = 0
+
+# The maximum number of idle connections that Grafana will keep alive.
+;max_idle_connections = 100
+
+# How many seconds the data proxy keeps an idle connection open before timing out.
+;idle_conn_timeout_seconds = 90
+
+# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
+;send_user_header = false
+
+# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
+;response_limit = 0
+
+# Limits the number of rows that Grafana will process from SQL data sources.
+;row_limit = 1000000
+
+#################################### Analytics ####################################
+[analytics]
+# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
+# No ip addresses are being tracked, only simple counters to track
+# running instances, dashboard and error counts. It is very helpful to us.
+# Change this option to false to disable reporting.
+;reporting_enabled = true
+
+# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs
+;reporting_distributor = grafana-labs
+
+# Set to false to disable all checks to https://grafana.com
+# for new versions of grafana. The check is used
+# in some UI views to notify that a grafana update exists.
+# This option does not cause any auto updates, nor send any information
+# only a GET request to https://raw.githubusercontent.com/grafana/grafana/main/latest.json to get the latest version.
+;check_for_updates = true
+
+# Set to false to disable all checks to https://grafana.com
+# for new versions of plugins. The check is used
+# in some UI views to notify that a plugin update exists.
+# This option does not cause any auto updates, nor send any information
+# only a GET request to https://grafana.com to get the latest versions.
+;check_for_plugin_updates = true
+
+# Google Analytics universal tracking code, only enabled if you specify an id here
+;google_analytics_ua_id =
+
+# Google Tag Manager ID, only enabled if you specify an id here
+;google_tag_manager_id =
+
+# Rudderstack write key, enabled only if rudderstack_data_plane_url is also set
+;rudderstack_write_key =
+
+# Rudderstack data plane url, enabled only if rudderstack_write_key is also set
+;rudderstack_data_plane_url =
+
+# Rudderstack SDK url, optional, only valid if rudderstack_write_key and rudderstack_data_plane_url is also set
+;rudderstack_sdk_url =
+
+# Rudderstack Config url, optional, used by Rudderstack SDK to fetch source config
+;rudderstack_config_url =
+
+# Controls if the UI contains any links to user feedback forms
+;feedback_links_enabled = true
+
+#################################### Security ####################################
+[security]
+# disable creation of admin user on first start of grafana
+;disable_initial_admin_creation = false
+
+# default admin user, created on startup
+;admin_user = admin
+
+# default admin password, can be changed before first start of grafana, or in profile settings
+;admin_password = admin
+
+# used for signing
+;secret_key = SW2YcwTIb9zpOOhoPsMm
+
+# current key provider used for envelope encryption, default to static value specified by secret_key
+;encryption_provider = secretKey.v1
+
+# list of configured key providers, space separated (Enterprise only): e.g., awskms.v1 azurekv.v1
+;available_encryption_providers =
+
+# disable gravatar profile images
+;disable_gravatar = false
+
+# data source proxy whitelist (ip_or_domain:port separated by spaces)
+;data_source_proxy_whitelist =
+
+# disable protection against brute force login attempts
+;disable_brute_force_login_protection = false
+
+# set to true if you host Grafana behind HTTPS. default is false.
+;cookie_secure = false
+
+# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
+;cookie_samesite = lax
+
+# set to true if you want to allow browsers to render Grafana in a ,