Kubernetes RBAC 完全指南(适用于 Kubernetes v1.35)
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 中,“谁”可以是三种类型:
| 类型 | 说明 | 示例 |
|---|---|---|
| User | Kubernetes 集群的外部用户(通常由集群管理员管理) | alice@example.com |
| Group | 一组用户的集合(用于批量授权) | developers、ops-team |
| ServiceAccount | Kubernetes 内部服务账户,供 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 是集群作用域的资源,有以下几种用法:
- 定义对命名空间作用域资源的权限,并在所有命名空间内授予
- 定义对集群作用域资源的权限(如 Nodes、PersistentVolumes)
- 定义对非资源端点的权限(如
/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 中最常见的权限管理模式:
- 使用 ClusterRole 定义一组通用的权限(如
view、edit、admin) - 使用 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 | 绑定方式 |
|---|---|---|
| 只读用户(审计) | view | ClusterRoleBinding 或 RoleBinding |
| 普通开发者 | edit | RoleBinding(限定命名空间) |
| 项目负责人 | admin | RoleBinding(限定命名空间) |
| CI/CD 系统 | 自定义 Role | RoleBinding(限定命名空间) |
| 集群管理员 | cluster-admin | ClusterRoleBinding(极少数人) |
⚠️ 安全警告:
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
- 例外:
escalateverb 可以绕过此限制(需要特殊授权)
第十章:最佳实践总结
10.1 基本原则
- 最小权限原则:只授予完成任务所需的最小权限
- 使用命名空间隔离:不同团队/项目使用不同命名空间,权限限定在命名空间内
- 优先使用内置 ClusterRole:
view、edit、admin覆盖大多数场景 - 避免使用
cluster-admin:除非绝对必要 - 定期审计权限:定期检查谁有什么权限,清理不必要的授权
- 使用 ServiceAccount 而非 User:Kubernetes 内部服务优先使用 ServiceAccount
- 将 RBAC 配置纳入版本控制:使用 Git 管理 YAML 文件
10.2 default ServiceAccount 的安全管理
Kubernetes 在每个命名空间都有一个 default ServiceAccount。如果未显式指定,Pod 会使用它。
默认行为:default ServiceAccount 没有权限访问 API Server(在较新版本中)。
安全建议:
- 不要给
defaultServiceAccount 授予额外权限 - 为每个应用创建专用的 ServiceAccount
- 在 Pod 中显式指定
serviceAccountName
spec:
serviceAccountName: my-app-sa # 显式指定,避免使用 default
10.3 命名约定建议
| 资源类型 | 命名建议 | 示例 |
|---|---|---|
| Role | <用途>-<命名空间> | developer-staging |
| ClusterRole | <用途>-<scope> | pod-log-reader |
| RoleBinding | <主体>-<角色>-<命名空间> | alice-developer-staging |
| ClusterRoleBinding | <主体>-<角色>-cluster | bob-view-cluster |
附录:快速索引
| 需求 | 命令/配置 |
|---|---|
| 创建 ServiceAccount | kubectl create serviceaccount <name> -n <ns> |
| 创建 Role | kubectl apply -f role.yaml |
| 创建 ClusterRole | kubectl apply -f clusterrole.yaml |
| 创建 RoleBinding | kubectl apply -f rolebinding.yaml |
| 创建 ClusterRoleBinding | kubectl apply -f clusterrolebinding.yaml |
| 查看所有 Role | kubectl get roles -A |
| 查看所有 ClusterRole | kubectl get clusterrole |
| 查看 RoleBinding | kubectl get rolebindings -A |
| 查看 ClusterRoleBinding | kubectl get clusterrolebindings |
| 验证权限 | kubectl auth can-i <verb> <resource> -n <ns> --as=<user> |
| 删除 RoleBinding | kubectl delete rolebinding <name> -n <ns> |
| 删除 ClusterRoleBinding | kubectl 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(基于证书)
此方法适用于 alice、bob 这类由外部身份系统管理的用户。
前提:你需要为每个用户生成一组由集群 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 文档
更多推荐
所有评论(0)