4. 日志平台组件拓扑:采集、传输、存储、查询的交互关系

日志平台组件拓扑定义了日志数据从产生到消费的完整路径。在云原生环境中,各组件之间的交互关系直接影响权限模型的边界划分。本节将拆解日志流水线的四个核心阶段,并明确每个阶段涉及的资源与接口。

4.1 日志流水线四阶段模型

日志平台通常遵循“采集 → 传输 → 存储 → 查询”的线性拓扑结构。每个阶段承担不同的职责,并暴露不同的资源类型。

阶段 核心组件 数据形态 典型协议/接口
采集 Filebeat / Fluent Bit / Vector 原始文本、JSON 行 文件 tail、stdout、SDK
传输 Kafka / NATS / 内存队列 序列化消息(Avro/Protobuf) TCP、gRPC、HTTP
存储 Elasticsearch / Loki / ClickHouse 索引文档 / 日志块 REST API、批量写入接口
查询 Kibana / Grafana / 自研 UI 检索结果集 HTTP、WebSocket、SQL
拓扑设计要点: 传输层作为缓冲与解耦枢纽,是权限控制的关键分界点。采集端通常只具备写入传输层的权限,而查询端只具备读取存储层的权限。

4.2 组件交互关系与数据流

下图展示了日志平台各组件的拓扑结构及数据流动方向。箭头表示数据流向,虚线框表示逻辑分组。

日志平台组件拓扑与数据流 日志平台组件拓扑与数据流 采集层 Filebeat / Fluent Bit 容器 stdout / 文件 tail 输出:JSON 行 / 原始文本 传输层 Kafka / NATS Topic / Subject 序列化:Avro / Protobuf 存储层 Elasticsearch / Loki 索引 / 日志流 写入接口:Bulk API 查询层:Kibana / Grafana gRPC / TCP 批量写入 REST API 实时订阅 拓扑交互说明 1. 采集层通过文件 tail 或容器 stdout 获取原始日志,转换为结构化 JSON 行。 2. 传输层作为缓冲队列,解耦采集与存储,支持 Avro/Protobuf 序列化。 3. 存储层通过批量写入接口接收数据,构建索引或日志流。 4. 查询层通过 REST API 检索存储层,也可通过实时订阅获取传输层数据。

4.3 各组件资源模型与权限边界

每个组件暴露的资源类型不同,OPA 策略需要针对这些资源定义细粒度权限。下表列出了各层的关键资源模型。

组件层 资源类型 操作 权限粒度示例
采集层 采集器实例、采集配置 启动、停止、更新配置 仅允许 namespace:prod 的采集器读取 secret
传输层 Topic、Consumer Group 发布、订阅、偏移量管理 仅允许 app:payment 写入 topic:payment-logs
存储层 索引、日志流、分片 写入、删除、滚动 仅允许 team:security 删除索引
查询层 仪表盘、搜索模板、告警规则 查询、导出、创建告警 仅允许 role:admin 导出超过 10000 条日志

4.4 交互关系中的权限控制点

在组件交互的边界处,需要插入 OPA 策略进行权限校验。以下是四个关键控制点。

  1. 采集端 → 传输端:校验采集器是否有权向特定 Topic 写入数据。通常基于采集器身份(ServiceAccount)和命名空间标签。
  2. 传输端 → 存储端:校验传输组件是否有权向特定索引写入数据。需要验证 Topic 与索引的映射关系是否被授权。
  3. 存储端 → 查询端:校验用户是否有权查询特定索引或日志流。这是最常见的权限控制点,支持字段级脱敏。
  4. 查询端 → 传输端(实时订阅):校验用户是否有权实时订阅传输层数据。通常需要额外的流式读取权限。
常见误区: 很多团队只关注存储层的查询权限,忽略了采集端和传输端的写入权限控制。这可能导致恶意采集器向生产 Topic 注入伪造日志,或传输组件误写入非授权索引。

4.5 拓扑视角下的 OPA 策略设计原则

基于组件拓扑的交互关系,OPA 策略设计应遵循以下原则。

  • 边界校验原则:在每个组件交互的边界处(采集→传输、传输→存储、存储→查询)部署 OPA 策略,而不是在组件内部。
  • 资源映射原则:将每个组件的资源模型映射为统一的 OPA 输入格式。例如,Kafka Topic 映射为 input.resource.topic,ES 索引映射为 input.resource.index。
  • 最小权限原则:默认拒绝所有跨层操作,仅显式允许经过审批的交互路径。
  • 审计追溯原则:所有跨层交互必须携带请求来源标识(如采集器 ID、用户 ),便于审计。

4.6 典型拓扑变体:多集群与跨区域

在大型部署中,日志平台可能跨越多个 Kubernetes 集群或地理区域。此时拓扑会演变为更复杂的形态。

多集群日志拓扑变体 多集群日志拓扑变体 集群 A(生产) 采集器 Kafka 集群 A ES 集群 A 集群 B(灾备) 采集器 Kafka 集群 B ES 集群 B 全局查询层 跨集群复制 跨集群场景下,OPA 策略需要感知集群标识,防止跨集群越权访问
跨集群权限要点: 在多集群拓扑中,OPA 策略需要引入 input.cluster_id 字段。例如,仅允许集群 A 的采集器向集群 A 的 Kafka 写入,禁止跨集群直接写入。全局查询层需要校验用户是否有权跨集群聚合查询。

4.7 组件拓扑与 OPA 策略的映射关系

最后,将组件拓扑中的每个交互关系映射为 OPA 策略的输入结构。以下是一个典型的策略输入示例。

{
  "input": {
    "stage": "collection_to_transport",
    "source": {
      "component": "filebeat",
      "namespace": "prod",
      "service_account": "system:serviceaccount:prod:log-collector"
    },
    "destination": {
      "component": "kafka",
      "topic": "prod-app-logs",
      "cluster": "cluster-a"
    },
    "request": {
      "action": "write",
      "resource_type": "topic"
    }
  }
}

基于此输入,OPA 策略可以判断:

  • 采集器是否属于允许写入该 Topic 的命名空间?
  • 采集器的 ServiceAccount 是否具有 Topic 的写入权限?
  • 跨集群写入是否被显式允许?

通过将组件拓扑与 OPA 策略输入结构对齐,可以实现细粒度、可审计的日志平台权限控制。