本文已发表超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否仍然正确。
Kubernetes 1.30:结构化身份验证配置进入 Beta 阶段
随着 Kubernetes 1.30 的发布,我们(SIG Auth)正在将结构化身份验证配置迁移到 beta 阶段。
今天的文章是关于**身份验证**:找出谁正在执行任务,并验证他们是否是他们声称的那个人。明天请回来查看 Kubernetes v1.30 在**授权**(决定某人可以访问什么以及不能访问什么)方面的新进展。
动机
Kubernetes 对更灵活和可扩展的身份验证系统有着长期需求。当前的系统虽然强大,但在某些场景下存在一些限制,使其难以使用。例如,无法使用相同类型的多个身份验证器(例如,多个 JWT 身份验证器),也无法在不重启 API 服务器的情况下更改配置。结构化身份验证配置功能是解决这些限制并提供更灵活和可扩展的 Kubernetes 身份验证配置方式的第一步。
什么是结构化身份验证配置?
Kubernetes v1.30 构建在基于文件的身份验证配置的实验性支持之上,该支持在 Kubernetes v1.30 中以 alpha 版形式添加。在此 beta 阶段,Kubernetes 仅支持配置 JWT 身份验证器,它作为现有 OIDC 身份验证器的下一个迭代。JWT 身份验证器是使用符合 JWT 的令牌来验证 Kubernetes 用户的身份验证器。该身份验证器将尝试解析原始 ID 令牌,并验证其是否已由配置的颁发者签名。
Kubernetes 项目添加了文件配置,以便提供比使用命令行选项更灵活的方式(命令行选项仍然有效并受支持)。支持配置文件也使得在后续版本中轻松提供更多改进成为可能。
结构化身份验证配置的优势
以下是使用配置文件配置集群身份验证的优势所在:
- 多个 JWT 身份验证器:你可以同时配置多个 JWT 身份验证器。这允许你使用多个身份提供者(例如,Okta、Keycloak、GitLab),而无需使用像 Dex 这样的中间层来处理多个身份提供者之间的多路复用。
- 动态配置:你可以在不重启 API 服务器的情况下更改配置。这允许你添加、移除或修改身份验证器,而不会中断 API 服务器。
- 任何 JWT 兼容令牌:你可以使用任何 JWT 兼容令牌进行身份验证。这允许你使用任何支持 JWT 的身份提供者颁发的令牌。有效的 JWT 负载至少必须包含 Kubernetes 文档中结构化身份验证配置页面中说明的声明(claim)。
- CEL (通用表达式语言) 支持:你可以使用CEL 来确定令牌的声明是否与 Kubernetes 中的用户属性(例如,用户名、组)匹配。这允许你使用复杂的逻辑来判断令牌是否有效。
- 多个受众:你可以为一个身份验证器配置多个受众。这允许你将同一个身份验证器用于不同的受众,例如为
kubectl
和 dashboard 使用不同的 OAuth 客户端。 - 使用不支持 OpenID Connect Discovery 的身份提供者:你可以使用不支持OpenID Connect Discovery 的身份提供者。唯一的要求是将发现文档托管在与颁发者不同位置(例如在集群本地),并在配置文件中指定
issuer.discoveryURL
。
如何使用结构化身份验证配置
要使用结构化身份验证配置,你需要在 API 服务器中指定 --authentication-config
命令行参数,指向身份验证配置文件的路径。该配置文件是 YAML 格式的,用于指定身份验证器及其配置。以下是配置两个 JWT 身份验证器的示例配置文件:
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
# Someone with a valid token from either of these issuers could authenticate
# against this cluster.
jwt:
- issuer:
url: https://issuer1.example.com
audiences:
- audience1
- audience2
audienceMatchPolicy: MatchAny
claimValidationRules:
expression: 'claims.hd == "example.com"'
message: "the hosted domain name must be example.com"
claimMappings:
username:
expression: 'claims.username'
groups:
expression: 'claims.groups'
uid:
expression: 'claims.uid'
extra:
- key: 'example.com/tenant'
expression: 'claims.tenant'
userValidationRules:
- expression: "!user.username.startsWith('system:')"
message: "username cannot use reserved system: prefix"
# second authenticator that exposes the discovery document at a different location
# than the issuer
- issuer:
url: https://issuer2.example.com
discoveryURL: https://discovery.example.com/.well-known/openid-configuration
audiences:
- audience3
- audience4
audienceMatchPolicy: MatchAny
claimValidationRules:
expression: 'claims.hd == "example.com"'
message: "the hosted domain name must be example.com"
claimMappings:
username:
expression: 'claims.username'
groups:
expression: 'claims.groups'
uid:
expression: 'claims.uid'
extra:
- key: 'example.com/tenant'
expression: 'claims.tenant'
userValidationRules:
- expression: "!user.username.startsWith('system:')"
message: "username cannot use reserved system: prefix"
从命令行参数迁移到配置文件
结构化身份验证配置功能设计为向后兼容现有的基于命令行选项配置 JWT 身份验证器的方法。这意味着你可以继续使用现有的命令行选项来配置 JWT 身份验证器。但是,我们(Kubernetes SIG Auth)建议迁移到新的基于配置文件的方案,因为它提供了更高的灵活性和可扩展性。
注意
如果你在指定 --authentication-config
的同时还指定了任何 --oidc-*
命令行参数,则会发生配置错误。在这种情况下,API 服务器会报告错误并立即退出。
如果你想切换到使用结构化身份验证配置,则必须移除 --oidc-*
命令行参数,并改用配置文件。
以下是演示如何从命令行标志迁移到配置文件的示例:
命令行参数
--oidc-issuer-url=https://issuer.example.com
--oidc-client-id=example-client-id
--oidc-username-claim=username
--oidc-groups-claim=groups
--oidc-username-prefix=oidc:
--oidc-groups-prefix=oidc:
--oidc-required-claim="hd=example.com"
--oidc-required-claim="admin=true"
--oidc-ca-file=/path/to/ca.pem
配置文件中没有等同于 --oidc-signing-algs
的参数。对于 Kubernetes v1.30,身份验证器支持 oidc.go
中列出的所有非对称算法。
配置文件
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://issuer.example.com
audiences:
- example-client-id
certificateAuthority: <value is the content of file /path/to/ca.pem>
claimMappings:
username:
claim: username
prefix: "oidc:"
groups:
claim: groups
prefix: "oidc:"
claimValidationRules:
- claim: hd
requiredValue: "example.com"
- claim: admin
requiredValue: "true"
下一步是什么?
对于 Kubernetes v1.31,我们期望此功能在收集更多反馈的同时继续保持 Beta 阶段。在接下来的版本中,我们希望探索:
- 通过 CEL 表达式实现分布式声明(distributed claims)。
- 支持对
issuer.url
和issuer.discoveryURL
的调用使用 egress selector 配置。
你可以在 Kubernetes 文档中的结构化身份验证配置页面了解更多关于此功能的信息。你也可以关注 KEP-3331 来跟踪未来 Kubernetes 版本中的进展。
试用一下
在这篇文章中,我介绍了 Kubernetes v1.30 中结构化身份验证配置功能带来的优势。要使用此功能,你必须使用 --authentication-config
命令行参数指定身份验证配置文件的路径。从 Kubernetes v1.30 起,此功能已处于 Beta 阶段并默认启用。如果你想继续使用命令行参数而不是配置文件,它们将继续按原样工作。
我们非常希望听到你对此功能的反馈。请在 Kubernetes Slack 的 #sig-auth-authenticators-dev 频道联系我们(获取邀请,请访问 https://slack.k8s.io/)。
如何参与其中
如果你有兴趣参与此功能的开发、分享反馈或参与任何其他正在进行的 SIG Auth 项目,请在 Kubernetes Slack 的 #sig-auth 频道联系我们。
你也可以参加每两周一次的 SIG Auth 会议,会议通常在隔周的周三举行。