大数据流处理批处理数据工程【免费下载链接】flink项目地址https://gitcode.com/gh_mirrors/fli/flink点击查看免费下载委派令牌Delegation Token简称 DT是 Flink 在安全模式下替代长期凭证如 Kerberos 密码或 keytab访问受保护外部服务HDFS、HBase 等的核心机制。本文以 官方文档 为主体结合当前仓库中DelegationTokenProvider/DelegationTokenReceiverSPI 与DefaultDelegationTokenManager的实现源码系统讲解 DT 的诞生背景、生命周期、续约方案、代理用户限制与配置方式帮助你理解 Flink 集群如何在 JobManagerJM与 TaskManagerTM之间安全、透明地分发和刷新令牌。什么是委派令牌为什么要使用它委派令牌是部分服务用于替代长期凭证的一种认证令牌。Hadoop 生态中的许多服务都支持 DT因为与长期凭证相比它具备几个显著优点。无需在分布式环境中分发长期凭证在分布式应用中向所有节点分发长期凭证既麻烦又不安全——用户通常不希望把长期凭证作为应用数据的一部分在网络中传输那等于为攻击者额外打开了一个攻击面。DT 改变了这种局面整个分布式应用中只有单一位置例如 JobManager需要持有长期凭证由它负责向应用的其他部分例如各 TaskManager分发 DT后者即可凭 DT 完成对目标服务的认证。每个服务只需一个令牌即可完成认证如果使用 Kerberos 认证客户端与服务器的每一次连接都需要向密钥分发中心KDC发起请求并生成服务票据service ticket。在分布式系统中服务票据的数量会随着客户端进程数如 TM 数量× 服务进程数如 HDFS DataNode 数量迅速膨胀给 KDC 带来不必要的额外负载甚至可能触达 KDC 管理员设置的用量上限。委派令牌仅用于认证与长期凭证不同DT 只能用于向签发它的那个特定服务完成认证。你无法用已有的 DT 去创建新的 DT也无法为其他服务创建 DT。换句话说DT不是长期凭证它被许多服务用来替代 Kerberos 认证或其他形式的认证——尽管从实现细节上讲它并不与某种特定的认证机制绑定。委派令牌的生命周期DT 是服务特定的不存在一个集中式的机构可以为某个服务签发 DT。因此获取 DT 的第一步是能够向目标服务完成认证——在 Hadoop 生态中这一步通常通过 Kerberos 完成。这意味着长期凭证必须存在于应用的某个位置。用户通常负责提供这些凭证最常见的方式是登录 KDC例如执行kinit生成包含票据授予票据TGT的凭证缓存credential cacheTGT 随后可用于请求服务票据。虽然获取 TGT 还有其他途径但归根结底你需要一个 TGT 来引导整个过程。一旦拿到 TGT就可以使用目标服务的客户端库向该服务认证并请求创建委派令牌。此后该令牌可以被发送给其他进程用于向该服务的不同守护进程完成认证。DT 的第一个缺点也由此显现你需要服务特定的逻辑来创建和使用它们。对此Flink 实现了一套一定程度上可插拔的内部 DT 创建 API。要为新的服务添加支持只需实现一个DelegationTokenProvider委派令牌管理器delegation token manager在为应用生成 DT 时会调用它。在接口层面该 SPI 定义在 DelegationTokenProvider.java核心方法包括serviceName()返回服务名称要求全局唯一init(Configuration)构造后由DelegationTokenManager调用以完成初始化delegationTokensRequired()返回该服务当前是否确实需要 DTobtainDelegationTokens()返回ObtainedDelegationTokens对象其中包含令牌的序列化字节数组tokens以及OptionalLong validUntil——即令牌的到期时间若永久有效则返回Optional.empty()。令牌创建之后其运作语义同样是服务特定的但大体遵循 Kerberos 令牌的语义renewable period对应 TGT 的 lifetime令牌在需要续约之前的有效期max lifetime对应 TGT 的 renewable life令牌可以被续约的最长时间。一旦令牌达到 max lifetime就必须重新联系对应服务创建新令牌即重启上述整个流程。委派令牌的续约与 Renewer这是 DT 处理中最容易令人困惑的部分部分原因在于这套体系当初主要是围绕 Apache Hadoop YARN 设计的尽管后来扩展到了其他服务和机制。如上所述DT 需要周期性续约直到最终彻底过期。以 HDFS 服务的默认配置为例委派令牌最长有效期为 7 天且每 24 小时必须续约一次如果 24 小时未续约令牌便无法再使用7 天之后令牌也无法再被续约。那么谁来负责续约很长一段时间里答案都是 YARN。提交 YARN 应用时会随应用一起提交一组 DT。YARN 负责将这些令牌分发给容器遵循UserGroupInformationAPI 约定的机制并在应用运行期间持续为其续约。这些令牌不仅供应用本身使用也被 YARN 自身用于实现日志收集与聚合等功能。但这带来几个需要注意的问题。谁在续约令牌在 YARN 场景下这一步大多由 Hadoop 库透明地处理。部分服务有令牌续约者renewer的概念它是被允许续约该 DT 的服务主体名称。提交到 YARN 时renewer 就是 YARN 服务所运行的那个主体这意味着客户端应用需要知道该信息。而对于其他资源管理器renewer 通常无关紧要因为没有服务在真正执行续约。哪些令牌会被续约这是最大的坑。如前所述DT 是服务特定的创建和续约都需要服务特定的库。要让 YARN 能为应用续约令牌YARN 需要应用所使用的全部服务的客户端库如何连接这些服务的信息连接这些服务的权限。但实际上多数时候 YARN 只能访问单个 HDFS 集群其 DT 续约能力也就止步于此。任何其他提交给 YARN 的令牌虽然会被分发到容器却不会被续约。这意味着除非有其他代码负责续约否则这些令牌会在远未达到 max lifetime 之前就过期。另外并非所有客户端库都实现了令牌续约。以 Flink 支持的服务为例HBase 令牌的renew()方法是一个 no-op因此续约HBase 令牌的唯一方式就是创建一个新令牌。这一点在源码中有直接印证HBaseDelegationTokenProvider.java 中注释明确写着 HBase does not support to renew the delegation token currently因此其obtainDelegationTokens()返回的validUntil是Optional.empty()。令牌彻底过期后会发生什么最后一个问题是无论怎样续约DT 都有最大寿命。过了这个期限你必须创建新令牌才能连接服务。这意味着你需要具备不依赖 DT 也能连接服务的能力即需要某种 DT 之外的认证方式。这对长期无人值守运行的应用尤其重要——它们必须能够持续运行下去而不必每隔几天就有人登录终端敲一次密码。Flink 的委派令牌续约机制针对上述问题Flink 实现了一套不同的续约方式。这个方案是一个折中它瞄准的是最低公共分母即像 HBase 这样不支持真正令牌续约的服务。下面的讨论经常以 Hadoop 生态组件为例展开因为从认证角度看它们往往比 AWS S3 等其他服务更复杂。在 Flink 中DT 的续约是通过**给应用提供长期凭证如 keytab**来启用的。keytab 相当于把 Kerberos 密码明文写入一个文件因此极其敏感任何人只要拿到 keytab 文件只要其中的凭证在 KDC 中依然有效就可以以该用户身份向任何服务认证。持有 keytab 后Flink 可以无限期地维持一个有效的 Kerberos TGT。有了长期凭证Flink 会在旧 DT 过期时为已配置的服务创建新令牌。也就是说Flink 并不像上一节描述的那样续约令牌而是在每个续约周期创建新令牌并把这些新令牌分发给 TM。这种方案除了支持像 HBase 这样的服务之外还有另一个优势消除了对外部续约服务如 YARN的依赖。因此只要应用持有长期凭证Flink 的续约特性就可以用于不支持 DT 的资源管理器例如 Kubernetes。源码视角DefaultDelegationTokenManager 的续约循环上述机制在运行时由 DefaultDelegationTokenManager.java 实现。它通过 Java 的ServiceLoader加载所有注册的DelegationTokenProvider并持有配置项security.delegation.tokens.renewal.time-ratio与security.delegation.tokens.renewal.retry.backoff。其核心循环startTokensUpdate()L305-L354大致如下调用obtainDelegationTokensAndGetNextRenewal(container)L252-L287遍历所有 provider对每个delegationTokensRequired()返回 true 的 provider 调用obtainDelegationTokens()把序列化后的令牌写入DelegationTokenContainer并收集各令牌的validUntil取其中的最小值作为下一次续约时间点若容器中确有令牌则先通过DelegationTokenReceiverRepository.onNewTokensObtained(container)让本进程内的 receiver 生效再通过listener.onNewTokensObtained(...)把序列化后的容器通知出去由集群运行时负责分发给各 TaskManager根据calculateRenewalDelayL366-L377计算下次续约延迟renewalDelay round(timeRatio * (nextRenewal - now))并用ScheduledExecutor安排下一次令牌刷新若某次获取令牌失败则按renewalRetryBackoffPeriod的退避时间重试。相应地令牌接收侧由 DelegationTokenReceiver.java 定义其onNewTokensObtained(byte[] tokens)回调负责把新令牌应用到本进程。Hadoop 场景的接收实现 HadoopDelegationTokenReceiver.java 会反序列化Credentials并调用UserGroupInformation.getCurrentUser().addCredentials(credentials)完成注入。Provider 与 Receiver 通过服务名一一对应注册信息位于 META-INF/services/org.apache.flink.core.security.token.DelegationTokenProvider当前仓库内置了HadoopFSDelegationTokenProvider服务名hadoopfs见 HadoopFSDelegationTokenProvider.java与HBaseDelegationTokenProvider两个实现。委派令牌与代理用户Proxy Users代理用户是 Hadoop 术语指身份模拟impersonation如果服务允许用户 A 可以在连接该服务时模拟用户 B。Flink 在提交应用时不允许模拟身份。Spark 支持模拟身份但不支持令牌续约而 Flink 主要面向流式工作负载添加该特性收益有限因此 Flink 直接选择了不支持。外部生成的委派令牌Flink 使用UserGroupInformationUGIAPI 管理 Hadoop 凭证因此继承了从文件自动加载 DT的特性当定义了HADOOP_TOKEN_FILE_LOCATION环境变量时Hadoop 类会自动加载其指向的令牌缓存文件。该功能主要由替用户启动工作负载的服务使用普通用户很少使用——因为他们需要自己想办法在 Flink 之外获取这些令牌。从源码可以看到这一加载点位于 HadoopModule.java当登录用户来自 keytab 且环境变量HADOOP_TOKEN_FILE_LOCATION存在时会通过Credentials.readTokenStorageFile读取令牌文件并注入登录用户。需要注意的是Flink 自身也可以获取 DT如果UGI中已包含某个服务的 DT而 Flink 又配置了为该服务获取令牌那么该令牌会先被加载、随后被 Flink 的加载机制覆盖。委派令牌支持的局限性使用 DT 时需要注意以下限制以下内容完整引自官方文档并结合源码补充了配置手段并非所有 DT 都暴露续约周期续约周期是服务配置通常不暴露给客户端。因此某些 DT provider 无法提供续约周期要求该服务的配置在某种程度上与另一个能提供该信息的服务保持同步。HDFS 服务通常恰恰是在需要 DT 时总会出现的那一个能提供该信息所以一般建议所有使用 DT 的服务在续约周期上采用与 HDFS 相同的配置。Flink 不解析用户应用代码因此它不知道应用到底需要哪些 DT。这意味着 Flink 会基于可用配置尽可能多地获取 DT例如 HBase token provider 已启用但应用并未真正使用 HBase仍会生成一个 DT。此时用户必须显式禁用对应的 provider。在配置上可以通过security.delegation.token.provider.serviceName.enabled关闭某个 provider详见下文配置汇总这与 SecurityOptions.java 中DELEGATION_TOKEN_PROVIDER_ENABLED的说明一致。按需创建 DT 很困难Flink 是提前获取/分发令牌并按周期重新获取/重新分发。优点在于只要配置得当用户代码完全无需关心 DT——Flink 会透明地处理它们。存在认证到同一服务的外部文件系统插件一个典型例子是s3-hadoop与s3-presto两者都认证到 S3服务名不同却为同一服务获取令牌可能引发非预期后果。由于它们为同一服务获取令牌令牌存储在同一个位置如果二者使用相同凭证令牌会在单线程方式下互相覆盖属于同一用户不会出问题但如果配置了不同的用户凭证则数据处理实际使用的令牌可能属于任一用户结果不确定。配置汇总与默认值结合 SecurityOptions.java 与DefaultDelegationTokenManager与 DT 相关的核心配置如下以当前仓库源码为准配置键类型默认值说明security.kerberos.login.principalString无与 keytab 关联的 Kerberos 主体名旧键security.principalsecurity.kerberos.login.keytabString无keytab 文件的绝对路径包含用户凭证旧键security.keytabsecurity.kerberos.login.use-ticket-cacheBooleantrue是否从 Kerberos 票据缓存中读取凭证security.kerberos.login.contextsString无逗号分隔的登录上下文列表例如Client,KafkaClientsecurity.kerberos.krb5-conf.pathString无krb5.conf的本地路径定义后会挂载到 K8s/Yarn 的 JM、TM 容器security.delegation.tokens.enabledBooleantrue是否启动面向外部服务的委派令牌体系旧键kerberos.fetch.delegation.tokensecurity.delegation.tokens.renewal.time-ratioDouble0.75在令牌到期前多久重新获取新凭证到期时间 × 该比例security.delegation.tokens.renewal.retry.backoffDuration1h获取令牌失败后重试前等待的时间security.delegation.token.provider.serviceName.enabledBooleantrue是否在安全模式下为某服务获取凭证默认会为所有已配置且受支持的服务获取其中security.delegation.token.provider是 provider 的配置前缀见 DelegationTokenProvider.javareceiver 对应前缀为security.delegation.token.receiver见 DelegationTokenReceiver.java。SecurityOptions还提供了SecurityOptions.forProvider(config, my_provider)便捷方法L237-L241用于按 provider 读写其专属配置例如Configuration config ...; SecurityOptions.forProvider(config, hadoopfs) .set(SecurityOptions.DELEGATION_TOKEN_PROVIDER_ENABLED, false);需要说明的是委派令牌体系与 Kerberos 登录配置紧密耦合。完整的 Kerberos 安全配置keytab、principal、ticket cache 等以及 SSL/TLS 相关配置可进一步阅读同目录下的 Kerberos 认证指南 与 SSL 配置指南。若要为全新服务接入 DT 支持则需同时实现DelegationTokenProvider与同服务名的DelegationTokenReceiver并在META-INF/services中注册参考 DefaultDelegationTokenManager.java 对 provider/receiver 一致性校验的说明。赞分享大数据流处理批处理数据工程【免费下载链接】flink项目地址https://gitcode.com/gh_mirrors/fli/flink点击查看免费下载相关推荐Flink Delegation Token委托令牌安全机制完全指南原理、续期与配置Flink Delegation Token委托令牌安全机制完全指南原理、续期与配置 本文以 Apache Flink 的 Delegation Toke大数据流处理批处理数据工程Spark 委托令牌Delegation Token处理机制完全指南从 Kerberos 到令牌分发与续期Spark 委托令牌Delegation Token处理机制完全指南从 Kerberos 到令牌分发与续期 导读 委托令牌Delegation Toke大数据数据分析批处理流处理机器学习图计算YouTube.js OAuth2Tokens 类型全解析掌握 InnerTube OAuth2 令牌结构与令牌生命周期管理YouTube.js OAuth2Tokens 类型全解析掌握 InnerTube OAuth2 令牌结构与令牌生命周期管理 导读 OAuth2Tokens后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考