3. 标签(Tag)机制详解:标签的作用、标签命名规范、标签与路由的关系
在 Fluent Bit 多租户日志路由体系中,标签(Tag) 是连接数据采集与数据输出的核心纽带。每个日志记录在进入管道时都会被赋予一个标签,该标签决定了这条日志最终流向哪个输出插件。理解标签机制,是掌握多租户路由的第一步。
3.1 标签的核心作用
标签在 Fluent Bit 中承担以下三项关键职责:
- 数据标识:为每条日志记录标记来源(如:来自哪个主机、哪个容器、哪个应用)。
- 路由决策:输出插件通过
match规则匹配标签,决定是否接收该日志。 - 多租户隔离:不同租户的日志使用不同的标签前缀,实现逻辑隔离,避免数据混流。
核心原则:标签是 Fluent Bit 中唯一的路由依据。没有标签,输出插件无法判断日志归属;标签错误,日志将丢失或路由到错误的输出。
3.2 标签命名规范与最佳实践
Fluent Bit 的标签命名没有强制语法限制,但遵循一套约定俗成的规范,有助于构建可维护的多租户路由体系。推荐使用 点分隔(.) 或 斜杠分隔(/) 的层级结构。
| 规范类型 | 示例 | 说明 |
|---|---|---|
| 点分隔层级 | tenant-a.app.nginx |
租户 → 应用 → 组件,清晰表达归属关系 |
| 斜杠分隔层级 | tenant-b/backend/api |
与 Kubernetes 资源命名风格一致 |
| 来源前缀 | kube.var.log.containers |
Fluent Bit 内置输入插件自动生成的标签格式 |
| 通配符友好 | prod.web.* |
便于使用 * 通配符进行批量匹配 |
多租户命名建议:始终将 租户标识 放在标签的最左侧,例如
tenant-alpha.service.web。这样在输出配置中可以使用 match tenant-alpha.* 一次性匹配该租户的所有日志。
3.3 标签与路由的关系:匹配规则
输出插件通过 match 或 match_* 指令来声明自己需要处理哪些标签的日志。Fluent Bit 支持三种匹配模式:
- 精确匹配:
match tenant-a.app.nginx— 只接收标签完全等于tenant-a.app.nginx的日志。 - 通配符匹配:
match tenant-a.*— 接收所有以tenant-a.开头的标签。 - 多规则匹配:
match tenant-a.* tenant-b.*— 使用空格分隔多个匹配模式,满足任一即可。
下图展示了标签如何驱动日志从输入到输出的完整路由过程:
3.4 标签的自动生成与手动覆盖
标签的来源有两种方式:
- 自动生成:大多数输入插件(如
tail、systemd、kubernetes)会根据配置或文件路径自动生成标签。例如tail插件默认使用文件路径作为标签。 - 手动覆盖:在输入插件配置中使用
tag参数可以覆盖默认标签。例如:tag tenant-a.app.nginx。
注意:当使用
tag 参数手动覆盖时,Fluent Bit 会完全替换自动生成的标签,而不是追加。如果希望保留部分原始信息,可以使用 tag_prefix 或 tag_regex 进行更精细的控制。
3.5 标签与多租户路由的典型配置
以下是一个多租户场景下的标签与路由配置示例:
[INPUT]
Name tail
Path /var/log/containers/*.log
Tag kube.var.log.containers.*
Tag_Regex (?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?)_(?<namespace>[^_]+)_(?<container>[^_]+)-
DB /var/log/flb_kube.db
[OUTPUT]
Name elasticsearch
Match tenant-alpha.*
Host es-alpha.internal
Port 9200
Index logs-alpha
[OUTPUT]
Name s3
Match tenant-beta.*
Bucket logs-beta
Region us-east-1
在此配置中:
- 输入插件从容器日志文件读取数据,自动生成包含命名空间信息的标签。
- 输出插件通过
Match规则分别匹配tenant-alpha.*和tenant-beta.*的日志。 - 不同租户的日志被路由到不同的后端存储,实现完全隔离。
3.6 标签匹配的优先级与冲突处理
当多个输出插件匹配同一个标签时,Fluent Bit 会将日志记录复制并发送给所有匹配的输出。这是实现日志多路复用的基础。但需要注意:
- 无优先级:所有匹配的输出插件都会收到日志,不存在先后顺序。
- 冲突避免:如果两个输出插件使用相同的
match规则,且目标后端相同,可能导致重复写入。建议为每个输出插件设计唯一的匹配模式。 - 排除规则:使用
match_exclude参数可以排除某些标签,避免日志被错误路由。
最佳实践:在多租户场景中,为每个租户分配一个唯一的标签前缀,并在输出插件中使用
match <租户前缀>.* 进行匹配。这样既保证了隔离性,又便于后期扩展新租户。