本文已发布超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。
使用 RBAC,在 Kubernetes v1.8 中通用可用 (GA)
编者注:本文是关于 Kubernetes 1.8 新功能的系列深度文章的一部分。
Kubernetes 1.8 是基于角色的访问控制 (RBAC) 授权器的一个重要里程碑,它在此版本中晋升为 GA。RBAC 是一种控制 Kubernetes API 访问的机制,自其在 1.6 中达到 Beta 版以来,许多 Kubernetes 集群和 Provisioning 策略已默认启用它。
展望未来,我们期望看到 RBAC 成为保护 Kubernetes 集群安全的基本构建块。本文探讨了如何使用 RBAC 管理用户和应用对 Kubernetes API 的访问。
授予用户访问权限
RBAC 使用标准的 Kubernetes 资源进行配置。用户可以通过绑定(ClusterRoleBindings 和 RoleBindings)绑定到一组角色(ClusterRoles 和 Roles)。用户开始时没有权限,必须由管理员明确授予访问权限。
所有 Kubernetes 集群都会安装一组默认的 ClusterRoles,代表可以将用户放入的常见类别。“edit”角色允许用户执行部署 Pods 等基本操作;“view”允许用户查看非敏感资源;“admin”允许用户管理一个 Namespace;而“cluster-admin”授予管理集群的权限。
$ kubectl get clusterroles
NAME AGE
admin 40m
cluster-admin 40m
edit 40m
# ...
view 40m
ClusterRoleBindings 授予用户、组或 Service Account 某个 ClusterRole 在整个集群范围内的权限。使用 kubectl,我们可以通过将示例用户“jane”绑定到“edit” ClusterRole,让她在所有 Namespace 中执行基本操作。
$ 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 在 Namespace 内授予 ClusterRole 的权限,允许管理员管理一个在整个集群中重用的 ClusterRoles 中心列表。例如,当新的资源添加到 Kubernetes 时,默认的 ClusterRoles 会更新,以自动授予 RoleBinding 主体在其 Namespace 内的正确权限。
接下来我们将允许“infra”组修改“dev” Namespace 中的资源。
$ kubectl create rolebinding infra --clusterrole=edit --group=infra --namespace=dev
rolebinding "infra" created
因为我们使用了 RoleBinding,这些权限只在 RoleBinding 的 Namespace 内生效。在我们的例子中,“infra”组中的用户可以查看“dev” Namespace 中的资源,但不能查看“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 manifests,并使用 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 与你的应用 manifests 一起发布。这不仅确保你的应用可以在启用 RBAC 的集群上工作,还有助于用户审计你的应用将在集群上执行哪些操作,并考虑其安全影响。
Namespaced Role 通常更适合应用,因为应用传统上运行在单个 Namespace 内,并且 Namespace 的资源应与应用的生命周期相关联。然而,Roles 不能授予对非 Namespaced 资源(如 nodes)的访问权限,也不能跨 Namespace 授予权限,因此某些应用可能仍然需要 ClusterRoles。
以下 Role 允许 Prometheus 实例在“dev” Namespace 中监控和发现 services、endpoints 和 pods。
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 集群中运行的容器会接收到 Service Account 凭据,用于与 Kubernetes API 通信,Service Account 可以被 RoleBinding 指定。Pods 通常使用“default” Service Account 运行,但最好为每个应用运行一个唯一的 Service Account,这样 RoleBindings 就不会无意中授予其他应用权限。
要使用自定义 Service Account 运行 Pod,请在同一 Namespace 中创建一个 ServiceAccount 资源,并在 manifest 中指定 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 的众多 SIGs 之一。参与 Kubernetes 社区的好方法是加入一个与你兴趣相关的 SIG,提供反馈并帮助制定路线图。
关于作者
Eric Chiang 是 CoreOS 的软件工程师和 Kubernetes 开发技术负责人,CoreOS 是企业级 Kubernetes 平台 Tectonic 的创建者。Eric 共同领导 Kubernetes SIG Auth,并代表 CoreOS 维护多个开源项目和库。