4. 准入门禁概念:什么是准入门禁(Gateway/Auth Proxy),在日志检索中的作用与设计原则
在跨集群日志检索架构中,准入门禁(Gateway / Auth Proxy) 是位于客户端与后端日志存储/查询引擎之间的统一入口层。它并非简单的反向代理,而是集身份认证、请求路由、流量控制、审计日志于一体的安全中间件。在 Prometheus 生态与日志检索场景下,准入门禁承担着“统一鉴权、请求分发、安全隔离”的核心职责。
4.1 准入门禁的核心定义
准入门禁是一个无状态的代理服务,所有外部查询请求必须经过它才能到达后端的日志存储集群(如 Loki、Elasticsearch、ClickHouse 等)。它通常以 Sidecar 或独立 Deployment 的形式部署在集群边缘,作为南北向流量的唯一入口。
| 维度 | 说明 |
|---|---|
| 身份认证 | 验证请求方身份(、mTLS、OAuth2、LDAP) |
| 权限校验 | 基于 RBAC/ABAC 判断用户是否有权访问目标日志索引或命名空间 |
| 请求路由 | 根据请求中的集群标识、租户 ID、时间范围,将请求转发到正确的后端集群 |
| 流量控制 | 限制单用户/单 IP 的 QPS、并发数,防止恶意查询拖垮后端 |
| 审计日志 | 记录每次查询的请求方、时间、查询语句、返回行数,用于安全审计 |
关键认知: 准入门禁不是“网关”的简单重命名。在日志检索场景中,它必须理解日志查询协议(如 LogQL、ES DSL),才能实现细粒度的索引级权限控制,而不仅仅是 URL 路径转发。
4.2 准入门禁在日志检索中的作用
在跨集群日志检索架构中,准入门禁解决了三个核心问题:
- 统一鉴权与租户隔离:不同业务线、不同环境(生产/预发/测试)的日志存储在同一套后端集群时,准入门禁确保用户只能查询自己有权访问的日志流。
- 跨集群透明路由:用户无需感知日志数据分布在哪个集群,准入门禁根据请求中的
cluster标签或tenant字段自动路由到正确的后端。 - 安全防护与限流:防止未授权访问、SQL/LogQL 注入、大范围扫描查询(如
{__name__=~".+"})对后端造成过载。
实战案例: 某公司有 3 个 Loki 集群(prod、staging、dev),通过准入门禁统一暴露一个查询端点。用户在查询语句中携带
cluster="prod",准入门禁校验该用户是否有 prod 集群的读取权限,然后转发到 prod 集群的 querier 组件。
4.3 准入门禁的设计原则
设计一个生产可用的准入门禁,需要遵循以下五项核心原则:
| 原则 | 描述 | 实现要点 |
|---|---|---|
| 1. 无状态 | 准入门禁不存储任何会话或缓存状态,所有实例对等 | 使用 JWT 或外部 Session Store(Redis);支持水平扩缩 |
| 2. 最小权限 | 默认拒绝所有请求,仅显式授权的查询可通过 | 基于标签(label)或索引(index)级别的 ACL 配置 |
| 3. 透明代理 | 对客户端和后端尽量透明,不修改查询语义 | 保留原始请求头、查询参数;仅注入认证上下文 |
| 4. 可观测性 | 准入门禁自身必须暴露 Prometheus 指标和访问日志 | 记录请求延迟、状态码、拒绝原因、QPS 等指标 |
| 5. 故障隔离 | 准入门禁故障不应影响后端集群的正常运行 | 使用熔断器(Circuit Breaker)、超时控制、优雅降级 |
常见误区: 不要将准入门禁设计为“全能网关”,避免在其中实现日志聚合、数据清洗、格式转换等业务逻辑。准入门禁只做安全与路由,数据处理应交给后端的 querier 或 ingester 组件。
4.4 准入门禁的请求处理流程
一个典型的日志查询请求经过准入门禁的完整生命周期如下:
- 接收请求:客户端发起 HTTP/gRPC 请求,携带认证凭证(如 Bearer )。
- 身份认证:准入门禁验证 有效性(签名、过期时间、颁发者)。
- 权限校验:从 中提取用户角色/租户信息,与请求中的日志流标签进行匹配。
- 请求改写:在请求头中注入用户身份上下文(如
X-Tenant-ID),供后端做二次校验。 - 路由转发:根据请求中的
cluster参数或 DNS 解析,选择对应的后端集群地址。 - 限流检查:检查该用户/租户的当前 QPS 是否超过阈值,超过则返回 429 Too Many Requests。
- 审计记录:异步写入审计日志(查询语句、时间、结果行数、响应状态)。
- 返回响应:将后端返回的日志结果透传给客户端,并记录响应延迟指标。
4.5 准入门禁的典型配置示例
以下是一个基于 Envoy 或 Nginx 风格的准入门禁配置片段,展示如何实现基于 的认证与路由:
# 准入门禁路由规则示例(YAML 风格)
gateway:
listen: ":8080"
auth:
type: jwt
jwks_url: "https://auth.example.com/.well-known/jwks.json"
required_claims: ["sub", "tenant"]
rate_limit:
per_user: 100 # 每秒最多 100 次查询
per_tenant: 500
routes:
- match:
cluster: "prod"
tenant: "platform"
backend:
address: "loki-prod.internal:3100"
timeout: 30s
- match:
cluster: "staging"
tenant: "*"
backend:
address: "loki-staging.internal:3100"
timeout: 60s
audit:
log_file: "/var/log/gateway/audit.log"
fields: ["user", "query", "timestamp", "response_size"]
生产建议: 准入门禁的认证密钥(JWKS)应定期轮换,且准入门禁实例应部署在独立的网络命名空间,仅暴露必要的端口(如 8080/443),后端集群地址使用内部 DNS 或 Service Mesh 进行服务发现。