理解RBAC在Kubernetes中的作用
在Kubernetes集群中,权限管理是保障安全的关键环节。RBAC(Role-Based Access Control,基于角色的访问控制)机制让管理员可以精确控制用户或服务账户对资源的操作权限。比如,开发人员只需要查看和更新自己应用的Pod,而不应删除其他团队的Deployment。通过RBAC,这些需求都能实现。
启用RBAC并创建基本角色
Kubernetes默认支持RBAC,只要API Server启动时启用了--authorization-mode=RBAC即可。大多数现代集群都已默认开启。接下来就可以定义角色(Role)和角色绑定(RoleBinding)。
假设有一个名为dev-team的命名空间,我们希望给开发者只读权限。先创建一个Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-team
name: pod-reader
rules:
- apiGroups: [""]
resources: [pods]
verbs: [get, list, watch]这个角色允许在dev-team命名空间内获取、列出和监听Pod状态。
绑定用户到角色
有了角色后,需要将用户或ServiceAccount与之关联。如果使用的是Kubernetes内置的用户体系,通常通过证书CN字段识别用户。例如,将用户alice绑定到pod-reader角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: dev-team
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io执行kubectl apply -f 后,alice就能在dev-team空间查看Pod了,但无法做修改操作。
跨命名空间权限用ClusterRole
如果需要更广泛的权限,比如让运维人员能查看所有命名空间的日志,就得用ClusterRole和ClusterRoleBinding。ClusterRole不局限于单个命名空间,适合全局资源管理。
例如,创建一个可查看任意命名空间Pod的集群角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-reader
rules:
- apiGroups: [""]
resources: [pods]
verbs: [get, list, watch]然后绑定到特定用户:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-cluster-reader
subjects:
- kind: User
name: ops-admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-pod-reader
apiGroup: rbac.authorization.k8s.io这样ops-admin就有全集群的Pod读取权限了。
服务账户与RBAC结合使用
实际部署中,更多场景是Pod内的应用需要调用Kubernetes API。这时应为ServiceAccount分配RBAC权限。比如某个监控Sidecar需要读取当前命名空间的Deployment信息。
先创建ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: monitor-sa
namespace: production再创建Role和RoleBinding指向该账户:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: deployment-reader
rules:
- apiGroups: ["apps"]
resources: [deployments]
verbs: [get, list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: monitor-deploy-read
namespace: production
subjects:
- kind: ServiceAccount
name: monitor-sa
namespace: production
roleRef:
kind: Role
name: deployment-reader
apiGroup: rbac.authorization.k8s.io最后在Pod定义中指定serviceAccountName,容器内通过挂载的Token即可安全访问API。
避免常见权限配置陷阱
新手常犯的一个错误是直接给用户绑定cluster-admin角色,看似省事,实则埋下巨大安全隐患。一旦凭证泄露,整个集群就失控了。应该坚持最小权限原则,按需授权。
另一个问题是忽略API组和资源版本。例如,Deployment属于"apps/v1"而非核心组,写规则时必须明确apiGroups: ["apps"],否则权限不生效。
定期审查现有绑定也很重要。可以用kubectl get rolebindings,clusterrolebindings --all-namespaces检查谁有什么权限,及时清理不再使用的绑定。