这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。

Kubernetes 1.30:结构化身份认证配置进阶至 Beta

在 Kubernetes 1.30 中,我们(SIG Auth)将结构化身份认证配置(Structured Authentication Configuration)进阶至 Beta。

今天的文章是关于身份认证:找出谁在执行任务,核查他们是否是自己所说的那个人。本文还述及 Kubernetes v1.30 中关于 鉴权(决定某些人能访问什么,不能访问什么)的新内容。

动机

Kubernetes 长期以来都需要一个更灵活、更好扩展的身份认证系统。当前的系统虽然强大,但有一些限制,使其难以用在某些场景下。例如,不可能同时使用多个相同类型的认证组件(例如,多个 JWT 认证组件),也不可能在不重启 API 服务器的情况下更改身份认证配置。结构化身份认证配置特性是解决这些限制并提供一种更灵活、更好扩展的方式来配置 Kubernetes 中身份认证的第一步。

什么是结构化身份认证配置?

Kubernetes v1.30 针对基于文件来配置身份认证提供实验性支持,这是在 Kubernetes v1.30 中新增的 Alpha 特性。在此 Beta 阶段,Kubernetes 仅支持配置 JWT 认证组件,这是现有 OIDC 认证组件的下一次迭代。JWT 认证组件使用符合 JWT 标准的令牌对 Kubernetes 用户进行身份认证。此认证组件将尝试解析原始 ID 令牌,验证其是否由配置的签发方签名。

Kubernetes 项目新增了基于文件的配置,以便提供比使用命令行选项(命令行依然有效,仍受支持)更灵活的方式。对配置文件的支持还使得在即将发布的版本中更容易提供更多改进措施。

结构化身份认证配置的好处

以下是使用配置文件来配置集群身份认证的好处:

  1. 多个 JWT 认证组件:你可以同时配置多个 JWT 认证组件。这允许你使用多个身份提供程序(例如 Okta、Keycloak、GitLab)而无需使用像Dex 这样的中间程序来处理多个身份提供程序之间的多路复用。
  2. 动态配置:你可以在不重启 API 服务器的情况下更改配置。这允许你添加、移除或修改认证组件而不会中断 API 服务器。
  1. 任何符合 JWT 标准的令牌:你可以使用任何符合 JWT 标准的令牌进行身份认证。这允许你使用任何支持 JWT 的身份提供程序的令牌。最小有效的 JWT 载荷必须包含 Kubernetes文档中结构化身份认证配置页面中记录的申领。
  2. CEL(通用表达式语言)支持:你可以使用 CEL 来确定令牌的申领是否与 Kubernetes 中用户的属性(例如用户名、组)匹配。这允许你使用复杂逻辑来确定令牌是否有效。
  1. 多个受众群体:你可以为单个认证组件配置多个受众群体。这允许你为多个受众群体使用相同的认证组件,例如为 kubectl 和仪表板使用不同的 OAuth 客户端。
  2. 使用不支持 OpenID 连接发现的身份提供程序:你可以使用不支持OpenID 连接发现 的身份提供程序。唯一的要求是将发现文档托管到与签发方不同的位置(例如在集群中本地),并在配置文件中指定 issuer.discoveryURL

如何使用结构化身份认证配置

要使用结构化身份认证配置,你可以使用 --authentication-config 命令行参数在API 服务器中指定身份认证配置的路径。此配置文件是一个 YAML 文件,指定认证组件及其配置。以下是一个配置两个 JWT 认证组件的示例配置文件:

apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
# 如果某人具有这些 issuer 之一签发的有效令牌,则此人可以在集群上进行身份认证
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"
# 第二个认证组件将发现文档公布于与签发方不同的位置
- 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)建议迁移到新的基于配置文件的方法,因为这种方法更灵活,更好扩展。

以下是如何从命令行标志迁移到配置文件的示例:

命令行参数

--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: <取值是 /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 表达式使分布式申领生效。
  • issuer.urlissuer.discoveryURL 的调用提供 Egress 选择算符配置支持。

你可以在 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 双周会议