认证

开启 TLS 时,所有的请求都需要首先认证。Kubernetes 支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。如果认证成功,则用户的 username 会传入授权模块做进一步授权验证;而对于认证失败的请求则返回 HTTP 401。

Kubernetes 不直接管理用户

虽然 Kubernetes 认证和授权用到了 user 和 group,但 Kubernetes 并不直接管理用户,不能创建 user 对象,也不存储 user。

目前,Kubernetes 支持以下认证插件:

  • X509 证书

  • 静态 Token 文件

  • 引导 Token

  • 静态密码文件

  • Service Account

  • OpenID

  • Webhook

  • 认证代理

  • OpenStack Keystone 密码

X509 证书

使用 X509 客户端证书只需要 API Server 启动时配置 --client-ca-file=SOMEFILE。在证书认证时,其 Common Name(CN)域用作用户名,而 Organization(O)域则用作 group 名。

创建一个客户端证书的方法为:

接着,就可以使用 username.key 和 username.crt 来访问集群:

静态 Token 文件

使用静态 Token 文件认证只需要 API Server 启动时配置 --token-auth-file=SOMEFILE。该文件为 csv 格式,每行至少包括三列 token,username,user id,后面是可选的 group 名,比如

客户端在使用 token 认证时,需要在请求头中加入 Bearer Authorization 头,比如

引导 Token

引导 Token 是动态生成的,存储在 kube-system namespace 的 Secret 中,用来部署新的 Kubernetes 集群。

使用引导 Token 需要 API Server 启动时配置 --experimental-bootstrap-token-auth,并且 Controller Manager 开启 TokenCleaner --controllers=*,tokencleaner,bootstrapsigner

在使用 kubeadm 部署 Kubernetes 时,kubeadm 会自动创建默认 token,可通过 kubeadm token list 命令查询。

静态密码文件

需要 API Server 启动时配置 --basic-auth-file=SOMEFILE,文件格式为 csv,每行至少三列 password, user, uid,后面是可选的 group 名,如

客户端在使用密码认证时,需要在请求头重加入 Basic Authorization 头,如

Service Account

ServiceAccount 是 Kubernetes 自动生成的,并会自动挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount 目录中。

在认证时,ServiceAccount 的用户名格式为 system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT),并从属于两个 group:system:serviceaccountssystem:serviceaccounts:(NAMESPACE)

OpenID

OpenID 提供了 OAuth2 的认证机制,是很多云服务商(如 GCE、Azure 等)的首选认证方法。

使用 OpenID 认证,API Server 需要配置

  • --oidc-issuer-url,如 https://accounts.google.com

  • --oidc-client-id,如 kubernetes

  • --oidc-username-claim,如 sub

  • --oidc-groups-claim,如 groups

  • --oidc-ca-file,如 /etc/kubernetes/ssl/kc-ca.pem

Webhook

API Server 需要配置

配置文件格式为

Kubernetes 发给 webhook server 的请求格式为

示例:kubernetes-github-authn 实现了一个基于 WebHook 的 github 认证。

认证代理

API Server 需要配置

OpenStack Keystone 密码

需要 API Server 在启动时指定 --experimental-keystone-url=<AuthURL>,而 https 时还需要设置 --experimental-keystone-ca-file=SOMEFILE

不支持 Keystone v3

目前只支持 keystone v2.0,不支持 v3(无法传入 domain)。

匿名请求

如果使用 AlwaysAllow 以外的认证模式,则匿名请求默认开启,但可用 --anonymous-auth=false 禁止匿名请求。

匿名请求的用户名格式为 system:anonymous,而 group 则为 system:unauthenticated

Kubelet 凭证提供程序的服务账户令牌(v1.33 Alpha)

从 Kubernetes v1.33 开始,引入了 Service Account Token Integration for Kubelet Credential Providers 这一 Alpha 特性,允许 kubelet 凭证提供程序使用 Pod 的服务账户令牌来获取镜像拉取凭证,从而实现工作负载级别的镜像访问控制。

工作原理

当启用此特性后:

  1. 令牌生成:Kubelet 为 Pod 生成短期、自动轮换的服务账户令牌

  2. 令牌传递:这些令牌通过 CredentialProviderRequest 传递给凭证提供程序

  3. 凭证交换:凭证提供程序使用服务账户令牌向镜像仓库(如 AWS ECR、GCP Artifact Registry、Azure ACR)交换临时的镜像拉取凭证

  4. 镜像拉取:Kubelet 使用获得的临时凭证代表 Pod 拉取镜像

配置方法

  1. 启用特性门控

  2. 配置凭证提供程序: 在凭证提供程序配置中设置 tokenAttributes 字段以选择接收服务账户令牌:

  3. Pod 配置: Pod 使用服务账户,kubelet 会自动为其生成令牌用于镜像拉取:

优势

  • 消除长期密钥:不再需要在集群中存储长期有效的镜像拉取密钥

  • 工作负载隔离:每个 Pod 使用自己的服务账户令牌,实现细粒度的访问控制

  • 自动轮换:令牌自动过期和轮换,提高安全性

  • 与云原生集成:可以与云提供商的 IAM 系统无缝集成

这一特性预计在 Kubernetes v1.34 中升级为 Beta 版本。更多信息请参考 KEP-4412

Credential Plugin

从 v1.11 开始支持 Credential Plugin(Beta),通过调用外部插件来获取用户的访问凭证。这是一种客户端认证插件,用来支持不在 Kubernetes 中内置的认证协议,如 LDAP、OAuth2、SAML 等。它通常与 Webhook 配合使用。

Credential Plugin 可以在 kubectl 的配置文件中设置,比如

具体的插件开发及使用方法请参考 kubernetes/client-go

开源工具

如下的开源工具可以帮你简化认证和授权的配置:

参考资料

最后更新于