feat: 引入 vmauth 鉴权与严格多租户
- 对外端口统一为 18428(vmauth 入口),VM 不再直接暴露宿主机端口 - 边缘 vmagent 与中央 Prometheus remote_write 增加 basic auth - 支持 tenants.csv 驱动的 per-tenant 写入/查询隔离,并提供管理员跨租户只读查询 - 更新 Grafana provisioning 与部署/文档 Made-with: Cursor
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
| `PROMETHEUS_PORT` | 9091 | Prometheus Web UI 端口(避免与 cockpit 冲突) |
|
||||
| `GRAFANA_PORT` | 3000 | Grafana Web UI 端口 |
|
||||
| `ALERTMANAGER_PORT` | 9093 | Alertmanager Web UI 端口 |
|
||||
| `VICTORIAMETRICS_PORT` | 8428 | VictoriaMetrics 端口(边缘节点推送数据到此端口) |
|
||||
| `VICTORIAMETRICS_PORT` | 18428 | vmauth 对外端口(边缘节点推送数据/查询都走此端口) |
|
||||
|
||||
**注意**:
|
||||
- 如果端口被占用,修改 `.env` 文件中对应的端口号
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
# VictoriaMetrics 数据源(边缘节点上报的数据存储在此)
|
||||
# 边缘节点通过 remote_write 推送到中央 VictoriaMetrics,本数据源用于在 Grafana 中查询这些数据
|
||||
# 使用前需在边缘节点配置:remote_write 指向中央服务器 VictoriaMetrics 地址(如 http://中央IP:8428/api/v1/write)
|
||||
# 使用前需在边缘节点配置:remote_write 指向中央服务器 VictoriaMetrics 地址(如 http://中央IP:18428/api/v1/write)
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: VictoriaMetrics
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://victoria-metrics:8428
|
||||
url: http://vmauth:8427
|
||||
isDefault: false
|
||||
editable: true
|
||||
basicAuth: true
|
||||
basicAuthUser: ${VMAUTH_READ_USER}
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
queryTimeout: 60s
|
||||
timeInterval: 15s
|
||||
secureJsonData:
|
||||
basicAuthPassword: ${VMAUTH_READ_PASSWORD}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# VictoriaMetrics 数据源(通过 vmauth 进行鉴权访问)
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: VictoriaMetrics
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://vmauth:8427
|
||||
isDefault: false
|
||||
editable: true
|
||||
basicAuth: true
|
||||
basicAuthUser: "${VMAUTH_READ_USER}"
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
queryTimeout: 60s
|
||||
timeInterval: 15s
|
||||
secureJsonData:
|
||||
basicAuthPassword: "${VMAUTH_READ_PASSWORD}"
|
||||
@@ -21,7 +21,10 @@ global:
|
||||
# 远程写入:将中央 Prometheus 抓取到的本地服务指标推送到 VictoriaMetrics
|
||||
# (边缘节点由 vmagent 直接 remote_write 到 VictoriaMetrics)
|
||||
remote_write:
|
||||
- url: http://victoria-metrics:8428/api/v1/write
|
||||
- url: http://vmauth:8427/api/v1/write
|
||||
basic_auth:
|
||||
username: ${VMAUTH_WRITE_USER}
|
||||
password: ${VMAUTH_WRITE_PASSWORD}
|
||||
queue_config:
|
||||
max_samples_per_send: 10000
|
||||
capacity: 20000
|
||||
|
||||
@@ -21,7 +21,10 @@ global:
|
||||
# 远程写入:将中央 Prometheus 抓取到的本地服务指标推送到 VictoriaMetrics
|
||||
# (边缘节点由 vmagent 直接 remote_write 到 VictoriaMetrics)
|
||||
remote_write:
|
||||
- url: http://victoria-metrics:${VICTORIAMETRICS_PORT}/api/v1/write
|
||||
- url: http://vmauth:8427/api/v1/write
|
||||
basic_auth:
|
||||
username: ${VMAUTH_WRITE_USER}
|
||||
password: ${VMAUTH_WRITE_PASSWORD}
|
||||
queue_config:
|
||||
max_samples_per_send: ${PROMETHEUS_REMOTE_WRITE_MAX_SAMPLES}
|
||||
capacity: ${PROMETHEUS_REMOTE_WRITE_CAPACITY}
|
||||
@@ -40,7 +43,7 @@ scrape_configs:
|
||||
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL}s
|
||||
metrics_path: '/metrics'
|
||||
static_configs:
|
||||
- targets: ['victoria-metrics:${VICTORIAMETRICS_PORT}']
|
||||
- targets: ['victoria-metrics:8428']
|
||||
|
||||
# 抓取Alertmanager
|
||||
- job_name: 'alertmanager'
|
||||
|
||||
3
central-server/config/vmauth/tenants.csv.example
Normal file
3
central-server/config/vmauth/tenants.csv.example
Normal file
@@ -0,0 +1,3 @@
|
||||
tenant_id,edge_node_id,write_user,write_password,read_user,read_password
|
||||
1001,edge_a,edge_a_write,CHANGE_ME,edge_a_read,CHANGE_ME
|
||||
1002,edge_b,edge_b_write,CHANGE_ME,edge_b_read,CHANGE_ME
|
||||
6
central-server/config/vmauth/vmauth.yml.template
Normal file
6
central-server/config/vmauth/vmauth.yml.template
Normal file
@@ -0,0 +1,6 @@
|
||||
unauthorized_user:
|
||||
# 未认证请求默认拒绝
|
||||
url_map: []
|
||||
|
||||
# 注意:本文件将由 deploy.sh 根据 config/vmauth/tenants.csv 自动生成。
|
||||
users: []
|
||||
@@ -30,7 +30,7 @@ fi
|
||||
PROMETHEUS_PORT=${PROMETHEUS_PORT:-9091}
|
||||
GRAFANA_PORT=${GRAFANA_PORT:-3000}
|
||||
ALERTMANAGER_PORT=${ALERTMANAGER_PORT:-9093}
|
||||
VICTORIAMETRICS_PORT=${VICTORIAMETRICS_PORT:-8428}
|
||||
VICTORIAMETRICS_PORT=${VICTORIAMETRICS_PORT:-18428}
|
||||
PROMETHEUS_DATA_DIR=${PROMETHEUS_DATA_DIR:-./data/prometheus-data}
|
||||
GRAFANA_DATA_DIR=${GRAFANA_DATA_DIR:-./data/grafana-data}
|
||||
VICTORIAMETRICS_DATA_DIR=${VICTORIAMETRICS_DATA_DIR:-./data/victoria-metrics-data}
|
||||
@@ -46,6 +46,12 @@ PROMETHEUS_REMOTE_WRITE_MAX_SHARDS=${PROMETHEUS_REMOTE_WRITE_MAX_SHARDS:-10}
|
||||
GRAFANA_DEFAULT_LANGUAGE=${GRAFANA_DEFAULT_LANGUAGE:-zh-Hans}
|
||||
GRAFANA_DEFAULT_THEME=${GRAFANA_DEFAULT_THEME:-light}
|
||||
TRAEFIK_PROVIDER=${TRAEFIK_PROVIDER:-external}
|
||||
VMAUTH_WRITE_USER=${VMAUTH_WRITE_USER:-vm_write}
|
||||
VMAUTH_WRITE_PASSWORD=${VMAUTH_WRITE_PASSWORD:-change-me-strong-write}
|
||||
VMAUTH_READ_USER=${VMAUTH_READ_USER:-vm_read}
|
||||
VMAUTH_READ_PASSWORD=${VMAUTH_READ_PASSWORD:-change-me-strong-read}
|
||||
VMAUTH_ADMIN_USER=${VMAUTH_ADMIN_USER:-vm_admin}
|
||||
VMAUTH_ADMIN_PASSWORD=${VMAUTH_ADMIN_PASSWORD:-change-me-strong-admin}
|
||||
|
||||
# 根据 TRAEFIK_ENABLED 与 TRAEFIK_PROVIDER 设置网络
|
||||
if [ "${TRAEFIK_ENABLED:-false}" = "true" ]; then
|
||||
@@ -194,6 +200,147 @@ elif [ ! -f "config/prometheus/prometheus.yml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
generate_vmauth_and_grafana_datasources() {
|
||||
mkdir -p config/vmauth config/grafana/provisioning/datasources
|
||||
|
||||
local tenants_file="config/vmauth/tenants.csv"
|
||||
local vmauth_out="config/vmauth/vmauth.yml"
|
||||
local grafana_out="config/grafana/provisioning/datasources/victoriametrics.yml"
|
||||
|
||||
echo "📝 生成 vmauth 配置与 Grafana 数据源..."
|
||||
|
||||
# vmauth header
|
||||
cat > "$vmauth_out" <<'EOF'
|
||||
unauthorized_user:
|
||||
url_map: []
|
||||
|
||||
users:
|
||||
EOF
|
||||
|
||||
# grafana header
|
||||
cat > "$grafana_out" <<'EOF'
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
EOF
|
||||
|
||||
if [ -f "$tenants_file" ]; then
|
||||
# CSV: tenant_id,edge_node_id,write_user,write_password,read_user,read_password
|
||||
# Skip header line
|
||||
tail -n +2 "$tenants_file" | while IFS=',' read -r tenant_id edge_node_id wuser wpass ruser rpass; do
|
||||
# Skip empty lines
|
||||
[ -z "$tenant_id" ] && continue
|
||||
|
||||
# vmauth write user (route to per-tenant insert)
|
||||
cat >> "$vmauth_out" <<EOF
|
||||
- username: "$wuser"
|
||||
password: "$wpass"
|
||||
url_prefix: "http://victoria-metrics:8428/insert/${tenant_id}/prometheus"
|
||||
|
||||
EOF
|
||||
|
||||
# vmauth read user (route to per-tenant select; allow only query-ish paths)
|
||||
cat >> "$vmauth_out" <<EOF
|
||||
- username: "$ruser"
|
||||
password: "$rpass"
|
||||
url_map:
|
||||
- src_paths:
|
||||
- "/api/v1/query"
|
||||
- "/api/v1/query_range"
|
||||
- "/api/v1/series"
|
||||
- "/api/v1/labels"
|
||||
- "/api/v1/label/.+/values"
|
||||
- "/api/v1/export"
|
||||
- "/federate"
|
||||
url_prefix: "http://victoria-metrics:8428/select/${tenant_id}/prometheus"
|
||||
|
||||
EOF
|
||||
|
||||
# grafana datasource per tenant
|
||||
# name includes tenant_id + edge_node_id for readability
|
||||
cat >> "$grafana_out" <<EOF
|
||||
- name: "VictoriaMetrics (tenant ${tenant_id}${edge_node_id:+ - ${edge_node_id}})"
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://vmauth:8427
|
||||
isDefault: false
|
||||
editable: true
|
||||
basicAuth: true
|
||||
basicAuthUser: "${ruser}"
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
queryTimeout: 60s
|
||||
timeInterval: 15s
|
||||
secureJsonData:
|
||||
basicAuthPassword: "${rpass}"
|
||||
|
||||
EOF
|
||||
done
|
||||
|
||||
echo "✅ 已根据 tenants.csv 生成 vmauth.yml 与 Grafana 多数据源"
|
||||
else
|
||||
# Fallback: single-tenant mode using .env variables
|
||||
cat >> "$vmauth_out" <<EOF
|
||||
- username: "${VMAUTH_WRITE_USER}"
|
||||
password: "${VMAUTH_WRITE_PASSWORD}"
|
||||
url_prefix: "http://victoria-metrics:8428"
|
||||
|
||||
- username: "${VMAUTH_READ_USER}"
|
||||
password: "${VMAUTH_READ_PASSWORD}"
|
||||
url_map:
|
||||
- src_paths:
|
||||
- "/api/v1/query"
|
||||
- "/api/v1/query_range"
|
||||
- "/api/v1/series"
|
||||
- "/api/v1/labels"
|
||||
- "/api/v1/label/.+/values"
|
||||
- "/api/v1/export"
|
||||
- "/federate"
|
||||
url_prefix: "http://victoria-metrics:8428"
|
||||
EOF
|
||||
|
||||
cat >> "$grafana_out" <<EOF
|
||||
- name: VictoriaMetrics
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://vmauth:8427
|
||||
isDefault: false
|
||||
editable: true
|
||||
basicAuth: true
|
||||
basicAuthUser: "${VMAUTH_READ_USER}"
|
||||
jsonData:
|
||||
httpMethod: POST
|
||||
queryTimeout: 60s
|
||||
timeInterval: 15s
|
||||
secureJsonData:
|
||||
basicAuthPassword: "${VMAUTH_READ_PASSWORD}"
|
||||
EOF
|
||||
|
||||
echo "✅ 未找到 tenants.csv,已使用单租户 .env 变量生成 vmauth.yml 与 Grafana 数据源"
|
||||
fi
|
||||
|
||||
# Append admin read-only user (can query any tenant via /select/<tenant>/prometheus/...)
|
||||
cat >> "$vmauth_out" <<EOF
|
||||
|
||||
- username: "${VMAUTH_ADMIN_USER}"
|
||||
password: "${VMAUTH_ADMIN_PASSWORD}"
|
||||
url_map:
|
||||
- src_paths:
|
||||
- "^/select/[0-9]+/prometheus/api/v1/query$"
|
||||
- "^/select/[0-9]+/prometheus/api/v1/query_range$"
|
||||
- "^/select/[0-9]+/prometheus/api/v1/series$"
|
||||
- "^/select/[0-9]+/prometheus/api/v1/labels$"
|
||||
- "^/select/[0-9]+/prometheus/api/v1/label/.+/values$"
|
||||
- "^/select/[0-9]+/prometheus/api/v1/export$"
|
||||
- "^/select/[0-9]+/prometheus/federate$"
|
||||
url_prefix: "http://victoria-metrics:8428"
|
||||
EOF
|
||||
|
||||
echo "✅ 已追加管理员只读账号(可跨租户查询)"
|
||||
}
|
||||
|
||||
generate_vmauth_and_grafana_datasources
|
||||
|
||||
# 检查配置文件
|
||||
if [ ! -f "config/prometheus/alert_rules.yml" ]; then
|
||||
echo "❌ 配置文件 config/prometheus/alert_rules.yml 不存在"
|
||||
@@ -267,6 +414,7 @@ mkdir -p "${VICTORIAMETRICS_DATA_DIR}"
|
||||
mkdir -p config/grafana/dashboards
|
||||
mkdir -p config/grafana/provisioning/datasources
|
||||
mkdir -p config/grafana/provisioning/dashboards
|
||||
mkdir -p config/vmauth
|
||||
|
||||
# 设置目录权限
|
||||
# Prometheus 需要写权限
|
||||
|
||||
@@ -77,14 +77,25 @@ services:
|
||||
container_name: victoria-metrics
|
||||
restart: unless-stopped
|
||||
mem_limit: "64m"
|
||||
ports:
|
||||
- "${VICTORIAMETRICS_PORT:-8428}:8428"
|
||||
volumes:
|
||||
- ${VICTORIAMETRICS_DATA_DIR:-./data/victoria-metrics-data}:/victoria-metrics-data
|
||||
command:
|
||||
- '--storageDataPath=/victoria-metrics-data'
|
||||
- "--retentionPeriod=${VICTORIAMETRICS_RETENTION_PERIOD:-30d}"
|
||||
- "--httpListenAddr=:${VICTORIAMETRICS_PORT:-8428}"
|
||||
|
||||
# vmauth:VictoriaMetrics 的鉴权/路由入口(对外只暴露 vmauth)
|
||||
vmauth:
|
||||
image: victoriametrics/vmauth:latest
|
||||
container_name: vmauth
|
||||
restart: unless-stopped
|
||||
mem_limit: "64m"
|
||||
ports:
|
||||
- "${VICTORIAMETRICS_PORT:-18428}:8427"
|
||||
volumes:
|
||||
- ./config/vmauth/vmauth.yml:/etc/vmauth/vmauth.yml:ro
|
||||
command:
|
||||
- "-auth.config=/etc/vmauth/vmauth.yml"
|
||||
- "-httpListenAddr=:8427"
|
||||
|
||||
# GPS 标注助手(上传/下载 targets.csv,H5 采集 GPS + 天地图校验)
|
||||
topology-editor:
|
||||
|
||||
@@ -40,8 +40,8 @@ GRAFANA_PORT=3000
|
||||
ALERTMANAGER_PORT=9093
|
||||
|
||||
# VictoriaMetrics 端口(边缘 vmagent 通过 remote_write 推送到此端口)
|
||||
# 必须与边缘侧 CENTRAL_VM_URL 中的端口一致;通常不通过 Traefik,边缘直连
|
||||
VICTORIAMETRICS_PORT=8428
|
||||
# 必须与边缘侧 CENTRAL_SERVER_PORT 一致;通常不通过 Traefik,边缘直连
|
||||
VICTORIAMETRICS_PORT=18428
|
||||
|
||||
# ============================================
|
||||
# Grafana 配置
|
||||
@@ -92,6 +92,33 @@ PROMETHEUS_REMOTE_WRITE_MAX_SHARDS=10
|
||||
# VM 数据保留时间(如 30d、90d)
|
||||
VICTORIAMETRICS_RETENTION_PERIOD=30d
|
||||
|
||||
# ============================================
|
||||
# vmauth(鉴权 / 多租户入口)
|
||||
# ============================================
|
||||
# vmauth 作为 VictoriaMetrics 的统一入口:对外仅暴露 vmauth 端口;
|
||||
# - 写入账号:边缘 vmagent、中央 Prometheus remote_write
|
||||
# - 只读账号:Grafana 查询(建议只读)
|
||||
#
|
||||
# 生产环境必须修改为强口令,并避免跨环境复用。
|
||||
#
|
||||
# 【严格多租户(推荐)】
|
||||
# 在 central-server/config/vmauth/tenants.csv 中为每个边缘节点配置独立凭据与 tenant_id;
|
||||
# deploy.sh 会据此生成 vmauth.yml 与 Grafana 多数据源 provisioning。
|
||||
# 可参考示例:central-server/config/vmauth/tenants.csv.example
|
||||
#
|
||||
# 【单租户兼容模式(可选)】
|
||||
# 如果你不提供 tenants.csv,将使用下面这组单租户账号生成 vmauth 配置(不做按 tenant 隔离)。
|
||||
VMAUTH_WRITE_USER=vm_write
|
||||
VMAUTH_WRITE_PASSWORD=change-me-strong-write
|
||||
VMAUTH_READ_USER=vm_read
|
||||
VMAUTH_READ_PASSWORD=change-me-strong-read
|
||||
|
||||
# 【管理员只读账号(可选)】
|
||||
# 允许访问所有租户的 /select/<tenant_id>/prometheus/... 查询接口(只读)。
|
||||
# 用途:管理员在同一套 Grafana 下查看所有租户(可在仪表盘用“数据源变量”切换租户)。
|
||||
VMAUTH_ADMIN_USER=vm_admin
|
||||
VMAUTH_ADMIN_PASSWORD=change-me-strong-admin
|
||||
|
||||
# ============================================
|
||||
# 数据存储路径
|
||||
# ============================================
|
||||
|
||||
Reference in New Issue
Block a user