Cortex 多租户认证与授权实战:基于 X-Scope-OrgID 的租户隔离方案

可观测性时序数据库后端指标监控【免费下载链接】cortexA horizontally scalable, highly available, multi-tenant, long term Prometheus.项目地址https://gitcode.com/gh_mirrors/cortex6/cortex点击查看免费下载本篇技术指南围绕 Cortex 的多租户认证与授权机制展开核心讲解X-Scope-OrgID请求头的传递方式、-auth.enabledfalse单租户模式、可信环境下的remote_write免认证接入以及如何借助反向代理与 cortex-tenant 代理为 Prometheus 请求注入租户标识。读完本文你将掌握在真实部署中为 Cortex 正确配置租户隔离、处理写入与查询租户一致性以及规避常见安全误配的完整方案。多租户模型一切组件都信任 X-Scope-OrgIDCortex 是一个水平可扩展、高可用、多租户的长期 Prometheus 存储系统。在多租户模型下每一个 Cortex 组件都会从每个请求的X-Scope-OrgID请求头中读取租户 IDtenant ID也称为 user 或 org。一个租户是写入到 Cortex、并从 Cortex 查询的一组时序数据的属主租户 ID 本质上就是这套时序数据在集群中的命名空间。这一机制的落地贯穿了从 HTTP 到 gRPC 的整条链路。在 HTTP 层middleware.AuthenticateUser负责从请求头提取租户 ID 并注入请求上下文context在 gRPC 层则通过middleware.ServerUserHeaderInterceptor与StreamServerUserHeaderInterceptor两个拦截器完成同样的工作参见 pkg/util/fakeauth/fake_auth.go。提取出的租户 ID 最终会被各组件用于数据读写、配额限制overrides、环形哈希分片ring sharding等所有与租户相关的逻辑。以写入链路为例Prometheus 通过remote_write将数据推送到 Cortex 的/api/prom/push端点Distributor 会依据请求上下文中的租户 ID 将时序数据路由并写入对应租户的存储空间查询链路则相反Querier 从上下文中取出租户 ID只读取该租户名下的数据。整个流程对租户 ID 的依赖是全链路、无例外的。信任边界与安全模型为什么必须增加额外防护层需要特别强调的是Cortex 的所有组件都完全信任X-Scope-OrgID的值它不会对这个值做真实性校验也不会反向验证调用方的身份。如果你的 Cortex 实例暴露在不可信网络中任何能够构造请求的人都可以通过伪造X-Scope-OrgID头冒充任意租户读写数据。因此若需要防止意外或恶意的调用就必须在 Cortex 之外增加一层额外的保护。典型做法是把 Cortex 部署在反向代理reverse proxy之后并确保所有调用方——无论是通过remote_write接口推送数据的机器还是通过 GUI 发起查询的人——都必须提供能够标识身份并确认其已获授权的凭据credentials。反向代理负责完成认证Authentication你是谁与授权Authorisation你能访问哪个租户校验通过后再代为注入X-Scope-OrgID头转发给后端的 Cortex 组件。在配置 Prometheus 的remote_writeAPI 时可以使用 HTTP Basic Auth 的user与password字段或 Bearer token 来携带租户 ID 和/或凭据。这是官方推荐的身份传递方式因为它把租户标识与调用方身份认证统一到了标准 HTTP 认证机制中反向代理可以透明地解析并校验这些凭据再转换为X-Scope-OrgID头。可信环境下的免认证接入在 remote_write 中直接设置请求头如果你运行在可信环境trusted environment中——例如集群内部网络、所有写入方都已被信任——可以让 Prometheus 自己发送X-Scope-OrgID头通过在remote_write配置的headers字段中直接声明即可remote_write: - url: http://cortex/prometheus/api/v1/push headers: X-Scope-OrgID: org其中org替换为你的租户 IDcortex替换为 Cortex 集群的入口地址。这种方式的优点是不需要额外部署代理组件配置简单直接代价是安全性完全依赖于网络环境的可信度——只要网络内有任意主机能连到 Cortex它就可以伪造该头。从源码角度看这一配置之所以能生效是因为 HTTP 层提取租户 ID 的中间件只是机械地读取X-Scope-OrgID头并写入上下文见 pkg/api/api.go 中HTTPAuthMiddleware对处理器的包装逻辑它不区分这个头是 Prometheus 自己发的、代理注入的还是攻击者伪造的。因此可信环境 自带头和不可信环境 代理校验两种部署方式必须在设计安全模型时就明确区分。关闭多租户-auth.enabledfalse 与 fake 租户如果不需要多租户功能例如单租户的私有部署可以向每一个 Cortex 组件传入-auth.enabledfalse参数。此时所有请求的租户 ID 都会被统一设置为字符串fake。该开关在 pkg/cortex/cortex.go 中定义默认值为truef.BoolVar(c.AuthEnabled, auth.enabled, true, Set to false to disable auth.)当AuthEnabled为false时pkg/util/fakeauth/fake_auth.go 中的SetupAuthMiddleware会做三件事为 HTTP 层挂载fakeHTTPAuthMiddleware该中间件直接把fake注入请求上下文再透传请求user.InjectOrgID(r.Context(), fake)为 gRPC 一元调用挂载fakeGRPCAuthUniaryMiddleware同样注入fake租户 ID为 gRPC 流式调用挂载fakeGRPCAuthStreamMiddleware包裹ServerStream使其上下文携带fake。也就是说关闭认证后 Cortex 内部的租户解析逻辑依然在运行只是所有请求都被强行归一到fake这一个租户名下数据全部写入fake命名空间。这保证了组件间通信代码无需感知认证是否启用内部依然保持多租户的处理逻辑。需要留意的是即使auth.enabled保持开启也并非所有 gRPC 方法都需要校验租户 ID。在 pkg/cortex/cortex.go 中有一份显式的豁免名单noGRPCAuthOn包括健康检查grpc.health.v1.Health/Check、前端到调度器的长连接schedulerpb.SchedulerForFrontend/FrontendLoop、Querier 与调度器的schedulerpb.SchedulerForQuerier/QuerierLoop等方法。原因是这些调用要么天然不带租户如健康检查要么单次长连接会为多个租户服务无法在握手阶段绑定单一租户 ID。租户 ID 命名规范写入前必须先校验的约束在配置租户 ID 之前务必了解 Cortex 对租户 ID 命名的三条硬性约束详见 Tenant ID 命名规范。虽然租户 ID 对 Cortex 而言是不透明的字符串但命名仍有限制1. 支持的字符集以下字符是安全可用的字母与数字0-9、a-z、A-Z特殊字符感叹号!、连字符-、下划线_、单个句点.但.和..本身无效、星号*、单引号、左括号(、右括号)除此之外的字符都不安全尤其不支持斜杠/和空白字符空格。这一限制的底层实现位于 pkg/util/users/tenant.go 的isSupported函数它逐 rune 校验租户 ID 中的每个字符一旦遇到不支持的字符会返回形如tenant ID xxx contains unsupported character y的错误。2. 无效租户 ID以下租户 ID 在 Cortex 中被视为无效并会被拒绝当前目录.父目录..标记目录__markers__Cortex 内部用于块存储元数据标记的全局目录名用户索引文件user-index.json.gz这些判断在CheckTenantIDIsSupported中实现pkg/util/users/tenant.go目的是防止租户 ID 与对象存储中预留的目录/文件名冲突杜绝路径穿越类问题。3. 长度限制租户 ID 长度不应超过150 字节/字符超出会返回tenant ID is too long: max 150 characters错误pkg/util/users/tenant.go。上述全部规则都有对应的单元测试覆盖见 pkg/util/users/tenant_test.go测试用例包含了 150 字符边界、151 字符超限、./../__markers__/user-index.json.gz无效 ID以及全量特殊字符组合的合法校验。这些测试可以直接作为你选择租户 ID 时的合法性判据。写入与查询的租户一致性最常见的查不到数据根因官方文档明确了一个非常容易踩坑的约束写入数据时使用的租户 ID必须与查询时使用的租户 ID 完全一致。如果两者不匹配写入的时序数据会落在租户 A 的命名空间而查询却以租户 B 的身份发起结果自然是看不到任何数据即使匹配目前的实现中你也无法跨租户查看其他租户的时序数据——多租户隔离在读写路径上都是严格按租户 ID 分隔的。这一点可以在源码中得到印证从上下文提取租户 ID 后Querier、Distributor、Ingester 等组件均以该 ID 作为读写数据的键例如 pkg/util/users/resolver.go 中SingleResolver.TenantID的解析流程存储索引、overrides 限制、环形分片等全部按租户隔离。因此在接入新的写入源时务必先确认remote_write的认证配置、反向代理注入规则与查询端的租户 ID 三者一致再排查其他原因。如果你计划使用多个租户并希望允许跨租户查询Cortex 提供了租户联邦tenant federation能力当-tenant-federation.enabledtrue时请求中可用|分隔多个租户 ID例如X-Scope-OrgID: tenant-a|tenant-b底层通过 pkg/util/users/resolver.go 中的MultiResolver解析并归一化排序 去重租户列表。需要说明的是启用联邦后对租户 ID 字符集的限制会更严格|将变为保留分隔符而不能再出现在单个租户 ID 中。这是本文主文档之外、从源码结构推断的进阶能力具体可参考 Ruler 租户联邦 及相关实现 regex_resolver.go。Cortex-Tenant 代理从 Prometheus 标签自动提取租户当 Prometheus 实例较多、且你不想为每个实例单独配置认证头时可以采用cortex-tenant代理方案它是一个能够从 Prometheus 标签labels中提取租户 ID 的代理组件可以放置在 Prometheus 与 Cortex 之间。其工作流程是Prometheus 仍按原有方式将时序数据推送到代理代理在收到的时序数据中查找一个预定义标签将该标签的值作为X-Scope-OrgID头在将时序数据转发给 Cortex 时注入。这种方案非常适合在可信环境中运行 Cortex 并按某种标准例如团队、应用等将指标划分到不同命名空间的场景你只需在 Prometheus 的指标上打一个统一的租户标签代理即可自动完成标签 → 租户的映射无需逐台修改 Prometheus 的remote_write认证配置。需要特别提醒的是cortex-tenant 是第三方社区项目并非由 Cortex 团队维护。在将它引入生产环境前你需要自行评估其维护活跃度、安全性与功能完整性同时由于它只是做标签到请求头的转换并不承担身份认证职责它更适合可信环境下的命名空间划分而非不可信环境下的访问控制。完整接入检查清单最后汇总一份将新数据源接入 Cortex 多租户集群的检查清单覆盖本文全部要点确定租户 ID遵循 租户 ID 命名规范字符集受限、长度 ≤ 150、避开保留名选择接入方式可信环境可让 Prometheus 在remote_write.headers中直接声明X-Scope-OrgID不可信环境必须在反向代理处完成认证再注入该头或使用 cortex-tenant 从标签自动提取统一读写租户确认写入认证配置与查询端使用的租户 ID 完全一致否则查询将看不到数据确认认证开关单租户部署可对所有组件传-auth.enabledfalse统一使用fake租户多租户部署保持默认true并理解 gRPC 豁免名单的边界验证隔离性确认不存在跨租户可见性除非显式启用租户联邦并可在 tenant_test.go 的用例基础上补充自己的租户 ID 合法性自测。按照以上步骤你就能在 Cortex 上搭建出符合预期隔离语义的多租户读写链路同时避免查不到数据租户串号这两类最典型的生产事故。赞分享可观测性时序数据库后端指标监控【免费下载链接】cortexA horizontally scalable, highly available, multi-tenant, long term Prometheus.项目地址https://gitcode.com/gh_mirrors/cortex6/cortex点击查看免费下载相关推荐Grafana Loki 多租户隔离实战从 X-Scope-OrgID 认证到跨租户查询与 __tenant_id__ 标签Grafana Loki 多租户隔离实战从 X Scope OrgID 认证到跨租户查询与 __tenant_id__ 标签 Loki 从设计之初就是一个多租可观测性日志分析后端微服务对象存储云原生Grafana Tempo 多租户Multi-tenancy实战指南基于 X-Scope-OrgID 的租户隔离配置与源码剖析Grafana Tempo 多租户Multi tenancy实战指南基于 X Scope OrgID 的租户隔离配置与源码剖析 Tempo 是一个开箱即用后端可观测性链路追踪Thanos 多租户实战基于外部标签与分层 Querier 的租户隔离方案Thanos 多租户实战基于外部标签与分层 Querier 的租户隔离方案 本文围绕 docs/operating/multi tenancy.md http可观测性云原生时序数据库运维上一篇UniExtract2500格式一键提取你的万能文件解压神器下一篇GSD-2 编码 Agent 推倒重来决策指南四大信号、重新评估协议与低成本重写的架构支撑创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
报考提示:本文涉及的批次、材料要求可能随上级文件调整,报名前建议再确认一次。你所在的工种、城市、当前进度如果拿不准,可以直接电话 18236992212 或在线预约,我们按你的情况单独捋一遍流程,不白跑。
证书真伪提醒:凡是说"不用考试直接拿证""花钱买证""包过免考"的,基本都是假证或骗局。正规特种作业操作证必须本人参考、本人答题,办下来的证在应急管理部官网、河南省厅平台都能查到电子记录。查不到的证,上岗被查到要担责任,千万别图省事。拿不准的,先打 18236992212 问一句。
报考流程

从咨询到拿证,六步走完

不管这篇资讯讲的是哪个工种,报名到取证的流程都是这六步,照着走不绕弯。

01

咨询定工种

说清岗位和单位要求,确认该考哪类证。

02

材料预审

按清单准备,拍照发来免费预审。

03

报名建档

提交报名信息,同步本批次窗口。

04

考前辅导

理论题库加实操要点针对性训练。

05

参加考试

理论机考加实操考核,按批次安排。

06

取证复审

查证领证,到期前提醒复审换证。

报名咨询前台接待

正规培训通道

走应急管理部门认可的报名与培训渠道,本人参考本人答题。

材料免费预审

报名前拍照发来逐项核对,缺什么错什么当场指出来。

批次提前通知

河南应急厅批次一有消息,第一时间同步报名学员。

费用透明无隐形

报名前把费用明细一次性说清,包含哪些、怎么收都写明。

电话咨询

18236992212,说清工种和城市,我们按你的情况给建议。

邮箱咨询

809451989@qq.com,材料拍照发来,免费预审。

在线预约

留下姓名、电话、工种,我们安排专人回访对接。

濮阳 / 许昌

两地设服务点,就近安排报名与考试对接。

常见问题

关于报考,常被问到的几个问题

看完这篇资讯,下面这些问题顺便一起答了。

我现在报名,大概多久能参加考试?

材料预审通过、报名建档后,一般排在最近的一个批次。具体时间取决于河南应急管理厅当期批次安排和机位,濮阳、许昌本地考点通常每月都有场次。报名时我们会告诉你本批次的报名截止时间和预计考试时间。

没有相关工作经验,能直接考吗?

大部分工种允许零基础报名,经正规培训后参考。部分岗位对学历、体检有要求,具体以工种对照条件为准。不确定自己符不符合的,先说说你的情况,我们帮你判断该报哪个。

考试没过可以补考吗?怎么收费?

理论和实操分别考核,单科不合格一般有补考机会,补考按当期批次重新排期。费用明细我们会在报名前一次性说清,没有隐形收费。

企业要一批人考证,能统一办理吗?

可以。建筑、化工、制造类企业批量申报走企业团报通道,统一建档、对公收费、台账整理一起办,安全管理员配套我们也能对接。

拿到证以后多久要复审?在哪复审?

特种作业操作证每 3 年复审一次,满 6 年需要换证。复审不必须回发证地,濮阳、许昌本地都能办,异地也能对接。建议提前一两个月开始准备,别等证书过期了才想起这件事。

怎么查自己的证是不是真的?

上应急管理部官网或河南省厅政务平台,输入身份证号和证件号就能查电子记录。查不到的、或者有人跟你说"不用考试直接拿证"的,基本都是假证,上岗被查到要担责任,别图省事吃这个亏。

整个下来大概要花多少钱?

不同工种费用不一样,跟培训课时、考试次数挂钩。我们会在报名前把费用明细一次性说清,包含哪些、不包含哪些写在明面上,没有隐形收费。补考另行排期,费用按当期标准走。

我条件好像不太够,还能考吗?

年龄、学历、体检这几项卡得最严,哪项差一点、怎么补,各工种要求不同。别自己猜,把你的情况说清楚——多大年龄、什么学历、有没有相关经验——我们帮你判断该报哪个工种、差的条件怎么补,能考就告诉你怎么考,不能考也不耽误你时间。

个人预约 / 企业团报

文章里没说清的,直接问我们

你的工种、城市、当前进度,说一句就行。材料、批次、费用按你的情况单独捋,不套模板。