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

使用 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 的权限,允许管理员管理一个中央 ClusterRoles 列表,该列表在整个集群中重复使用。例如,当新资源添加到 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 通常更合适,因为应用程序通常在单个命名空间中运行,并且命名空间的资源应该与应用程序的生命周期相关联。然而,Role 不能授予对非命名空间资源(例如节点)或跨命名空间的访问权限,因此某些应用程序可能仍然需要 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 的开发是通过 Auth 兴趣小组组织的社区工作,它是负责维护 Kubernetes 的众多 SIG 之一。参与 Kubernetes 社区的一个好方法是加入一个符合您兴趣的 SIG,提供反馈,并协助制定路线图。

关于作者

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