Kubernetes RBAC 完全指南(适用于 Kubernetes v1.35)

文档说明

  • 适用版本:Kubernetes v1.35.4(rbac.authorization.k8s.io/v1
  • 前置知识:了解 Kubernetes 的基本概念(Pod、Namespace)
  • 目标:从零掌握 Kubernetes RBAC 的原理、配置与使用,构建安全、可控的权限体系

第一章:为什么需要 RBAC?

1.1 权限管理的挑战

在生产环境的 Kubernetes 集群中,不同角色的人员需要不同的操作权限:

角色需要的权限风险
开发者查看 Pod 日志、部署应用误删生产数据、修改关键配置
运维工程师管理节点、扩缩容、查看所有资源误操作导致集群瘫痪
安全审计员只读查看所有资源(含审计日志)
CI/CD 系统部署应用、滚动更新权限过大可能被利用

如果所有人都使用 cluster-admin 权限(相当于 root),后果不堪设想:

  • 开发者可能误删生产数据库的 Pod
  • CI/CD 系统被攻击后,攻击者获得集群完全控制权
  • 无法追溯谁在什么时间做了什么操作

一句话总结:RBAC 让你可以精确控制“谁能对什么资源做什么操作” ,实现最小权限原则——只给每个人/系统完成任务所需的最小权限。

1.2 RBAC 是什么?

RBAC(Role-Based Access Control,基于角色的访问控制) 是 Kubernetes 中管理用户和服务账户权限的核心机制

RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组来驱动鉴权决定,允许你通过 Kubernetes API 动态配置策略。

核心理念权限 = 角色 + 绑定。你先定义“角色”(能做什么),再把“角色”绑定给“谁”(用户/组/服务账户)。

第二章:RBAC 的核心概念与架构

2.1 四大核心资源

Kubernetes RBAC API 声明了四种对象:

资源类型作用范围作用
Role命名空间(Namespace)定义在某个命名空间内的权限规则
ClusterRole集群(Cluster)定义整个集群范围内的权限规则
RoleBinding命名空间(Namespace)某个命名空间内将 Role/ClusterRole 绑定给用户
ClusterRoleBinding集群(Cluster)整个集群范围内将 ClusterRole 绑定给用户

注意:权限规则是纯粹累加的——只定义“允许做什么”,不存在“拒绝”规则。

2.2 四者之间的关系

┌─────────────────────────────────────────────────────────────────────┐
│                         RBAC 四层模型                              │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                   Subject(主体)                            │  │
│  │         User / Group / ServiceAccount                       │  │
│  └────────────────────────┬─────────────────────────────────────┘  │
│                           │ 绑定                                   │
│                           ▼                                        │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │           RoleBinding / ClusterRoleBinding(绑定)           │  │
│  │              关联 Subject 与 Role/ClusterRole               │  │
│  └────────────────────────┬─────────────────────────────────────┘  │
│                           │ 引用                                   │
│                           ▼                                        │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │              Role / ClusterRole(角色)                      │  │
│  │       定义对哪些资源有哪些操作权限(rules)                  │  │
│  └──────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

2.3 使用场景速查

你想要实现的效果使用方案
只给某人在 某个命名空间查看 Pod 的权限Role + RoleBinding(同命名空间)
给某人在 所有命名空间查看 Pod 的权限ClusterRole + ClusterRoleBinding
给某人在 某个命名空间管理 Deployment(但命名空间级别的资源权限定义在 ClusterRole 中)ClusterRole(定义权限)+ RoleBinding(在特定命名空间绑定)
给某人 管理节点(集群级资源)的权限ClusterRole + ClusterRoleBinding

第三章:Subject(主体)—— 谁在请求权限?

在 RBAC 中,“谁”可以是三种类型:

类型说明示例
UserKubernetes 集群的外部用户(通常由集群管理员管理)alice@example.com
Group一组用户的集合(用于批量授权)developersops-team
ServiceAccountKubernetes 内部服务账户,供 Pod 使用my-sa(需提前创建)

重要提示:Kubernetes 没有内置的用户管理。User 和 Group 通常由外部身份系统(如 X.509 证书、OIDC、LDAP)提供。ServiceAccount 则是 Kubernetes 原生支持的内部身份。

3.1 创建 ServiceAccount(最常用)

# 在 default 命名空间创建 ServiceAccount
kubectl create serviceaccount my-sa

# 在指定命名空间创建
kubectl create serviceaccount my-sa -n staging

ServiceAccount 的用途

  • Pod 可以通过挂载 ServiceAccount 的 Token 来访问 API Server
  • CI/CD 系统可以使用 ServiceAccount 的凭证进行操作
  • 相比 User,ServiceAccount 更易于在 Kubernetes 内部管理

第四章:Role 和 ClusterRole —— 定义权限

4.1 Role —— 命名空间内的权限

Role 总是用来在某个命名空间内设置访问权限;创建 Role 时必须指定所属的命名空间。

Role YAML 结构

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default          # 必须指定命名空间
  name: pod-reader
rules:                         # 权限规则列表
- apiGroups: [""]              # API 组("" 表示核心 API 组)
  resources: ["pods"]          # 资源类型(复数形式)
  verbs: ["get", "list", "watch"]  # 允许的操作

rules 字段详解

字段说明示例
apiGroups资源所属的 API 组""(核心)、"apps""networking.k8s.io"
resources资源类型(必须用复数形式["pods"]["deployments"]["services"]
verbs允许的操作["get", "list", "watch", "create", "update", "patch", "delete"]

常用 verbs

Verb含义对应操作
get获取单个资源kubectl get pod <name>
list列出资源kubectl get pods
watch监听资源变化kubectl get pods -w
create创建资源kubectl create
update更新资源(整体替换)kubectl replace
patch部分更新资源kubectl patch
delete删除资源kubectl delete

4.2 ClusterRole —— 集群范围的权限

ClusterRole 是集群作用域的资源,有以下几种用法:

  1. 定义对命名空间作用域资源的权限,并在所有命名空间内授予
  2. 定义对集群作用域资源的权限(如 Nodes、PersistentVolumes)
  3. 定义对非资源端点的权限(如 /healthz

ClusterRole YAML 示例

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-reader    # 不需要 namespace
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]              # 集群级资源:节点
  resources: ["nodes"]
  verbs: ["get", "list"]
- nonResourceURLs: ["/healthz"]  # 非资源端点
  verbs: ["get"]

4.3 多资源、多 API 组配置

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: staging
  name: developer
rules:
# 核心 API 组资源
- apiGroups: [""]
  resources: ["pods", "pods/log", "services", "configmaps"]
  verbs: ["get", "list", "watch"]
# apps API 组资源(Deployment、StatefulSet 等)
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
# networking API 组资源(Ingress)
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch", "create", "update"]

4.4 子资源(Sub-resources)

某些资源有子资源,如 Pod 的日志(pods/log)和状态(pods/status):

rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]   # 允许查看 Pod 和 Pod 日志
  verbs: ["get", "list", "watch"]

4.5 资源名称限定(Resource Names)

可以精确到具体资源的名称,只允许操作特定的某个资源:

rules:
- apiGroups: [""]
  resources: ["pods"]
  resourceNames: ["my-app-abc123", "my-app-def456"]  # 只允许操作这两个 Pod
  verbs: ["get", "update", "delete"]

第五章:RoleBinding 和 ClusterRoleBinding —— 绑定权限

5.1 RoleBinding —— 命名空间内的绑定

RoleBinding 在某个命名空间内将角色绑定给主体。

RoleBinding YAML 示例

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:                       # 主体(谁)
- kind: User
  name: alice                   # 用户名
  apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
  name: my-sa                   # ServiceAccount
  namespace: default
roleRef:                        # 引用的角色(能做什么)
  kind: Role
  name: pod-reader              # 引用上面创建的 Role
  apiGroup: rbac.authorization.k8s.io

关键点:RoleBinding 可以引用同命名空间内的 Role,也可以引用 ClusterRole。引用 ClusterRole 时,ClusterRole 的权限会被限制在 RoleBinding 所在的命名空间内

5.2 ClusterRoleBinding —— 集群范围的绑定

ClusterRoleBinding 在整个集群范围内将 ClusterRole 绑定给主体。

ClusterRoleBinding YAML 示例

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-bind
subjects:
- kind: User
  name: admin-user
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:masters          # 组
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin           # 内置的最高权限角色
  apiGroup: rbac.authorization.k8s.io

5.3 使用 RoleBinding 绑定 ClusterRole(常见模式)

这是 Kubernetes 中最常见的权限管理模式:

  1. 使用 ClusterRole 定义一组通用的权限(如 vieweditadmin
  2. 使用 RoleBinding不同命名空间将同一个 ClusterRole 授予不同的人
# 在 staging 命名空间给开发者 view 权限
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-view
  namespace: staging
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view                    # 引用内置 ClusterRole
  apiGroup: rbac.authorization.k8s.io

第六章:内置 ClusterRole 与默认权限

Kubernetes 预置了几个常用的 ClusterRole:

ClusterRole权限范围适用场景
view只读权限,可查看命名空间内大多数资源(不包括 Secrets)审计员、只读用户
edit允许修改资源(创建/删除 Pod、更新 Deployment),不能管理 RBAC 或命名空间开发者
admin命名空间管理员,可管理资源(包括 Role 和 RoleBinding),不能管理集群级资源项目负责人
cluster-admin集群超级管理员,对所有资源拥有完全控制权集群管理员

6.1 查看内置 ClusterRole

# 列出所有 ClusterRole
kubectl get clusterrole

# 查看某个 ClusterRole 的详细信息
kubectl describe clusterrole view
kubectl describe clusterrole edit
kubectl describe clusterrole admin

6.2 使用内置 ClusterRole 的最佳实践

生产环境权限分配建议

人员/系统推荐的 ClusterRole绑定方式
只读用户(审计)viewClusterRoleBinding 或 RoleBinding
普通开发者editRoleBinding(限定命名空间)
项目负责人adminRoleBinding(限定命名空间)
CI/CD 系统自定义 RoleRoleBinding(限定命名空间)
集群管理员cluster-adminClusterRoleBinding(极少数人)

⚠️ 安全警告cluster-admin 相当于 root 权限。只有在绝对必要时才授予,且授予对象应严格限制。

第七章:完整实战示例

7.1 场景一:给开发者授予某个命名空间的 edit 权限

需求:开发者 alice 需要在 staging 命名空间内部署和管理应用。

Step 1:创建 ServiceAccount(可选)

# 如果使用 ServiceAccount 而非外部用户
kubectl create serviceaccount alice-sa -n staging

Step 2:创建 RoleBinding

# rolebinding-alice-staging.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: alice-staging-edit
  namespace: staging
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
# 或者使用 ServiceAccount
# - kind: ServiceAccount
#   name: alice-sa
#   namespace: staging
roleRef:
  kind: ClusterRole
  name: edit                     # 使用内置 edit ClusterRole
  apiGroup: rbac.authorization.k8s.io

Step 3:应用配置

kubectl apply -f rolebinding-alice-staging.yaml

Step 4:验证权限

# 以 alice 身份尝试操作(需要配置对应的 kubeconfig)
kubectl auth can-i create deployments -n staging --as=alice
# 输出:yes

kubectl auth can-i delete pods -n staging --as=alice
# 输出:yes(edit 权限允许删除 Pod)

kubectl auth can-i get secrets -n staging --as=alice
# 输出:no(edit 权限不允许查看 Secrets)

7.2 场景二:自定义 Role —— 只允许查看 Pod 日志

需求:运维人员 bob 需要查看所有命名空间的 Pod 日志,但不能做任何修改。

Step 1:创建自定义 ClusterRole

# clusterrole-pod-log-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-log-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

Step 2:创建 ClusterRoleBinding(授予所有命名空间)

# clusterrolebinding-bob-log-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: bob-log-reader
subjects:
- kind: User
  name: bob
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-log-reader
  apiGroup: rbac.authorization.k8s.io

Step 3:应用配置

kubectl apply -f clusterrole-pod-log-reader.yaml
kubectl apply -f clusterrolebinding-bob-log-reader.yaml

7.3 场景三:给 CI/CD 系统授予特定命名空间的部署权限

需求:GitLab CI 需要在 production 命名空间部署应用,权限最小化。

Step 1:创建 ServiceAccount

kubectl create serviceaccount gitlab-ci -n production

Step 2:创建自定义 Role

# role-gitlab-ci.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: gitlab-deployer
rules:
# Deployment 管理
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Service 管理
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Ingress 管理
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# 查看 Pod 状态(用于滚动更新监控)
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
# 查看 Events(用于调试)
- apiGroups: [""]
  resources: ["events"]
  verbs: ["get", "list", "watch"]

Step 3:创建 RoleBinding

# rolebinding-gitlab-ci.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: gitlab-ci-deployer
  namespace: production
subjects:
- kind: ServiceAccount
  name: gitlab-ci
  namespace: production
roleRef:
  kind: Role
  name: gitlab-deployer
  apiGroup: rbac.authorization.k8s.io

Step 4:应用配置

kubectl apply -f role-gitlab-ci.yaml
kubectl apply -f rolebinding-gitlab-ci.yaml

Step 5:获取 ServiceAccount 的 Token

# 获取 ServiceAccount 对应的 Secret 名称
kubectl get serviceaccount gitlab-ci -n production -o yaml

# 获取 Token
kubectl get secret <secret-name> -n production -o jsonpath='{.data.token}' | base64 -d

7.4 场景四:聚合 ClusterRole(Aggregated ClusterRole)

Kubernetes 支持将多个 ClusterRole 的规则聚合到一个 ClusterRole 中。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
  labels:
    rbac.authorization.k8s.io/aggregate-to-monitoring: "true"  # 聚合标签
rules: []
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-aggregated
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.authorization.k8s.io/aggregate-to-monitoring: "true"
rules: []   # 规则会自动从带标签的 ClusterRole 中聚合

第八章:权限验证与调试

8.1 使用 kubectl auth can-i 验证权限

# 检查当前用户能否在 default 命名空间创建 Deployment
kubectl auth can-i create deployments -n default

# 检查特定用户能否查看 Pod
kubectl auth can-i get pods -n staging --as=alice

# 检查 ServiceAccount 的权限
kubectl auth can-i list pods -n production --as=system:serviceaccount:production:gitlab-ci

# 检查所有命名空间的权限
kubectl auth can-i list nodes --as=bob

# 检查能否操作特定资源
kubectl auth can-i delete pod/my-app-abc123 -n default --as=alice

8.2 查看已有的 RBAC 配置

# 查看所有 Role
kubectl get roles -A

# 查看所有 ClusterRole
kubectl get clusterrole

# 查看 RoleBinding(含绑定的主体)
kubectl get rolebindings -A

# 查看 ClusterRoleBinding
kubectl get clusterrolebindings

# 查看某个 Role 的详细规则
kubectl describe role <role-name> -n <namespace>

# 查看某个 RoleBinding 绑定了谁
kubectl describe rolebinding <binding-name> -n <namespace>

8.3 使用 kubectl get 查看绑定关系

# 查看所有 RoleBinding 及其绑定的主体(宽输出)
kubectl get rolebindings -A -o wide

# 查看 ClusterRoleBinding
kubectl get clusterrolebindings -o wide

第九章:常见问题与故障排查

9.1 常见问题

问题可能原因解决方案
Error: forbidden没有相应权限检查 Role/ClusterRole 和 Binding 配置
ServiceAccount 无法操作资源未正确绑定检查 RoleBinding 的 subjects 是否正确
权限配置后不生效API Server 缓存等待几秒或重启 API Server
kubectl auth can-i 返回 no确实没有权限检查 Role 的 rules 是否正确
不知道用户属于哪个组认证配置不透明检查认证方式(证书/OIDC)

9.2 调试流程

# 1. 确认 RBAC 已启用
kubectl api-versions | grep rbac

# 2. 查看当前用户身份
kubectl whoami   # 某些版本支持

# 3. 检查 Role 是否存在
kubectl get role <role-name> -n <namespace>

# 4. 检查 RoleBinding 是否存在且正确
kubectl describe rolebinding <binding-name> -n <namespace>

# 5. 验证权限
kubectl auth can-i <verb> <resource> -n <namespace> --as=<user>

# 6. 查看 API Server 日志(需要管理员权限)
kubectl logs -n kube-system kube-apiserver-<node> | grep -i "forbidden\|rbac"

9.3 特权提升防护(Privilege Escalation Prevention)

Kubernetes RBAC 设计上防止用户创建比自己权限更大的角色。例如:

  • 普通用户不能创建 cluster-admin 级别的 ClusterRole
  • 用户不能创建包含自己没有的权限的 Role/ClusterRole
  • 例外:escalate verb 可以绕过此限制(需要特殊授权)

第十章:最佳实践总结

10.1 基本原则

  1. 最小权限原则:只授予完成任务所需的最小权限
  2. 使用命名空间隔离:不同团队/项目使用不同命名空间,权限限定在命名空间内
  3. 优先使用内置 ClusterRolevieweditadmin 覆盖大多数场景
  4. 避免使用 cluster-admin:除非绝对必要
  5. 定期审计权限:定期检查谁有什么权限,清理不必要的授权
  6. 使用 ServiceAccount 而非 User:Kubernetes 内部服务优先使用 ServiceAccount
  7. 将 RBAC 配置纳入版本控制:使用 Git 管理 YAML 文件

10.2 default ServiceAccount 的安全管理

Kubernetes 在每个命名空间都有一个 default ServiceAccount。如果未显式指定,Pod 会使用它。

默认行为default ServiceAccount 没有权限访问 API Server(在较新版本中)。

安全建议

  1. 不要default ServiceAccount 授予额外权限
  2. 为每个应用创建专用的 ServiceAccount
  3. 在 Pod 中显式指定 serviceAccountName
spec:
  serviceAccountName: my-app-sa   # 显式指定,避免使用 default

10.3 命名约定建议

资源类型命名建议示例
Role<用途>-<命名空间>developer-staging
ClusterRole<用途>-<scope>pod-log-reader
RoleBinding<主体>-<角色>-<命名空间>alice-developer-staging
ClusterRoleBinding<主体>-<角色>-clusterbob-view-cluster

附录:快速索引

需求命令/配置
创建 ServiceAccountkubectl create serviceaccount <name> -n <ns>
创建 Rolekubectl apply -f role.yaml
创建 ClusterRolekubectl apply -f clusterrole.yaml
创建 RoleBindingkubectl apply -f rolebinding.yaml
创建 ClusterRoleBindingkubectl apply -f clusterrolebinding.yaml
查看所有 Rolekubectl get roles -A
查看所有 ClusterRolekubectl get clusterrole
查看 RoleBindingkubectl get rolebindings -A
查看 ClusterRoleBindingkubectl get clusterrolebindings
验证权限kubectl auth can-i <verb> <resource> -n <ns> --as=<user>
删除 RoleBindingkubectl delete rolebinding <name> -n <ns>
删除 ClusterRoleBindingkubectl delete clusterrolebinding <name>

附录:常用 RBAC YAML 模板

Role 模板

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: <NAMESPACE>
  name: <ROLE_NAME>
rules:
- apiGroups: [""]
  resources: ["<RESOURCE>"]
  verbs: ["<VERB>"]

ClusterRole 模板

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: <CLUSTERROLE_NAME>
rules:
- apiGroups: [""]
  resources: ["<RESOURCE>"]
  verbs: ["<VERB>"]

RoleBinding 模板

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: <NAMESPACE>
  name: <BINDING_NAME>
subjects:
- kind: User|ServiceAccount|Group
  name: <SUBJECT_NAME>
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role|ClusterRole
  name: <ROLE_NAME>
  apiGroup: rbac.authorization.k8s.io

第十一章:分发凭证 —— 为用户生成和使用 kubeconfig 文件

在上一章中,我们通过 RBAC 定义了用户 alice 的权限。现在的问题是:如何将这把“钥匙”安全地交到她手上?

kubeconfig 文件就是这把“钥匙”。它是一个配置文件,其中包含了访问 Kubernetes 集群所需的所有信息:API Server 的地址、客户端凭证(如证书或 Token)以及上下文(Context)。

kubectl 命令行工具正是通过读取这个文件来找到 API Server 并与之通信的。

11.1 kubeconfig 文件的组成结构

一个 kubeconfig 文件主要包含三部分信息:

  • 集群(Clusters):要访问的 Kubernetes 集群信息,主要是 API Server 的地址和 CA 证书。
  • 用户(Users):用于向集群进行身份验证的凭证,可以是客户端证书Token用户名/密码
  • 上下文(Contexts):将“集群”、“用户”和“命名空间”组合在一起的一个配置,方便 kubectl 快速切换。

kubectl 会使用 当前上下文 中的参数与集群通信。

11.2 准备工作:获取集群的 CA 证书

在生成任何用户的 kubeconfig 之前,你需要先从集群中获取CA(证书颁发机构)证书。这是建立安全连接所必需的。

# 从 kubeconfig 中提取并解码 CA 证书(以 admin 用户的配置为例)
grep 'certificate-authority-data' ~/.kube/config | head -n1 | awk '{print $2}' | base64 -d > ca.crt

提示:在生产环境中,请从集群管理员处获取权威的 CA 证书文件。

11.3 场景一:为外部用户(User)生成 kubeconfig(基于证书)

此方法适用于 alicebob 这类由外部身份系统管理的用户。

前提:你需要为每个用户生成一组由集群 CA 签发的客户端证书(.crt私钥(.key。这通常是集群管理员的责任。

假设你已为 alice 用户生成了证书 alice.crt 和私钥 alice.key,以及集群的 CA 证书 ca.crt

1. 设置集群信息

# 将集群信息写入 alice-config 文件
# --server: 替换为你的 API Server 地址
# --certificate-authority: 指定 CA 证书路径
kubectl config set-cluster my-cluster \
  --server=https://<你的API-Server-地址>:6443 \
  --certificate-authority=ca.crt \
  --kubeconfig=alice-config \
  --embed-certs=true  # 将 ca.crt 内容嵌入到文件中

2. 设置用户凭证

# 将用户凭证写入 alice-config 文件
kubectl config set-credentials alice \
  --client-certificate=alice.crt \
  --client-key=alice.key \
  --kubeconfig=alice-config \
  --embed-certs=true  # 将证书和私钥嵌入到文件中

3. 设置上下文(Context)

# 创建一个名为 alice-context 的上下文
kubectl config set-context alice-context \
  --cluster=my-cluster \
  --user=alice \
  --namespace=default \ # 可指定该用户的默认命名空间
  --kubeconfig=alice-config

4. 切换当前上下文

# 设置 alice-config 文件的当前上下文为 alice-context
kubectl config use-context alice-context --kubeconfig=alice-config

5. 分发文件

最后,将生成的 alice-config 文件安全地交给 alice。她可以将此文件保存为 ~/.kube/config,或通过 --kubeconfig=alice-config 参数使用。

11.4 场景二:为 ServiceAccount 生成 kubeconfig(基于 Token)

这是为 CI/CD 工具(如 GitLab CI)或 Pod 中的应用授予权限的推荐方式。

此方法基于上一章的场景三,为 ServiceAccount gitlab-ci 生成 kubeconfig

1. 获取 ServiceAccount 的 Token

# 1. 获取 ServiceAccount 对应的 Secret 名称
SECRET_NAME=$(kubectl get serviceaccount gitlab-ci -n production -o jsonpath='{.secrets[0].name}')

# 2. 从 Secret 中解码并提取 Token
TOKEN=$(kubectl get secret $SECRET_NAME -n production -o jsonpath='{.data.token}' | base64 -d)

# 验证 Token 是否获取成功
echo $TOKEN

注意:在 Kubernetes v1.24+ 中,推荐使用更安全的 TokenRequest API 来生成具有时效性的 Token,而不是从 Secret 中获取永久 Token。

2. 设置集群信息

# 同样需要指定集群信息和 CA 证书
kubectl config set-cluster my-cluster \
  --server=https://<你的API-Server-地址>:6443 \
  --certificate-authority=ca.crt \
  --kubeconfig=ci-config \
  --embed-certs=true

3. 设置用户凭证(使用 Token)

# 将 Token 作为用户凭证
kubectl config set-credentials gitlab-ci-user \
  --token=$TOKEN \
  --kubeconfig=ci-config

4. 设置上下文并切换

# 创建并切换到名为 ci-context 的上下文
kubectl config set-context ci-context \
  --cluster=my-cluster \
  --user=gitlab-ci-user \
  --namespace=production \
  --kubeconfig=ci-config

kubectl config use-context ci-context --kubeconfig=ci-config

5. 分发和使用

生成的 ci-config 文件可以交给 CI/CD 系统使用。它的权限由 ServiceAccount gitlab-ci 绑定到的 Role 决定。

11.5 验证 kubeconfig 文件

在将文件交给用户之前,管理员可以使用以下命令验证其有效性:

# 使用新生成的 kubeconfig 文件查看当前用户信息
kubectl config view --kubeconfig=alice-config

# 使用新配置尝试列出 default 命名空间的 Pod
kubectl get pods --kubeconfig=alice-config

11.6 管理与切换多个集群

kubeconfig 文件的一个强大功能是它可以定义多个集群、用户和上下文。通过 kubectl config use-context 命令,你可以快速在它们之间切换,而无需重新配置环境。

# 查看当前配置
kubectl config view

# 切换到另一个上下文
kubectl config use-context another-context

kubectl 默认会加载 $HOME/.kube/config 文件。你也可以通过 KUBECONFIG 环境变量指定一个或多个配置文件。

11.7 最佳实践与安全提醒

  • 最小权限:在创建 kubeconfig 前,务必通过 RBAC 为用户或 ServiceAccount 配置好最小必要权限。
  • 安全分发kubeconfig 文件包含敏感凭证(私钥、Token),应通过加密渠道(如 LastPass、Vault)安全地分发给用户。
  • 谨慎嵌入证书:使用 --embed-certs=true 将凭证嵌入 kubeconfig 便于分发,但务必确保文件本身的安全。这等同于将密码写入了文件。
  • 使用短期 Token:为 ServiceAccount 生成 kubeconfig 时,优先使用可设置过期时间的 TokenRequest API,而不是使用永久 Secret,以降低凭证泄露的风险。
  • 最小化 kubeconfig 内容:只为用户提供其工作所需的最小配置(如特定的上下文),避免暴露整个集群的配置信息。

文档版本:v1.0
适用环境:Kubernetes v1.35+ / rbac.authorization.k8s.io/v1
前置条件:已部署 Kubernetes 集群并配置 kubectl
延伸阅读Kubernetes 官方 RBAC 文档

更多推荐