搜索中...
🔍

未找到相关结果

Akemi

Consul 配置中心统一管理 Promxy 与 vmalert

字数统计: 1.7k阅读时长: 8 min
2026/06/11

Promxy 和 vmalert 都部署好了,但每次改配置都要 kubectl edit 或重新 apply YAML,能不能像 Operator 管 CRD 一样,改个 KV 就热加载?

可以。用 Consul KV + consul-template sidecar。

前期准备:统一改为 Consul 管理

之前的状态:

  • Promxy:用它自己的 Helm chart(从 GitHub repo 拉取)单独部署,配置写死在 values.yaml 里
  • vmalert:由 victoria-metrics-k8s-stack 这个 Helm chart 自带,配置由 Operator 管理

两个组件各自为政,改配置都要 helm upgrade,不够灵活。

为了实现配置热更新,把它们都改为独立的 Deployment YAML 部署,加上 consul-template sidecar:

  • Promxy:卸载原来的 Helm release,改用 Deployment YAML + consul-template sidecar
  • vmalert:从 victoria-metrics-k8s-stack 的 values.yaml 中关闭(enabled: false),改用 Deployment YAML + consul-template sidecar

保留 Helm 管理的部分(不需要动态配置):

  • vminsert / vmselect / vmstorage(VM 存储层)
  • Grafana(可视化)
  • Alertmanager(告警接收,SMTP 配置相对固定)

独立部署后,配置文件不再写死在 YAML 里,而是由 Consul KV 统一管理,consul-template watch 变更并自动渲染。

架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
             ┌─────────────┐
│ Consul KV │
│ (配置中心) │
└──────┬──────┘
│ watch
┌──────────┴──────────┐
│ │
┌────────▼────────┐ ┌─────────▼─────────┐
│ consul-template │ │ consul-template │
│ (Promxy sidecar)│ │ (vmalert sidecar)│
└────────┬────────┘ └─────────┬─────────┘
│ render │ render
┌────────▼────────┐ ┌─────────▼─────────┐
│ Promxy │ │ vmalert │
│ (查询聚合代理) │ │ (告警引擎) │
└─────────────────┘ └───────────────────┘

核心思路:consul-template 作为 sidecar 跑在 Pod 里,watch Consul KV 的变更,自动渲染配置文件,然后通知主进程 reload。

Consul 部署

用 Helm 部署,只启用 server + UI:

1
2
3
4
helm pull hashicorp/consul --untar
cd consul
# 修改 values.yaml:只开 server 和 ui,关掉 client/connect/gateway 等
helm upgrade --install consul ./ -f values.yaml -n consul --create-namespace

验证 Consul UI 可用:

1
2
kubectl -n consul port-forward --address 0.0.0.0 svc/consul-consul-ui 3002:80 &
# 浏览器打开 http://192.168.10.100:3002/ui/dc1/kv

Promxy:单键配置

Promxy 的整个配置文件是一个 YAML,用一个 KV 键存就行。

consul-template 模板

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: ConfigMap
metadata:
name: promxy-ct-templates
namespace: victoria-metrics
data:
promxy.yaml.ctmpl: |
{% raw %}{{ with key "/promxy/config" }}
{{ . }}
{{ end }}{% endraw %}

{{ with key "/promxy/config" }} 从 Consul KV 读取单个键的值,直接输出。

Deployment 关键字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
spec:
template:
spec:
shareProcessNamespace: true # 关键:多容器共享 PID 命名空间
containers:
- name: promxy
image: quay.io/jacksontj/promxy:v0.0.93
command:
- sh
- -c
- "sleep 5 && /bin/promxy --config=/etc/promxy/config.yaml --bind-addr=:8082 --web.enable-lifecycle"
# --web.enable-lifecycle:启用 /-/reload 端点
volumeMounts:
- name: config
mountPath: /etc/promxy

- name: consul-template
image: hashicorp/consul-template:0.39.0
args:
- "-consul-addr=consul-consul-server.consul.svc.cluster.local:8500"
# ↑ 必须用 FQDN!headless Service 短域名会 NXDOMAIN
- "-template=/etc/ct-templates/promxy.yaml.ctmpl:/etc/promxy/config.yaml:wget -qO /dev/null --post-data='' http://localhost:8082/-/reload"
# ↑ 三段式:模板路径:输出路径:触发命令
- "-log-level=info"
volumeMounts:
- name: config
mountPath: /etc/promxy # 和 promxy 共享同一个 emptyDir

volumes:
- name: config
emptyDir: {} # consul-template 写,promxy 读

Consul KV 写入 Promxy 配置

在 Consul WebUI 中创建 Key promxy/config,Value 为 Promxy 的完整 YAML 配置:

Consul WebUI 中手动填写 promxy/config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
promxy:
server_groups:
# 数据源 1:test-cluster 的 vmselect(通过宿主机 port-forward 访问)
- static_configs:
- targets:
- 192.168.10.100:8481
scheme: http
remote_read: false
anti_affinity: 10s
query_params:
nocache: 1
path_prefix: /select/0/prometheus

# 数据源 2:ws-k8s 本地 Prometheus
- static_configs:
- targets:
- prometheus-kube-prometheus-prometheus.prometheus.svc:9090
scheme: http
remote_read: true

remote_write:
- url: http://vminsert-victoria-metrics-k8s-stack.victoria-metrics.svc:8480/insert/0/prometheus/api/v1/write

也可以用命令行写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubectl exec -n consul consul-consul-server-0 -- consul kv put promxy/config 'promxy:
server_groups:
- static_configs:
- targets: ["192.168.10.100:8481"]
scheme: http
remote_read: false
anti_affinity: 10s
query_params:
nocache: 1
path_prefix: /select/0/prometheus
- static_configs:
- targets: ["prometheus-kube-prometheus-prometheus.prometheus.svc:9090"]
scheme: http
remote_read: true'

验证

1
2
3
4
5
6
7
# 启动 port-forward
kubectl --context kind-test-cluster -n victoria-metrics port-forward --address 0.0.0.0 svc/vmselect-vm-stack-victoria-metrics-k8s-stack 8481:8481 &
kubectl --context kind-ws-k8s -n prometheus port-forward --address 0.0.0.0 svc/prometheus-grafana 3000:80 &
kubectl -n victoria-metrics port-forward --address 0.0.0.0 svc/promxy 8082:8082 &

# Grafana 中选择 Promxy 数据源,查询 up
# 能同时看到两个集群的数据

Grafana 验证:Promxy 聚合两个集群数据

Consul KV 变更 → consul-template 自动渲染 → Promxy reload → 查询聚合生效。

vmalert:目录遍历多键规则

vmalert 的告警规则有多条,每条规则单独一个 KV 键,存在 /vmalert/rules/ 目录下。consul-template 用 tree 函数遍历目录,把所有规则拼成一个文件。

consul-template 模板

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: ConfigMap
metadata:
name: vmalert-ct-templates
namespace: victoria-metrics
data:
rules.yml.ctmpl: |
groups:
{% raw %}{{- range $key, $pairs := tree "/vmalert/rules/" }}
{{ $pairs.Value | indent 4 }}
{{ end }}{% endraw %}

和 Promxy 模板的区别

对比项 Promxy vmalert
读取方式 {{ with key "/promxy/config" }} 单键 {{ range tree "/vmalert/rules/" }} 遍历目录
KV 结构 单个键存完整配置 每条规则一个键
输出 直接输出 value groups: + 每个 value 缩进拼接

模板细节

  • groups: 由模板统一添加,KV 中的 value 不带 groups: 字段
  • {{- range:左 trim,吃掉 range 前面的换行,避免 groups: 和第一项之间出现空行
  • indent 4:将每个 value(以 - name: 开头)缩进 4 格,使其成为 groups: 下的合法列表项

Deployment 关键字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
spec:
template:
spec:
shareProcessNamespace: true
containers:
- name: vmalert
image: victoriametrics/vmalert:v1.106.1
args:
- "-rule=/etc/vmalert/rules/*.yml"
- "-datasource.url=http://promxy.victoria-metrics.svc:8082" # 查询数据源:走 Promxy
- "-notifier.url=http://vmalertmanager-victoria-metrics-k8s-stack.victoria-metrics.svc:9093" # 告警发给 alertmanager
- "-evaluationInterval=15s"
- "-httpListenAddr=:8080"
volumeMounts:
- name: alert-rules
mountPath: /etc/vmalert/rules

- name: consul-template
image: hashicorp/consul-template:0.39.0
args:
- "-consul-addr=consul-consul-server.consul.svc.cluster.local:8500"
- "-template=/etc/ct-templates/rules.yml.ctmpl:/etc/vmalert/rules/rules.yml:pkill -HUP vmalert"
# ↑ reload 方式和 Promxy 不同:用 SIGHUP 信号,不是 HTTP API
- "-log-level=info"
volumeMounts:
- name: alert-rules
mountPath: /etc/vmalert/rules

volumes:
- name: alert-rules
emptyDir: {}

和 Promxy 的 reload 差异

  • Promxy:wget POST /-/reload(HTTP API,需要 --web.enable-lifecycle
  • vmalert:pkill -HUP vmalert(SIGHUP 信号,vmalert 原生支持热加载规则)

Consul KV 写入告警规则

在 Consul WebUI 中,Key 为 vmalert/rules/<规则名>,Value 为规则的 group body(不带 groups:):

  • Key:vmalert/rules/alert.yml
  • Value:- name: process-memory + rules: [...]
1
2
3
4
5
6
7
8
9
10
- name: process-memory
rules:
- alert: ProcessHighMemory
expr: namedprocess_namegroup_memory_bytes{memtype="resident"} > 2700000000
for: 1m
labels:
severity: warning
annotations:
summary: "进程 {{ $labels.groupname }} 内存占用过高"
description: "进程 {{ $labels.groupname }} 的 resident 内存为 {{ $value | humanize1024 }},超过 2.7GB 阈值"

后续加新规则:在 /vmalert/rules/ 下新建一个 key,consul-template 自动检测变更 → 渲染 → SIGHUP reload vmalert。

验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 检查 consul-template 渲染结果
kubectl exec deploy/vmalert -c vmalert -- cat /etc/vmalert/rules/rules.yml
# 应该看到 groups: + 规则内容

# 2. 检查 vmalert 是否加载了规则
kubectl logs deploy/vmalert -c vmalert | grep 'process-memory'
# group "process-memory" started; interval=15s

# 3. 检查告警是否触发
kubectl port-forward deploy/vmalert 8080:8080
curl http://localhost:8080/api/v1/alerts
# state=firing, name=ProcessHighMemory

# 4. 检查 alertmanager 是否收到
kubectl port-forward svc/vmalertmanager-victoria-metrics-k8s-stack 9093:9093
curl http://localhost:9093/api/v2/alerts
# state=active, receiver=default-email

告警邮件成功送达 QQ 邮箱

完整配置文件见 /root/k8s-manifests/


本文由 AI 辅助生成,内容经人工审核与验证。

CATALOG
  1. 1. 前期准备:统一改为 Consul 管理
  2. 2. 架构
  3. 3. Consul 部署
  4. 4. Promxy:单键配置
    1. 4.1. consul-template 模板
    2. 4.2. Deployment 关键字段
    3. 4.3. Consul KV 写入 Promxy 配置
    4. 4.4. 验证
  5. 5. vmalert:目录遍历多键规则
    1. 5.1. consul-template 模板
    2. 5.2. Deployment 关键字段
    3. 5.3. Consul KV 写入告警规则
    4. 5.4. 验证