在 Kubernetes 中,RBAC(Role-Based Access Control)是一个用来控制对 Kubernetes 资源访问的授权机制。它通过定义不同角色(Role)和这些角色可以访问的权限,确保只有被授权的用户或服务能够执行特定的操作。RBAC 提供了灵活的权限管理功能,适用于不同的用户、服务账户以及应用程序。
RBAC 的基本概念
Kubernetes 的 RBAC 主要包括以下几个基本概念:
- Role 和 ClusterRole
- RoleBinding 和 ClusterRoleBinding
- ServiceAccount
- PolicyRules
1. Role 和 ClusterRole
-
Role:定义了在某个特定命名空间内的权限。它描述了某个用户或服务账户可以对哪些资源进行哪些操作。例如,
Role
可以授予用户在default
命名空间中列出 Pods 和创建 Deployments 的权限。-
示例 Role:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:namespace: default # 指定 Role 的命名空间name: pod-reader # Role 的名称 rules: - apiGroups: [""]resources: ["pods"]verbs: ["get", "list"]
上述示例中,
pod-reader
角色授予用户对default
命名空间下的 Pods 资源的 get 和 list 权限。
-
-
ClusterRole:定义了集群范围内的权限,不依赖于命名空间。
ClusterRole
可以用于跨命名空间访问资源,或者在集群级别执行操作(例如管理节点、查看集群的状态等)。-
示例 ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:# ClusterRole 没有命名空间字段name: cluster-admin rules: - apiGroups: [""]resources: ["pods"]verbs: ["get", "list", "create", "delete"]
上述示例中的
cluster-admin
ClusterRole
赋予用户对集群内所有 Pods 资源的管理权限。
-
2. RoleBinding 和 ClusterRoleBinding
-
RoleBinding:将一个
Role
(命名空间级别)或ClusterRole
(集群级别)绑定到一个或多个用户、组或者服务账户上。RoleBinding
只在特定的命名空间内有效。-
示例 RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: read-podsnamespace: default subjects: - kind: Username: "jane" # 绑定的主体是用户 "jane"apiGroup: rbac.authorization.k8s.io roleRef:kind: Rolename: pod-reader # 绑定到名为 pod-reader 的 RoleapiGroup: rbac.authorization.k8s.io
在这个例子中,用户
jane
被授权使用default
命名空间中的pod-reader
Role,从而可以列出和查看该命名空间中的 Pods。
-
-
ClusterRoleBinding:将一个
ClusterRole
绑定到一个或多个用户、组或者服务账户上,作用范围是整个集群。-
示例 ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: admin-binding subjects: - kind: Username: "jane"apiGroup: rbac.authorization.k8s.io roleRef:kind: ClusterRolename: cluster-admin # 绑定到集群管理员权限apiGroup: rbac.authorization.k8s.io
这意味着
jane
用户将会获得集群管理员的权限,能够在整个集群中执行任何操作。
-
3. 使用 kubectl impersonate 命令模拟 jane
用户
Kubernetes 提供了 kubectl auth can-i
命令来模拟某个用户的权限。你可以使用 kubectl impersonate
来临时以 jane
用户的身份运行命令,检查她是否具有某些操作的权限。
步骤:
-
模拟
jane
用户执行kubectl
命令使用
kubectl auth can-i
命令来检查jane
是否有执行某个操作的权限。例如,检查她是否可以在default
命名空间下列出 Pods:kubectl auth can-i list pods --namespace=default --as=jane
解释:
--as=jane
:指定以jane
用户身份进行操作。list pods --namespace=default
:测试jane
是否可以列出default
命名空间中的 Pods。
如果命令返回
yes
,说明jane
拥有该操作的权限;如果返回no
,说明jane
不具有该权限。
示例输出:
$ kubectl auth can-i list pods --namespace=default --as=jane
yes
如果返回 yes
,那么 jane
就能够列出 Pods,说明她有 pod-reader
角色授予的权限。
4. 检查 RoleBinding 是否生效
你还可以检查 RoleBinding
是否正确配置,确认是否已将正确的角色和主体绑定在一起。
步骤:
-
查看 RoleBinding
使用以下命令检查
RoleBinding
是否正确绑定了角色:kubectl get rolebinding read-pods --namespace=default -o yaml
输出应类似于:
kind: RoleBinding metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"read-pods","namespace":"default"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"Role","name":"pod-reader"},"subjects":[{"apiGroup":"rbac.authorization.k8s.io","kind":"User","name":"jane"}]}creationTimestamp: "2024-12-04T06:31:39Z"name: read-podsnamespace: defaultresourceVersion: "188345"uid: 283615ff-8e9b-4e25-a6e8-7e5bcbbd582f roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: pod-reader subjects: - apiGroup: rbac.authorization.k8s.iokind: Username: jane
-
检查 Role 配置
确保
pod-reader
角色已正确配置,并且具有正确的权限。使用以下命令检查pod-reader
角色:kubectl get role pod-reader --namespace=default -o yaml
输出应类似于:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pod-reader","namespace":"default"},"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["get","list"]}]}creationTimestamp: "2024-12-04T06:31:33Z"name: pod-readernamespace: defaultresourceVersion: "188338"uid: 78e25dfb-4bd2-41da-af5f-4b812caa7cbf rules: - apiGroups:- ""resources:- podsverbs:- get- list
确保角色
pod-reader
确实有对pods
资源的get
和list
权限。
5. ServiceAccount
-
ServiceAccount:通常用于为 Kubernetes 中运行的 Pod 提供身份验证。通过给 Pod 分配一个
ServiceAccount
,可以控制 Pod 对 API 服务器的访问权限。例如,Pod 可以被配置为使用一个特定的ServiceAccount
,该账户可能拥有对某些资源的特定权限。-
示例 ServiceAccount:
apiVersion: v1 kind: ServiceAccount metadata:name: my-app-service-accountnamespace: default
你可以为 Pod 分配这个
ServiceAccount
,从而使 Pod 拥有该账户的权限。
-
5. 测试 Pod 的 ServiceAccount 权限
在 Kubernetes 中,ServiceAccount 是一种用于为 Pod 或应用程序提供身份认证的机制。当一个 Pod 被分配一个 ServiceAccount 时,Kubernetes 会将与该账户关联的权限授予该 Pod,从而允许它与 Kubernetes API 进行交互。
要测试一个 Pod 的 ServiceAccount 权限,通常是通过以下几个步骤来检查它是否有正确的权限来执行某些操作(如查看、创建或删除资源等)。我们可以通过以下步骤测试 ServiceAccount 的权限:
-
确保 Pod 使用了正确的 ServiceAccount
首先,确保 Pod 使用了您所创建的
ServiceAccount
。可以在 Pod 的 YAML 文件中指定serviceAccountName
来确保 Pod 使用该账户。例如,假设您有一个
ServiceAccount
名为my-app-service-account
,然后在 Pod 配置中引用它:apiVersion: v1 kind: Pod metadata:name: my-app-pod spec:serviceAccountName: my-app-service-account # 绑定 ServiceAccountcontainers:- name: my-app-containerimage: nginx
-
为 ServiceAccount 配置适当的 RBAC 权限
为了让
my-app-service-account
拥有访问权限,您需要使用 RBAC 配置为其授予特定的角色(Role
或ClusterRole
)和操作权限(如get
、list
、create
等)。以下是一个示例,假设您希望my-app-service-account
有权限列出 Pods 资源:-
Role(命名空间级别权限):
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:name: pod-readernamespace: default rules: - apiGroups: [""]resources: ["pods"]verbs: ["get", "list"]
-
RoleBinding(将
Role
绑定到ServiceAccount
):apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: read-podsnamespace: default subjects: - kind: ServiceAccountname: my-app-service-accountnamespace: default roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
在这个示例中,
pod-reader
角色允许my-app-service-account
列出和获取default
命名空间中的 Pods 资源。 -
-
测试 ServiceAccount 权限
现在,您可以通过以下方式来测试
my-app-service-account
是否具有足够的权限:-
使用
kubectl auth can-i
命令:使用
kubectl auth can-i
命令模拟ServiceAccount
执行操作。这个命令会帮助您测试ServiceAccount
是否有权限执行某个操作。kubectl auth can-i list pods --namespace=default --as=system:serviceaccount:default:my-app-service-account
这里:
list pods --namespace=default
:检查my-app-service-account
是否有权限列出default
命名空间下的 Pods。--as=system:serviceaccount:default:my-app-service-account
:模拟以my-app-service-account
身份执行操作。
如果返回
yes
,则说明ServiceAccount
有权限列出 Pods。如果返回no
,则说明没有该权限。示例输出:
$ kubectl auth can-i list pods --namespace=default --as=system:serviceaccount:default:my-app-service-account yes
-
直接在 Pod 中测试权限
你可以手动为该 Pod 指定一个 ServiceAccount。创建一个 YAML 文件,修改 ServiceAccount 后再应用
apiVersion: v1 kind: Pod metadata:name: debug spec:serviceAccountName: my-app-service-accountcontainers:- name: debugimage: bitnami/kubectl:latestcommand: ["/bin/sh"]stdin: truetty: true
kubectl exec -it debug -n default -- /bin/sh
-
6. PolicyRules
-
PolicyRules:在
Role
和ClusterRole
中定义的一组规则,用来描述哪些资源、哪些操作是允许的。PolicyRules
使用apiGroups
、resources
和verbs
来定义具体的权限。-
apiGroups:指定资源属于哪个 API 组。例如,
""
代表 Core API 组,apps
代表部署等资源。 -
resources:指定资源类型,如
pods
、deployments
、services
等。 -
verbs:指定允许的操作,如
get
(获取)、list
(列出)、create
(创建)、delete
(删除)等。 -
示例 PolicyRules:
rules: - apiGroups: [""]resources: ["pods"]verbs: ["get", "list"] - apiGroups: ["apps"]resources: ["deployments"]verbs: ["create", "delete"]
在这个示例中,定义了两条规则:
- 对
pods
资源,允许get
和list
操作。 - 对
deployments
资源,允许create
和delete
操作。
- 对
-
RBAC 使用场景
- 控制集群资源访问:通过
Role
和ClusterRole
控制用户或服务账户对 Kubernetes 资源的访问权限。例如,限制某个用户只能查看 Pods,而不能修改或删除。 - 服务账户:为不同的应用程序、服务或者 Pod 创建专用的服务账户,并绑定适当的角色,确保它们只有执行任务所需的最小权限。
- 权限最小化:通过精细的权限控制,遵循 最小权限原则,使得用户、服务账户或者应用程序只能访问它们执行任务所需的资源。
常见命令
-
查看角色和角色绑定:
kubectl get roles kubectl get rolebindings kubectl get clusterroles kubectl get clusterrolebindings
-
创建和应用 RBAC 资源:
kubectl apply -f role.yaml kubectl apply -f rolebinding.yaml
总结
Kubernetes 的 RBAC 通过 Role 和 ClusterRole 来定义不同的权限,并通过 RoleBinding 和 ClusterRoleBinding 来将这些权限绑定到特定的用户、组或服务账户。RBAC 提供了一种细粒度的访问控制机制,帮助管理员确保集群资源的安全性,并且根据不同的需求授予相应的权限。