认证
开启 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 名。
创建一个客户端证书的方法为:
# Create private key
openssl genrsa -out username.key 2048
# Create CSR (certificate signing request)
openssl req -new -key username.key -out username.csr -subj "/CN=username/O=group"
# Create certificate from CSR using the cluster authority
openssl x509 -req -in username.csr -CA $CA_LOCATION/ca.crt -CAkey $CA_LOCATION/ca.key -CAcreateserial -out username.crt -days 500
接着,就可以使用 username.key 和 username.crt 来访问集群:
# Config cluster
kubectl config set-cluster my-cluster --certificate-authority=ca.pem --embed-certs=true --server=https://<APISERVER_IP>:6443
# Config credentials
kubectl config set-credentials username --client-certificate=username.crt --client-key=username.key --embed-certs=true
# Config context
kubectl config set-context username --cluster=my-cluster --user=username
# Config RBAC if it's enabled
# Finally, switch to new context
kubectl config use-context username
静态 Token 文件
使用静态 Token 文件认证只需要 API Server 启动时配置 --token-auth-file=SOMEFILE
。该文件为 csv 格式,每行至少包括三列 token,username,user id
,后面是可选的 group 名,比如
token,user,uid,"group1,group2,group3"
客户端在使用 token 认证时,需要在请求头中加入 Bearer Authorization 头,比如
Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
引导 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 名,如
password,user,uid,"group1,group2,group3"
客户端在使用密码认证时,需要在请求头重加入 Basic Authorization 头,如
Authorization: Basic BASE64ENCODED(USER:PASSWORD)
Service Account
ServiceAccount 是 Kubernetes 自动生成的,并会自动挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount
目录中。
在认证时,ServiceAccount 的用户名格式为 system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)
,并从属于两个 group:system:serviceaccounts
和 system: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 需要配置
# 配置如何访问 webhook server
--authentication-token-webhook-config-file
# 默认 2 分钟
--authentication-token-webhook-cache-ttl
配置文件格式为
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authn-service
cluster:
# CA for verifying the remote service.
certificate-authority: /path/to/ca.pem
# URL of remote service to query. Must use 'https'.
server: https://authn.example.com/authenticate
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
user:
# cert for the webhook plugin to use
client-certificate: /path/to/cert.pem
# key matching the cert
client-key: /path/to/key.pem
# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authn-service
user: name-of-api-sever
name: webhook
Kubernetes 发给 webhook server 的请求格式为
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"spec": {
"token": "(BEARERTOKEN)"
}
}
示例:kubernetes-github-authn 实现了一个基于 WebHook 的 github 认证。
认证代理
API Server 需要配置
--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-
# 为了防止头部欺骗,证书是必选项
--requestheader-client-ca-file
# 设置允许的 CN 列表。可选。
--requestheader-allowed-names
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 的服务账户令牌来获取镜像拉取凭证,从而实现工作负载级别的镜像访问控制。
工作原理
当启用此特性后:
令牌生成:Kubelet 为 Pod 生成短期、自动轮换的服务账户令牌
令牌传递:这些令牌通过
CredentialProviderRequest
传递给凭证提供程序凭证交换:凭证提供程序使用服务账户令牌向镜像仓库(如 AWS ECR、GCP Artifact Registry、Azure ACR)交换临时的镜像拉取凭证
镜像拉取:Kubelet 使用获得的临时凭证代表 Pod 拉取镜像
配置方法
启用特性门控:
kubelet --feature-gates=ServiceAccountTokenForKubeletCredentialProviders=true
配置凭证提供程序: 在凭证提供程序配置中设置
tokenAttributes
字段以选择接收服务账户令牌:apiVersion: kubelet.config.k8s.io/v1 kind: CredentialProviderConfig providers: - name: my-provider tokenAttributes: audience: "https://my-registry.example.com" expirationSeconds: 3600
Pod 配置: Pod 使用服务账户,kubelet 会自动为其生成令牌用于镜像拉取:
apiVersion: v1 kind: Pod metadata: name: my-app spec: serviceAccountName: my-app-sa containers: - name: app image: my-registry.example.com/app:v1
优势
消除长期密钥:不再需要在集群中存储长期有效的镜像拉取密钥
工作负载隔离:每个 Pod 使用自己的服务账户令牌,实现细粒度的访问控制
自动轮换:令牌自动过期和轮换,提高安全性
与云原生集成:可以与云提供商的 IAM 系统无缝集成
这一特性预计在 Kubernetes v1.34 中升级为 Beta 版本。更多信息请参考 KEP-4412。
Credential Plugin
从 v1.11 开始支持 Credential Plugin(Beta),通过调用外部插件来获取用户的访问凭证。这是一种客户端认证插件,用来支持不在 Kubernetes 中内置的认证协议,如 LDAP、OAuth2、SAML 等。它通常与 Webhook 配合使用。
Credential Plugin 可以在 kubectl 的配置文件中设置,比如
apiVersion: v1
kind: Config
users:
- name: my-user
user:
exec:
# Command to execute. Required.
command: "example-client-go-exec-plugin"
# API version to use when decoding the ExecCredentials resource. Required.
#
# The API version returned by the plugin MUST match the version listed here.
#
# To integrate with tools that support multiple versions (such as client.authentication.k8s.io/v1alpha1),
# set an environment variable or pass an argument to the tool that indicates which version the exec plugin expects.
apiVersion: "client.authentication.k8s.io/v1beta1"
# Environment variables to set when executing the plugin. Optional.
env:
- name: "FOO"
value: "bar"
# Arguments to pass when executing the plugin. Optional.
args:
- "arg1"
- "arg2"
clusters:
- name: my-cluster
cluster:
server: "https://172.17.4.100:6443"
certificate-authority: "/etc/kubernetes/ca.pem"
contexts:
- name: my-cluster
context:
cluster: my-cluster
user: my-user
current-context: my-cluster
具体的插件开发及使用方法请参考 kubernetes/client-go。
开源工具
如下的开源工具可以帮你简化认证和授权的配置:
参考资料
Protect Kubernetes External Endpoints with OAuth2 Proxy by Alen Komljen
Single Sign-On for Internal Apps in Kubernetes using Google Oauth / SSO by William Broach
Single Sign-On for Kubernetes: An Introduction by Joel Speed
Let’s Encrypt, OAuth 2, and Kubernetes Ingress by Ian Chiles
Comparing Kubernetes Authentication Methods by Etienne Dilocker
Effective RBAC by Jordan Liggitt
Configure RBAC In Your Kubernetes Cluster via Bitnami
Using RBAC, Generally Available in Kubernetes v1.8 by Eric Chiang
最后更新于