Kubernetes中使用RBAC授权

基于角色的访问控制(“RBAC”)使用“rbac.authorization.k8s.io”API 组来实现授权控制,允许管理员通过Kubernetes API动态配置策略。

截至1.6 RBAC模式是beta版。启用RBAC:

apiserver --authorization-mode=RBAC。

API概述

RBAC API声明了四个最高级别的类型(本文介绍),RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。

Role 和 ClusterRole

Role是一系列的权限的集合,例如一个Role可以包含读取 Pod 的权限和列出 Pod 的权限, ClusterRole 跟 Role 类似,但是可以在集群中全局使用。

Role只能授予单个namespace 中资源的访问权限。以下是Role“default”namespace 中的示例,用于授予对pod的访问权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ClusterRole授权 >= Role授予(与Role类似),但ClusterRole属于集群级别对象:

  • 集群范围(cluster-scoped)的资源访问控制(如:节点访问权限)
  • 非资源类型(如“/ healthz”)
  • 所有namespaces 中的namespaced 资源(如 pod)

ClusterRole示例:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding和ClusterRoleBinding

RoleBinding是将Role中定义的权限授予给用户或用户组。它包含一个subjects列表(users,groups ,service accounts),并引用该Role。RoleBinding在某个namespace 内授权,ClusterRoleBinding适用在集群范围内使用。

RoleBinding可以引用相同namespace下定义的Role。以下的RoleBinding在“default”namespace中将“pod-reader”Role授予用户“jane”。将允许“jane”在“default”namespace中读取pod权限。

# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding还可以参考ClusterRole。将允许管理员为整个集群定义一组通用Role,然后在不同namespace中使用RoleBinding引用。

示例:

# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets
  namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
  name: dave
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

最后,ClusterRoleBinding可以用于集群中所有命名空间中授予权限。以下ClusterRoleBinding允许组“manager”中的任何用户在任何命名空间中读取secrets。

# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Referring to Resources

大多数资源由name字符串的形式表示,例如“pod”。然而,一些Kubernetes API 涉及“子资源”,例如Pod的logs ,pod log endpoint 的URL:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这种情况下,“pod”是namespace中资源,“log”是pod的子资源,这种情况要在RBAC角色中表示,可以使用斜杠来划分资源和子资源。如下例子:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

资源也可以通过resourceNames列表的某些请求的资源名称来引用。如下例子:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

需要注意如果设置了resourceNames,那么verbs不能指定为list、watch、create或deletecollection。

Role 示例

只有rules部分定义显示在以下示例中。

允许在核心API Group中读取“pods”资源:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

允许在“extensions”和“apps”API Group中读/写“deployments”:

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取 “Pod” 和 读/写 “jobs”:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取名称为 “my-config” 的 ConfigMap:

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

允许读取核心 Group中资源“Node”(Node属于集群范围,则必须将ClusterRole绑定ClusterRoleBinding):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

允许非资源型“/ healthz”和所有子路径进行 “GET”和“POST”请求:(必须将ClusterRole绑定ClusterRoleBinding):

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
  verbs: ["get", "post"]

Referring to Subjects

RoleBinding或ClusterRoleBinding可以将Role绑定到主体subjects。Subjects 可以是groups、users和service accounts。

用户名Users由字符串表示,可用的格式有,如纯字符“alice”,Emai格式“[email protected]”或表示为字符串的数字。Users除了需要满足Kubernetes管理员配置的 authentication modules,对Users, RBAC授权系统没有做任何格式限定。除了前缀为system:是为Kubernetes系统使用而保留的用户名格式,除此之外RBAC授权系统可以使用任何格式的Users。

Kubernetes的Group 信息目前由Authenticator模块提供。和Users 一样,Group 由字符串表示,而且字符串没有格式要求,除了前缀system:是保留的。

Service Accounts使用system:serviceaccount:前缀的用户名,并且属于具有system:serviceaccounts:前缀的Group组。

Role Binding 示例

适合一个名为“[email protected]”的用户:

subjects:
- kind: User
  name: "[email protected]"
  apiGroup: rbac.authorization.k8s.io

适合一个名为“frontend-admins”的Group:

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

适合kube-system Namespace中的默认ServiceAccount:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

适合“qa”Namespace中的所有ServiceAccount:

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

适合集群中所有ServiceAccount:

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

适合所有经过认证的用户(1.5版本以上):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

适合所有未经认证的用户(1.5版本以上):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

适合所有用户(1.5版本以上):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

默认Role和 Role Bindings

API Server会创建一组默认的ClusterRole和ClusterRoleBinding对象。其中许多都是system:前缀,表示这些资源属于系统基础组件。修改这些资源对象可能会引起一些未知错误。例如:是system:nodeClusterRole,此角色定义了kubelet的权限,如果角色被修改,将会引起kubelet无法工作。

Auto-reconciliation

在每次启动时,API Server会更新默认的cluster roles ,并更新默认ClusterRoleBinding各个角色绑定主体,这使集群能够修复某些意外修改情况。

RBAC授权器处于激活状态时,在Kubernetes 1.6版本会默认启用Auto-reconciliation功能。

Discovery Roles

Default ClusterRole Default ClusterRoleBinding Description
system:basic-user system:

authenticated和

system:unauthenticatedgroups

Allows a user read-only access to basic information about themselves.
system:discovery system:

authenticated 和system:unauthenticatedgroups

Allows read-only access to API discovery endpoints needed to discover and negotiate an API level

User-facing Roles

一些不以system:为前缀的角色是面向用户的Role 。它们包括超级用户Role (cluster-admin),ClusterRoleBindings (cluster-status),以及特定namespaces中授权的 RoleBinding( admin,edit,view )

Default ClusterRole Default ClusterRoleBinding Description
cluster-admin system:masters group Allows super-user access to perform any action on any resource. When used in a ClusterRoleBinding, it gives full control over every resource in the cluster and in all namespaces. When used in a RoleBinding, it gives full control over every resource in the rolebinding's namespace, including the namespace itself.
admin None Allows admin access, intended to be granted within a namespace using a RoleBinding. If used in a RoleBinding, allows read/write access to most resources in a namespace, including the ability to create roles and rolebindings within the namespace. It does not allow write access to resource quota or to the namespace itself.
edit None Allows read/write access to most objects in a namespace. It does not allow viewing or modifying roles or rolebindings
view None Allows read-only access to see most objects in a namespace. It does not allow viewing roles or rolebindings. It does not allow viewing secrets, since those are escalating

Core Component Roles

Default ClusterRole Default ClusterRoleBinding Description
system:kube-scheduler system:kube-scheduler user Allows access to the resources required by the kube-scheduler component.
system:kube-controller-manager system:kube-controller-manager user Allows access to the resources required by the kube-controller-manager component. The permissions required by individual control loops are contained in the controller roles.
system:node system:nodes group (deprecated in 1.7) Allows access to resources required by the kubelet component, including read access to all secrets, and write access to all pods. As of 1.7, use of the [Node authorizer](/docs/admin/authorization/node/) and [NodeRestriction admission plugin](/docs/admin/admission-controllers#NodeRestriction) is recommended instead of this role, and allow granting API access to kubelets based on the pods scheduled to run on them. As of 1.7, when the `Node` authorization mode is enabled, the automatic binding to the `system:nodes` group is not created.
system:node-proxier system:kube-proxy user Allows access to the resources required by the kube-proxy component

Other Component Roles

Default ClusterRole Default ClusterRoleBinding Description
system:auth-delegator None Allows delegated authentication and authorization checks. This is commonly used by add-on API servers for unified authentication and authorization.
system:heapster None Role for the Heapster component.
system:kube-aggregator None Role for the kube-aggregator component.
system:kube-dns kube-dns service account in the kube-system namespace Role for the kube-dns component.
system:node-bootstrapper None Allows access to the resources required to perform Kubelet TLS bootstrapping.
system:node-problem-detector None Role for the node-problem-detector component.
system:persistent-volume-provisioner None Allows access to the resources required by most dynamic volume provisioners.

Controller Roles

Kubernetes controller manager负责运行的核心控制循环(core control loops)。当调用--use-service-account-credentials时,每个control loops都使用一个单独的service account启动,每个control loops存在前缀为system:controller:的Roles。如果controller manager未启动--use-service-account-credentials选项,它将使用本身的凭证运行所有control loops,如果这样需要在RBAC模式中授权相关Role。这些角色包括:

  • system:controller:attachdetach-controller
  • system:controller:certificate-controller
  • system:controller:cronjob-controller
  • system:controller:daemon-set-controller
  • system:controller:deployment-controller
  • system:controller:disruption-controller
  • system:controller:endpoint-controller
  • system:controller:generic-garbage-collector
  • system:controller:horizontal-pod-autoscaler
  • system:controller:job-controller
  • system:controller:namespace-controller
  • system:controller:node-controller
  • system:controller:persistent-volume-binder
  • system:controller:pod-garbage-collector
  • system:controller:replicaset-controller
  • system:controller:replication-controller
  • system:controller:resourcequota-controller
  • system:controller:route-controller
  • system:controller:service-account-controller
  • system:controller:service-controller
  • system:controller:statefulset-controller
  • system:controller:ttl-controller

命令行工具

有两个kubectl命令,用于在单个namespace或整个集群中授权Roles 。

kubectl create rolebinding

授权特定namespace中的Role或ClusterRole。如下示例:

  • 在“acme” Namespace将admin ClusterRole授予用户“bob”:
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
  • 在“acme”Namespace将view ClusterRole授予用户为“myapp”的Service Account:
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme

kubectl create clusterrolebinding

在整个集群中所有Namespace下授予ClusterRole。如下示例:

  • 在整个集群中将cluster-admin ClusterRole授予用户“root”:
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
  • 在整个集群中将system:node ClusterRole授予用户“kubelet”:
kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
  • 在整个集群中将view ClusterRole授予Namespace “acme”中的serviceaccount”myapp”:
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp

更多详细用法,请参考CLI说明

Service Account Permissions

默认RBAC策略限定的权限授予范围有control-plane组件、nodes和controllers,不会向“kube-system”Namespace之外的Service Account授予权限。

这允许你根据需要向特定的Service Account授予特定的Role 。细粒度角色绑定提供了更好的安全性,但需要更复杂的管理工作。更宽松的角色权限绑定可以提供不必要的API访问服务帐户权限,但更容易管理。

安全级别逐步降低:

1、应用指定Service Account授予特定的Role(最佳实践)

kubectl create rolebinding my-sa-view \
  --clusterrole=view \
  --serviceaccount=my-namespace:my-sa \
  --namespace=my-namespace

2、在Namespace中为“default”Service Account提供一个Role

kubectl create clusterrolebinding add-on-cluster-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:default

3、为Namespace中所有Service Account提供Role

kubectl create rolebinding serviceaccounts-view \
  --clusterrole=view \
  --group=system:serviceaccounts:my-namespace \
  --namespace=my-namespace

4、为所有Service Account授予Role(不推荐)

kubectl create clusterrolebinding serviceaccounts-view \
  --clusterrole=view \
  --group=system:serviceaccounts

5、授予超级用户权限对所有Service Account(强烈反对)

kubectl create clusterrolebinding serviceaccounts-cluster-admin \
  --clusterrole=cluster-admin \
  --group=system:serviceaccounts

从1.5版本升级

在Kubernetes 1.6之前,许多部署使用的ABAC策略,像有对Service Account授予全部的API访问权限。

默认RBAC策略限定的权限授予范围有control-plane组件、nodes和controllers,不会向“kube-system”Namespace之外的Service Account授予权限。

虽然安全性更高,但这可能应权限问题影响到某些工作负载。以下是管理两种权限的方法:

Parallel Authorizers

一起运行RBAC和ABAC授权(并包括旧版ABAC策略):

--authorization-mode=RBAC,ABAC --authorization-policy-file=mypolicy.json

RBAC授权器将首先尝试对请求授权,如果API请求被拒绝,那么将进行ABAC授权。

可以在apiserver(以2(-v=2)或更高的日志级别运行)的日志中看到RBAC授权被拒绝信息,使用该日志信息可以查看哪些Roles需要被授予哪些 users, groups, 或service accounts。如果向service accounts授予Roles,并且在服务器日志中查看到没有RBAC被拒绝的工作负载消息的时,则可以删除ABAC授权器。

Permissive RBAC Permissions

可以使用RBAC role bindings复制一个宽泛的策略。

警告:下面的策略允许所有Service Account充当集群管理员。在容器中运行的任何应用程序都会自动接收service account credentials ,并且可以对API执行任何操作,包括查看secrets、修改权限。默认不推荐使用。

kubectl create clusterrolebinding permissive-binding \
  --clusterrole=cluster-admin \
  --user=admin \
  --user=kubelet \
  --group=system:serviceaccounts