本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

在 Kubernetes v1.8 中普遍可用的 RBAC

编者按: 这篇文章是关于 Kubernetes 1.8 新特性的深度文章系列的一部分。

Kubernetes 1.8 代表了基于角色的访问控制 (RBAC) 授权器的一个重要里程碑,它在此版本中升级为 GA。RBAC 是一种控制对 Kubernetes API 访问的机制,自1.6 版本中的 beta 版以来,许多 Kubernetes 集群和配置策略已默认启用它。

展望未来,我们希望看到 RBAC 成为保护 Kubernetes 集群的基本构建模块。本文探讨如何使用 RBAC 来管理用户和应用程序对 Kubernetes API 的访问。

授予用户访问权限

RBAC 使用标准的 Kubernetes 资源进行配置。用户可以通过绑定(ClusterRoleBindings 和 RoleBindings)绑定到一组角色(ClusterRoles 和 Roles)。用户开始时没有任何权限,必须由管理员明确授予访问权限。

所有 Kubernetes 集群都安装了一组默认的 ClusterRoles,代表用户可以放入的常用存储桶。“edit”角色允许用户执行部署 Pod 等基本操作;“view”允许用户观察非敏感资源;“admin”允许用户管理命名空间;“cluster-admin”允许用户管理集群。


$ kubectl get clusterroles

NAME            AGE

admin           40m

cluster-admin   40m

edit            40m

# ...


view            40m

ClusterRoleBindings 授予用户、组或服务帐户在整个集群中 ClusterRole 的权限。使用 kubectl,我们可以通过将示例用户“jane”绑定到“edit” ClusterRole,让她在所有命名空间中执行基本操作


$ kubectl create clusterrolebinding jane --clusterrole=edit --user=jane

$ kubectl get namespaces --as=jane

NAME          STATUS    AGE

default       Active    43m

kube-public   Active    43m

kube-system   Active    43m

$ kubectl auth can-i create deployments --namespace=dev --as=jane

yes

RoleBindings 授予 ClusterRole 在命名空间内的权限,允许管理员管理整个集群中重复使用的 ClusterRole 的中央列表。例如,当新的资源被添加到 Kubernetes 时,默认的 ClusterRoles 会更新,以自动授予其命名空间内 RoleBinding 主题的正确权限。

接下来,我们将允许“infra”组修改“dev”命名空间中的资源


$ kubectl create rolebinding infra --clusterrole=edit --group=infra --namespace=dev

rolebinding "infra" created

由于我们使用了 RoleBinding,这些权限仅在 RoleBinding 的命名空间内生效。在我们的例子中,“infra”组中的用户可以查看“dev”命名空间中的资源,但不能查看“prod”中的资源


$ kubectl get deployments --as=dave --as-group=infra --namespace dev

No resources found.

$ kubectl get deployments --as=dave --as-group=infra --namespace prod

Error from server (Forbidden): deployments.extensions is forbidden: User "dave" cannot list deployments.extensions in the namespace "prod".

创建自定义角色

当默认的 ClusterRoles 不够用时,可以创建新的角色来定义自定义的权限集。由于 ClusterRoles 只是常规的 API 资源,它们可以表示为 YAML 或 JSON 清单,并使用 kubectl 应用。

每个 ClusterRole 都包含一个指定“规则”的权限列表。规则是纯粹的附加规则,允许对一组资源执行特定的 HTTP 动词。例如,以下 ClusterRole 拥有对“deployments”、“configmaps”或“secrets”执行任何操作的权限,以及查看任何“pod”的权限


kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

 name: deployer

rules:

- apiGroups: ["apps"]

 resources: ["deployments"]

 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]



- apiGroups: [""] # "" indicates the core API group

 resources: ["configmaps", "secrets"]

 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]



- apiGroups: [""] # "" indicates the core API group

 resources: ["pods"]

 verbs: ["get", "list", "watch"]

动词对应于请求的 HTTP 动词,而资源和 API 组是指被引用的资源。考虑以下 Ingress 资源


apiVersion: extensions/v1beta1

kind: Ingress

metadata:

 name: test-ingress

spec:

 backend:

   serviceName: testsvc

   servicePort: 80

要 POST 资源,用户需要以下权限


rules:

- apiGroups: ["extensions"] # "apiVersion" without version

 resources: ["ingresses"]  # Plural of "kind"

 verbs: ["create"]         # "POST" maps to "create"

应用程序的角色

部署需要访问 Kubernetes API 的容器时,最好在应用程序清单中附带 RBAC Role。除了确保您的应用程序在启用 RBAC 的集群上工作之外,这还有助于用户审核您的应用程序将在集群上执行的操作,并考虑其安全影响。

命名空间的 Role 通常更适合应用程序,因为应用程序传统上在单个命名空间内运行,并且命名空间的资源应与应用程序的生命周期相关联。但是,Roles 不能授予对非命名空间资源(例如节点)或跨命名空间的访问权限,因此某些应用程序可能仍然需要 ClusterRoles。

以下 Role 允许 Prometheus 实例监视和发现“dev”命名空间中的服务、端点和 Pod


kind: Role

metadata:

 name: prometheus-role

 namespace: dev

rules:

- apiGroups: [""] # "" refers to the core API group

 Resources: ["services", "endpoints", "pods"]

 verbs: ["get", "list", "watch"]

在 Kubernetes 集群中运行的容器会收到服务帐户凭据以与 Kubernetes API 通信,并且服务帐户可以成为 RoleBinding 的目标。Pod 通常使用“default”服务帐户运行,但最好使用唯一的服务帐户运行每个应用程序,这样 RoleBindings 就不会无意中授予其他应用程序权限。

要使用自定义服务帐户运行 Pod,请在同一命名空间中创建一个 ServiceAccount 资源,并指定清单的 serviceAccountName 字段。


apiVersion: apps/v1beta2 # Abbreviated, not a full manifest

kind: Deployment

metadata:

 name: prometheus-deployment

 namespace: dev

spec:

 replicas: 1

 template:

   spec:

     containers:

     - name: prometheus

       image: prom/prometheus:v1.8.0

       command: ["prometheus", "-config.file=/etc/prom/config.yml"]

   # Run this pod using the "prometheus-sa" service account.

   serviceAccountName: prometheus-sa

---

apiVersion: v1

kind: ServiceAccount

metadata:

 name: prometheus-sa

 namespace: dev

参与其中

RBAC 的开发是一项社区工作,由身份验证特别兴趣小组组织,它是负责维护 Kubernetes 的众多 SIG之一。参与 Kubernetes 社区的一个好方法是加入一个符合您兴趣的 SIG,提供反馈并帮助制定路线图。

关于作者

Eric Chiang 是 CoreOS 的软件工程师和 Kubernetes 开发技术主管,CoreOS 是企业级 Kubernetes 平台 Tectonic 的创建者。Eric 共同领导 Kubernetes SIG Auth,并代表 CoreOS 维护多个开源项目和库。