引言
在 Kubernetes 中,集群访问权限的管理方式与传统系统截然不同:它没有内置的用户数据库,而是通过一系列灵活的认证机制来识别访问者身份。无论是开发者、运维人员还是 CI/CD 流水线,都需要通过恰当的认证方式证明自己是谁,才能与集群交互。本文将深入解析 Kubernetes 中的用户类型、认证方式以及如何通过 kubeconfig 文件高效管理多集群访问,帮助构建安全可控的集群访问体系。
Kubernetes 用户认证体系概览
API Server内置的访问控制机制
-
认证(Authentication):
- 核验请求者身份的合法性,进行身份识别,验证客户端身份。
- 身份核验过程遵循“或”逻辑,且任何一个插件核验成功后都将不再进行后续的插件验证。
- 均不成功,则失败,或以“匿名者”身份访问,建议禁用“匿名者”。
-
授权(Authorization):
- 核验请求的操作是否获得许可,验证客户端是否有权限操作资源对象。
- 鉴权过程遵循“或”逻辑,且任何一个插件对操作的许可授权后都将不再进行后续的插件验证。
- 均未许可,则拒绝请求的操作
-
准入控制(Admission Control):
- 检查操作内容是否合规,仅同"写"请求相关,负责实现"检验"字段类型是否合法及和补全默认字段。
- 内容合规性检查过程遵循“与”逻辑,且无论成败,每次的操作请求都要经由所有插件的检验。
- 将数据写入etcd前,负责检查内容的有效性,因此仅对“写”操作有效。
- 分两类:validating(校验)和 mutating(补全或订正)。
身份认证策略
-
X.509客户端证书认证
- 在双向TLS通信中,客户端持有数字证书信任的CA,需要在kube-apiserver程序启动时,通过--client-ca-file选项传递。
- 认证通过后,客户端数字证书中的CN(Common Name)即被识别为用户名,而O(Organization)被识别为组名。
- kubeadm部署的K8s集群,默认使用"/etc/kubernetes/pki/ca.crt"(各组件间颁发数字证书的CA)进行客户端认证。
-
持有者令牌(token)
-
静态令牌文件(Static Token File)
- 令牌信息保存于文本文件中,由kube-apiserver在启动时通过--token-auth-file选项加载。
- 加载完成后的文件变动,仅能通过重启程序进行重载,因此,相关的令牌会长期有效。
- 客户端在HTTP请求中,通过“Authorization: Bearer TOKEN”标头附带令牌令牌以完成认证。
-
Bootstrap令牌
- 一般用于加入集群时使用,尤其是在集群的扩容场景时会用到。
-
Service Account令牌
- 该认证方式将由kube-apiserver程序内置直接启用,它借助于经过签名的Bearer Token来验证请求。
- 签名时使用的密钥可以由--service-account-key-file选项指定,也可以默认使用API Server的tls私钥
- 用于将Pod认证到API Server之上,以支持集群内的进程与API Server通信。
- K8s可使用ServiceAccount准入控制器自动为Pod关联ServiceAccount。
-
OIDC(OpenID Connect)令牌
- 有点类似于"微信","支付宝"认证的逻辑,自建的话需要配置认证中心。
- OAuth2认证机制,通常由底层的IaaS服务所提供。
-
Webhook令牌
- 基于web的形式进行认证,比如之前配置的"钉钉机器人","微信机器人"等;
- 是一种用于验证Bearer Token的回调机制,能够扩展支持外部的认证服务,例如LDAP等。
-
-
身份认证代理(Authenticating Proxy)
- 由kube-apiserver从请求报文的特定HTTP标头中识别用户身份,相应的标头名称可由特定的选项配置指定。
- kube-apiserver应该基于专用的CA来验证代理服务器身份。
-
匿名请求
- 生产环境中建议禁用匿名认证。
Kubernetes 用户
k8s用户概念
- “用户”即服务请求者的身份指代,一般使用身份标识符进行识别,比如用户名,用户组,服务账号,匿名用户等。
- 与普通系统不同,Kubernetes 没有存储用户信息的内置对象,而是通过外部认证机制来识别用户。
k8s用户类型
User Account
-
用户账户,指非Pod类的客户端访问API Server时使用的身份标识,一般是现实中的"人"。
-
API Server没有为这类账户提供保存其信息的资源类型,相关的信息通常保存于外部的文件(特指"kubeconfig"文件)或认证系统中。
-
身份核验操作可由API Server进行,也可能是由外部身份认证服务完成。
-
可以手动定义证书,其中O字段表示组,CN字段表示用户名。
-
典型认证方式
# 通过X509客户端证书认证 kubectl --client-certificate=./user.crt --client-key=./user.key get pods # 通过Bearer Token认证 kubectl --token="eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..." get pods
Service Account
-
服务账户,Kubernetes内置的资源类型,用于Pod内的进程访问API Server时使用的身份信息。
-
引用格式: "system:serviceaccount:NAMESPACE:SA_NAME"
-
创建和使用示例
# 创建 ServiceAccount apiVersion: v1 kind: ServiceAccount metadata: name: my-app-sa namespace: default # 在 Pod 中使用 ServiceAccount apiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: my-app-sa containers: - name: my-container image: nginx -
查看 ServiceAccount 的认证令牌
# 获取默认的 ServiceAccount token kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 -d # 创建一个新的 ServiceAccount 并获取其 token kubectl create serviceaccount my-sa kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: my-sa-token annotations: kubernetes.io/service-account.name: my-sa type: kubernetes.io/service-account-token EOF
Anonymous Account
- 匿名账户,不能被识别为Service Account,也不能被识别为User Account的用户。
- 这类账户K8S系统称之为"system:anonymous",即“匿名用户”。
深入kubeconfig 文件
kubeconfig概述
- kubeconfig是YAML格式的文件,用于存储身份认证信息,以便于客户端加载并认证到API Server。
- kubeconfig保存有认证到一至多个Kubernetes集群的相关配置信息,并允许管理员按需在各配置间灵活切换
kubeconfig的组成
-
clusters
- Kubernetes集群访问端点(API Server)列表。可以定义多个K8S集群列表
-
users
- 认证到API Server的身份凭据列表。可以定义多个用户列表,这个用户可以是token,或者x509证书凭据
-
contexts
- 将每一个user与可认证到的cluster建立关联的上下文列表
- 可以将多个用户和对应的集群进行关联,将来使用哪个用户,就会去关联的集群进行访问认证。也可以定义多个上下文的关系
-
current-context
- 当前默认使用的context
kubeconfig示例
apiVersion: v1
kind: Config
# 1. 集群配置 (clusters)
clusters:
- name: production-cluster
cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
#k8s集群API-server地址
server: https://10.0.0.51:6443
# 2. 用户凭证 (users)
users:
- name: alice
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ...
# 3. 上下文配置 (contexts)
contexts:
- name: prod-alice-context
context:
cluster: production-cluster
user: alice
namespace: production
# 4. 当前上下文
current-context: prod-alice-context
多集群环境配置示例
apiVersion: v1
kind: Config
clusters:
- name: development-cluster
cluster:
certificate-authority: /path/to/dev-ca.crt
server: https://dev.example.com:6443
- name: production-cluster
cluster:
insecure-skip-tls-verify: true # 仅测试环境使用
server: https://prod.example.com:6443
users:
- name: developer
user:
client-certificate: /path/to/dev-user.crt
client-key: /path/to/dev-user.key
- name: admin
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9...
contexts:
- name: dev-context
context:
cluster: development-cluster
user: developer
namespace: dev-namespace
- name: prod-context
context:
cluster: production-cluster
user: admin
namespace: production
current-context: dev-context
常用kubeconfig命令
# 查看当前配置
kubectl config view
# 查看特定上下文配置
#打印kubeconfig信息,默认会使用“REDACTED”或者“DATA+OMITTED”关键字隐藏证书信息
kubectl config view --minify --context=prod-context
# 切换当前上下文
kubectl config use-context prod-context
# 添加新集群配置
kubectl config set-cluster new-cluster \
--server=https://new.example.com:6443 \
--certificate-authority=/path/to/ca.crt
# 添加用户凭证
kubectl config set-credentials new-user \
--client-certificate=/path/to/client.crt \
--client-key=/path/to/client.key
# 添加上下文
kubectl config set-context new-context \
--cluster=new-cluster \
--user=new-user \
--namespace=default
# 重命名上下文
kubectl config rename-context old-name new-name
# 删除配置项
kubectl config delete-context unwanted-context
kubectl config delete-cluster old-cluster
kubectl config delete-credentials old-user
kubectl加载kubeconfig文件的优先级
- 使用--kubeconfig的优先级最大,直接无视之后的两个配置文件
- 使用KUBECONFIG变量的优先级次之
- 使用默认的"~/.kube/config"最后加载
创建一个用户并授权
1.为 Alice 生成证书签发请求私钥和证书签发请求
#csr:证书签发请求
#-out 指定证书签发请求csr 基于alice.key这个私钥签发
#指定的用户名CN是alice 组织O 为developers
[root@worker51 ~]# openssl genrsa -out alice.key 2048
[root@worker51 ~]# openssl req -new -key alice.key -out alice.csr -subj "/CN=alice/O=developers"
[root@worker51 ~]# ll alice*
-rw-r--r-- 1 root root 911 Jan 24 10:43 alice.csr
-rw------- 1 root root 1704 Jan 24 10:43 alice.key
2.使用集群的 CA 签署证书
openssl x509 -req -in alice.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out alice.crt -days 365
3.为 Alice 配置 kubeconfig
# --embed-certs=true 是否拷贝证书 是
kubectl config set-credentials alice \
--client-certificate=alice.crt \
--client-key=alice.key \
--embed-certs=true
kubectl config set-context alice-context \
--cluster=your-cluster-name \
--user=alice
kubectl config use-context alice-context
4.为 Alice 配置权限(RBAC)
现在用户 alice 可以访问集群了,但默认没有任何权限。需创建一个 Role 和 RoleBinding 来授权。
# 创建一个角色,例如允许在 default 命名空间查看 pods
apiVersion: rbac.authorization.k8s.io/v1
kind: Rolex
metadata:
namespace: default
name: pod-viewer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
# 将角色绑定给用户 alice
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: view-pods-to-alice
subjects:
- kind: User
name: alice # 这里的名字必须与证书中的 CN 完全一致
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-viewer
apiGroup: rbac.authorization.k8s.io