概述

当你在堡垒机或controller节点上(区别于容器内部发起的请求)执行kubectl get po 命令是,默认使用的是 user 用户的权限,这个权限是什么?来自哪里,有哪些权限?

Kubernetes 用字符串来表示用户名。 用户名可以是普通的用户名,像 “alice”;或者是邮件风格的名称,如 “bob@example.com”, 或者是以字符串形式表达的数字 ID。你作为 Kubernetes 管理员负责配置身份认证模块, 以便后者能够生成你所期望的格式的用户名。

注意:
前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求。

在本篇之前,建议先读 【k8s】rbac权限框架和鉴权、鉴权概念

1、用户身份确定流程

用户没有get user 命令进行查看,他是登录用户的id,这个id由指定或其他认证提出来的,然后用于后面的rbac授权检查!

默认配置文件位置:~/.kube/config

用户身份由以下因素决定:

  • 当前 context 中指定的用户

  • 该用户配置的认证方式(证书、token、OIDC等)

1.1 查看当前使用的用户

1)查看当前 context 的详细信息
kubectl config current-context

2)~/.kube/config 示例
全量的配置信息:

[root@caas-dc4-bastion vtu]# cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSaJQ0FURS0tLS0tCk1JSUR2RENDQXFTZ0F3SUJBZ0lKQU44aTBqZWRPaGZRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdKTVFzd0NRWUQKVlFRR0V3SkRUakVRTUE0R0ExVUVDQXdIYzJsamFIVmhiakVRTUE0R0ExVUVCd3dIWTJobGJtZGtkVEVNTUFvRwpBMVVFQ2d3RGVuUmxNUTR3REFZRFZRUUxEQVY2Wlc1aGNERTRNRFlHQTFVRUF3d3ZXbFJGSUU5d1pXNVFZV3hsCmRIUmxJRkp2YjNRZ1EyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVJREl3TWpBd0lCY05NakF4TVRFM01EZzAKT1RNd1doZ1BNakExTURFeE1UQXdPRFE1TXpCYU1JR0pNUXN3Q1FZRFZRUUdFd0pEVGpFUU1BNEdBMVVFQ0F3SApjMmxqYUhWaGJqRVFNQTRHQTFVRUJ3d0hZMmhsYm1ka2RURU1NQW9HQTFVRUNnd0RlblJsTVE0d0RBWURWUVFMCkRBVjZaVzVoY0RFNE1EWUdBMVVFQXd3dldsUkZJRTl3Wlc1UVlXeGxkSFJsSUZKdmIzUWdRMlZ5ZEdsbWFXTmgKZEdVZ1FYVjBhRzl5YVhSNUlESXdNakF3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQgpBUURiY3NvU3JucWxYT3hGdGdubzB4MlR6WkI4dU9lbjUvc3JOMURqcEovQ1YwYmVDYUtscXcvQU5kWDJOUDBXCjlTVmZ5eitaR21FN0s1bnU4UE12WkNPVkw4VUVCTk5hc25aVUltWUZXWE5XN2hKTm5waXZHbEN0SUJxVWFTSmgKMzI1UFppM2FxNDFROEt4bEtVbnlva0ppelQzeHNuWmRPd3JRa0Z2TDNpUGVkTjI4MWFHRVN1dUY1WjBiOEllTgo3ZmF3cWlEb0hFM2diTXg1blo5UjNTOHF5b0d6ejB6U2tDbDJPbEV5b1FZZUQ0dXVMaUtJVDJRcHI5anhMZFhxCkNBbG1OdW52R3pzM1NhTEwrbHA2aXlOOFY3bFRxYUc2WlJKazhYTHk1NENBYkdvR1RDOHNuQUpqY2RoeXV3VVoKcGRPNzV6ZW5hclVCM0tDSi9XSGpjZXU5QWdNQkFBR2pJekFoTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3RGdZRApWUjBQQVFIL0JBUURBZ0VHTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCSjJKM3dzd1U1TlQxRmNNWTVUVnoxCmJrRXhIT2ErSTNxT09HTXhiZFh4cXR6dStiY3JseGV6QVp4YTBZTlJNYUlUYjlvcUo1QXgwRC9JSTdDdXZwYTkKOHNoM0tGeUVxNEVpMWhETUVzbDBkWnRVYlpDV0Y1dHQ4djlNUFhZU3RwVnFlL1RXY3IyeGpIb1lnbW1sYUNKSgpiQzNUK3pLS2FzMjVKbEZYMEw4V0drZGlleHJPb1VYUWRRc2pjcmZrbHU5ZFNFbERsQTlsU05XOHZreHNXREpPCnlxbVZqUXl4N1RlNjdRN01oRTQ0SzBYWTVZYUVzWFd5ZkFZWkhFVlF1Rkd2K3RoMnpBclhJVkw4WSt3dVZsL1UKK1Z6dlhvVEFrQjFOOWw2cXBVRUVwU0pYNkJBUXQxeFpiQzV1ZVVKLyt4SlRzMlRGcW1LNVRYVFg5aXlOS2hzZwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://[fd00:79:200:3305::16:12]:2602
  name: cluster.local
contexts:
- context:
    cluster: cluster.local
    user: kubectl
  name: kubectl-to-cluster.local
current-context: kubectl-to-cluster.local
kind: Config
preferences: {}
users:
- name: kubectl
  user:
    client-certificate-data: Q2VydGlmaWNhdGU6CiAgICBEYXRhOgogIsgICAgIFZlcnNpb246IDMgKDB4MikKICAgICAgICBTZXJpYWwgTnVtYmVyOgogICAgICAgICAgICBiNzo3Njo4Mjo0NDo4ZjpmZ
    。。。。。。

3)查看完整配置,找到当前使用的用户
kubectl config view --minify

mini版,等价于把~/.kube/config 示例进行简化

示例:

[root@caas-dc4-bastion ~]# kubectl config view --minify
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://[fd00:79:200:3305::16:12]:2602
  name: cluster.local
contexts:
- context:
    cluster: cluster.local
    user: kubectl
  name: kubectl-to-cluster.local
current-context: kubectl-to-cluster.local
kind: Config
preferences: {}
users:
- name: kubectl
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

1.2 验证用户

查看当前正在用的用户:

# kubectl auth whoami
ATTRIBUTE   VALUE
Username    kubectl
Groups      [system:masters:20250715164013169 system:authenticated]

【用户身份分析】

  1. Username: kubectl
    这表明 kubeconfig 中配置的用户名是 kubectl。这通常是一个服务账号(ServiceAccount)或自定义的用户名。

  2. Groups: system:masters:xxx
    system:masters 是 Kubernetes 中的超级用户组,相当于集群的 root 用户

system:masters:20250715164013169 看起来是一个带时间戳的特定组名,可能是通过 OIDC 或 Webhook 认证后赋予的组

system:authenticated 表示用户已通过认证(这是一个内置组,所有认证用户都属于该组)

【权限分析】
由于用户属于 system:masters 组,这意味着:

  • 该用户拥有集群管理员权限

  • 可以执行任何操作,不受 RBAC 限制

这就是为什么你能成功执行 kubectl get po

2. user的认证方式

常见的认证方式:

认证方式 每次鉴权 额外开销 典型场景
客户端证书 ✅ 每次都验证证书 较低(TLS握手) 长期运维人员
Token ✅ 每次都验证token 极低 CI/CD、服务账号
OIDC ✅ 每次都验证token 中等(需验证IDP) 企业SSO
Webhook ✅ 每次都调用webhook 较高(外部调用) 自定义认证

2.1 客户端证书认证:

users:
- name: kubectl
  user:
    client-certificate: /path/to/cert.pem
    client-key: /path/to/key.pem

client-certificate-data 和 client-key-data 与 client-certificate/client-key 是相同内容,前者是字符串,后者是外部证书文件。

2.2 Token 认证:

users:
- name: kubectl
  user:
    token: <token>

2.3 OIDC 认证(可能性较大,因为组名包含时间戳):

users:
- name: kubectl
  user:
    exec:
      command: kubectl
      args: ["oidc-login", "get-token"]

3. 查看集群中的用户

环境中有哪些用户,用户组,怎么查?

在 Kubernetes 中,查看用户和用户组的方式比较特殊,因为 Kubernetes 没有内置的用户存储 ,即没有get user这种语法,用户管理通常由外部系统(如证书、OIDC、服务账号)负责。以下是几种查看方法:

3.1 查看 RBAC 配置中的用户/组引用

RBAC 资源(Role、ClusterRole、RoleBinding、ClusterRoleBinding)中会引用用户和组:

# 查看所有 ClusterRoleBinding(集群级别绑定)
kubectl get clusterrolebindings

# 查看特定 ClusterRoleBinding 的详情
kubectl describe clusterrolebinding <binding-name>

# 查看所有 RoleBinding(命名空间级别)
kubectl get rolebindings --all-namespaces

# 查看哪些用户/组被绑定了集群管理员权限
kubectl describe clusterrolebinding cluster-admin

# 查看所有绑定中的 subjects(用户、组、ServiceAccount)
kubectl get clusterrolebindings,rolebindings --all-namespaces -o json | jq '.items[].subjects[]? | select(.kind=="User" or .kind=="Group")'

示例:

# 查看所有集群角色绑定
kubectl get clusterrolebindings

# 输出示例:
NAME                           ROLE                        AGE
cluster-admin                  ClusterRole/cluster-admin   30d
system:basic-user              ClusterRole/system:basic-user 30d
kubectl-to-cluster.local-binding  ClusterRole/cluster-admin 15d

# 查看具体绑定的详情
kubectl describe clusterrolebinding kubectl-to-cluster.local-binding

# 输出:
Name:         kubectl-to-cluster.local-binding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name     Namespace
  ----   ----     ---------
  User   kubectl           # 这里显示用户 kubectl 被绑定

在这里插入图片描述

3.2 通过 RBAC 查询用户权限

# 检查特定用户是否有权限(需要集群支持)
kubectl auth can-i list pods --as=<username>

# 检查特定组是否有权限
kubectl auth can-i list pods --as-group=<groupname>

# 查看当前用户的所有权限(需要安装 rbac-view 插件)
kubectl rbac-view

示例:

# 检查特定用户是否有权限
kubectl auth can-i list pods --as=kubectl

# 输出:
yes

# 更详细的检查
kubectl auth can-i create deployments --as=kubectl -n default

# 输出:
no

# 检查所有权限
kubectl auth can-i --list --as=kubectl

# 输出示例:
Resources                                       Non-Resource URLs   Resource Names   Verbs
*.*                                             []                  []               [*]
                                                [*]                 []               [*]

在这里插入图片描述

3.3 为什么不能等同?

kubectl get clusterrolebindingskubectl auth can-i --as=<user> 相同吗? 本质不同

3.3.1 场景一:配置存在但权限无效

# 1. 查看绑定配置(存在)
kubectl get clusterrolebindings dev-binding
# 输出:dev-binding    ClusterRole/dev-role    10d

# 2. 但实际权限可能无效(比如角色被修改)
kubectl auth can-i list pods --as=developer
# 输出:no

# 原因:dev-role 可能被修改,不再包含 list pods 权限

配置上定义了权限绑定,但是实际有偏差,或后来被修改了,实际上执行命令时报错了

3.3.2 场景二:隐式权限

# 1. 查看绑定配置(找不到)
kubectl get clusterrolebindings | grep kubectl
# 可能没有直接显示 kubectl 的绑定

# 2. 但实际有权限(可能通过组继承)
kubectl auth can-i list pods --as=kubectl
# 输出:yes

# 原因:kubectl 用户属于 system:masters 组,该组有权限

虽然没有配置这个具体权限,但是由于定义在了高级用户组,那么也有高级权限!

3.3.2.1 隐式权限 中,怎么知道某个用户归属 的用户组?

在 Kubernetes 中,用户组信息不像用户名那样直接可见,需要通过以下几种方式来查看。

方法一:使用 kubectl auth whoami(推荐)

# 查看当前认证用户的详细信息
kubectl auth whoami

# 输出示例:
ATTRIBUTE   VALUE
Username    kubectl
Groups      [system:masters:20250715164013169 system:authenticated]

方法二:查看证书中的组信息(如果是证书认证)

# 从 kubeconfig 提取证书并查看
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | \
  base64 -d | openssl x509 -text -noout | grep -E "Subject:|O="

# 输出示例:
# Subject: CN=kubectl, O=system:masters:20250715164013169, O=system:authenticated
# 多个 O= 表示属于多个组

方法三:查看 token 中的组信息(如果是 OIDC/Token 认证)

# 如果使用 JWT token,可以解码查看
kubectl config view --raw -o jsonpath='{.users[0].user.token}' | \
  cut -d. -f2 | base64 -d 2>/dev/null | jq .

# 输出示例:
{
  "sub": "kubectl",
  "groups": ["system:masters", "system:authenticated"],
  "exp": 1234567890
}

4. 内置的用户组

Kubernetes 没有“内置用户”的传统数据库或用户列表,但确实有内置的用户组(系统组)和一些特殊的 ServiceAccount

Kubernetes 的组确实可以分为用户组服务账户组两大类,它们在来源、用途和管理方式上有本质区别。

组的两大分类

用户组(User Groups):由外部认证系统管理的组,代表真实用户或系统管理员。

服务账户组(ServiceAccount Groups):由Kubernetes 内部自动管理的组,代表服务账户(ServiceAccount)。

详细对比

维度 用户组 服务账户组
来源 外部认证(证书、OIDC、LDAP) Kubernetes 内置,自动创建
管理方式 外部系统管理 Kubernetes 自动管理
命名规则 自定义(如 system:masters 固定前缀 system:serviceaccounts
认证方式 客户端证书、token、OIDC ServiceAccount token
典型用途 管理员、开发人员、运维人员 CI/CD、应用组件、Pod
生命周期 由外部系统控制 与 ServiceAccount 绑定

4.1 用户组

4.1.1 system:masters

特征

  • 类型:用户组
  • 包含:集群管理员用户
  • 自动加入:否(需要在证书或 OIDC 中配置)
  • 典型用途:完整的管理员权限

如何加入:

  1. 证书认证:证书的 O=system:masters
  2. OIDC:groups claim 包含 system:masters
  3. 不建议直接绑定普通用户到此组

【原理】
system:masters 是一个内置的用户组(Group),它通过一个内置的 ClusterRoleBinding 被永久绑定到了system:masters 这个 ClusterRole 上。

这个绑定关系是 API Server 启动时自动创建的,你无法删除或修改它(即使 kubectl delete 也不行,API Server 会重新创建)。

验证这个绑定

# 查看 system:masters 组的绑定关系
kubectl get clusterrolebinding system:masters -o yaml

输出类似:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:masters
  # 注意:这个 binding 是系统内置的,annotations 标记了它由 Kubernetes 自动管理
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:masters
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters   # 关键:将组绑定到 system:masters 角色

其中ClusterRole类型的 名称叫 system:masters(名称相同,有助于识别),也是内置的,这样实现了自动授权!

如何让一个用户属于 system:masters?
1)用户(或组件)的组信息由鉴权层提供,最常见的方式是通过客户端证书的 O(Organization)字段:
生成一个属于 system:masters 的证书

# 创建证书签名请求,O 设置为 system:masters
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "O": "system:masters",   # 关键:组织字段,对应 Group
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF

# 使用 Kubernetes CA 签发证书
cfssl gencert -ca=ca.crt -ca-key=ca.key admin-csr.json | cfssljson -bare admin

生成的 admin.pem 证书中,O=system:masters。当 API Server 用 CA 验证这个证书时,会解析出:

  • CN → 用户名:admin

  • O → 用户组:system:masters

然后这个用户就自动拥有了 cluster-admin 的全部权限。
2)直接使用生成的证书文件,不修改现有的 ~/.kube/config

kubectl get pods \
  --server=https://your-api-server:6443 \
  --certificate-authority=ca.crt \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem

4.1.2 system:authenticated

特征:

  • 类型:用户组
  • 包含:所有认证成功的用户(包括用户和服务账户)
  • 自动加入:是
  • 典型用途:基础权限,如只读访问

示例:给予所有认证用户只读权限

# 示例:给予所有认证用户只读权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: authenticated-readers
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

4.1.3 system:unauthenticated

特征

  • 类型:用户组
  • 包含:所有未认证的请求
  • 自动加入:是(匿名请求)
  • 典型用途:公开的只读端点

注意:生产环境建议禁用匿名访问:

#API Server 配置:
--anonymous-auth=false

4.1.4 system:nodes

特征

  • 类型:用户组
  • 包含:所有集群节点
  • 自动加入:是(节点证书认证时)
  • 典型用途:节点与 API Server 通信
# 查看节点用户
kubectl auth whoami --as=system:node:node-1

输出会显示属于 system:nodes 组

4.2 服务账户组

system:serviceaccounts 所有 ServiceAccount 自动,任何 SA 都属于此组
system:serviceaccounts: 特定命名空间的 SA 自动,SA 创建时自动加入

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐