注意事项 佩雷夫 :本文由来自Bitnami著名Kubernetes社区的工程师Javier Salmeron撰写,并于8月初发布在CNCF博客上。 作者讨论了一年半前出现在Kubernetes中的RBAC(基于角色的访问控制)机制的基本知识。 该材料对于熟悉K8关键部件装置的人特别有用(请参阅最后的其他类似文章的链接)。
Google员工在发布Kubernetes 1.6时所做的演示的幻灯片许多有经验的Kubernetes用户可能会想起基于Kubernetes 1.6的发布,当时基于角色的访问控制(RBAC)的授权成为beta。 因此出现了一种替代的身份验证机制,该机制对已经存在但难以管理和理解的基于属性的访问控制(ABAC)进行了补充。 每个人都热烈欢迎这项新功能,但与此同时,无数用户对此感到失望。 StackOverflow和GitHub上充斥着RBAC限制的报告,因为大多数文档和示例都没有考虑RBAC(但现在一切都很好)。 参考示例为Helm:仅运行
helm init
+
helm install
不再起作用。 突然之间,我们甚至需要在使用WordPress或Redis部署图表之前,需要添加诸如
ServiceAccounts
或
RoleBindings
类的“怪异”元素(有关更多信息,请参见
说明 )。
撇开这些未成功的第一手尝试,不能否认RBAC为将Kubernetes转变为可投入生产的平台所做的巨大贡献。 我们中的许多人都拥有完全的管理员特权,可以使用Kubernetes进行游戏,我们完全理解在实际环境中这是必要的:
- 使许多具有不同属性的用户提供所需的身份验证机制。
- 完全控制每个用户或用户组可以执行的操作。
- 完全控制心脏中每个过程可以执行的操作。
- 限制名称空间中某些资源的可见性。
在这方面,RBAC是提供急需功能的关键元素。 在本文中,我们将快速讲解基础知识
(有关详细信息,请参见此视频 ;请使用英语的1小时Bitnami网络研讨会链接- 大约翻译 ),并深入了解最令人困惑的时刻。
在Kubernetes中了解RBAC的关键
要完全实现RBAC的想法,您需要了解其中涉及三个要素:
- 主题 -一组想要访问Kubernetes API的用户和流程;
- 资源 -集群中可用的Kubernetes API对象的集合。 他们的示例(包括Pod , Deployment , Services , Nodes , PersistentVolumes等) ;
- 动词 (动词)-可以对资源执行的一组操作。 动词有多种(获取,监视,创建,删除等),但它们最终都是来自CRUD类别(创建,读取,更新,删除)的操作。

考虑到这三个要素,RBAC的关键思想是:
“我们希望将主题,API资源和操作联系起来。” 换句话说,我们要为给定的
用户指示可以对各种
资源执行哪些
操作 。
了解API中的RBAC对象
通过结合这三种类型的实体,Kubernetes API中可用的RBAC对象变得很清楚:
Roles
连接资源和动词。 它们可以重用于不同的主题。 绑定到一个名称空间(我们不能使用表示多个[名称空间]的模板,但可以将同一角色对象部署到不同的名称空间)。 如果要将角色应用于整个集群,则有一个类似的ClusterRoles
对象。RoleBindings
连接其余实体实体。 通过指定已经将API对象与动词联系起来的角色,我们现在选择可以使用它们的主题。 集群级别(即不绑定到名称空间)的ClusterRoleBindings
是ClusterRoleBindings
。
在下面的示例中,我们赋予用户
jsalmeron读取,获取列表以及在
测试名称空间中创建壁炉
的权利。 这意味着
jsalmeron将能够执行以下命令:
kubectl get pods --namespace test kubectl describe pod --namespace test pod-name kubectl create --namespace test -f pod.yaml
...但不是那样的:
kubectl get pods --namespace kube-system

YAML文件的示例:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: pod-read-create namespace: test rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "create"]
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: salme-pods namespace: test subjects: - kind: User name: jsalmeron apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-read-create apiGroup: rbac.authorization.k8s.io
另一个有趣的一点是:既然用户可以创建吊舱,我们可以限制多少个吊舱吗? 这将需要与RBAC规范不直接相关的其他对象,并允许您配置资源限制:
ResourceQuota
和
LimitRanges
。 在配置如此重要的群集组件(例如创建炉膛)时,绝对值得探索。
主题:用户和... ServiceAccounts?
许多Kubernetes用户在主题上下文中面临的困难之一是常规用户和
ServiceAccounts
之间的区别。 从理论上讲,一切都很简单:
Users
-面向群集外人员或流程的全球用户;ServiceAccounts
受名称空间限制,适用于在Pod上运行的集群中的进程。
两种类型的相似之处在于需要通过API进行身份验证以对许多资源执行某些操作,并且它们的主题区域看起来非常具体。 它们也可以属于组,因此
RoleBinding
允许
RoleBinding
绑定多个主题(尽管
ServiceAccounts
-
system:serviceaccounts
只允许一个组)。 但是,主要的区别是造成头痛的原因:用户在Kubernetes API中没有与之相对应的对象。 事实证明存在这样的操作:
kubectl create serviceaccount test-service-account
...但是这个消失了:
kubectl create user jsalmeron
这种情况产生了严重的后果:如果群集未存储有关用户的信息,则管理员将不得不管理群集外部的帐户。 解决问题的方法有多种:TLS证书,令牌,OAuth2等。
另外,您将需要创建
kubectl
上下文,
kubectl
我们可以通过这些新帐户访问集群。 要使用它们创建文件,您可以使用
kubectl config
命令(不需要访问Kubernetes API,因此任何用户都可以执行它们)。 上面的视频提供了使用TLS证书创建用户的示例。
部署中的RBAC:示例
我们看到了一个示例,其中向指定的用户授予了集群中操作的权限。 但是需要访问Kubernetes API的
部署又如何呢? 考虑一个特定的场景以更好地理解。
以流行的基础架构应用程序-RabbitMQ为例。 我们将使用Bitnami的
RabbitMQ的
Helm图表 (来自官方helm / charts存储库),该图表使用
bitnami / rabbitmq容器 。 容器中内置了Kubernetes插件,该插件负责检测RabbitMQ集群的其他成员。 因此,容器内的进程需要访问Kubernetes API,并且我们需要使用正确的RBAC特权配置
ServiceAccount
。
对于
ServiceAccounts
,请遵循以下良好做法:
-使用
最小权限集 为每个部署配置
ServiceAccounts 。
对于需要访问Kubernetes API的应用程序,您可能会想创建某种“特权
ServiceAccount
”,它几乎可以在集群中执行任何操作。 尽管这似乎是一个更简单的解决方案,但它最终可能会导致一个安全漏洞,该漏洞可能允许不必要的操作。 (该视频观看了一个Tiller [Helm组件]的示例,以及具有非常特权的
ServiceAccounts
的后果。)
另外,不同的
部署在访问API方面会有不同的需求,因此每个
部署都有不同的
ServiceAccounts
是合理的。
牢记这一点,让我们看看哪种RBAC配置对于RabbitMQ的
Deployment情况是正确
的 。
在
插件的文档 及其源代码中,您可以看到它正在从Kubernetes API请求
端点列表。 这就是检测RabbitMQ集群其余成员的方式。 因此,Bitnami RabbitMQ图表创建:
- ServiceRabbitMQ的炉膛帐户:
{{- if .Values.rbacEnabled }} apiVersion: v1 kind: ServiceAccount metadata: name: {{ template "rabbitmq.fullname" . }} labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" {{- end }}
- 角色 (我们假设整个RabbitMQ集群都部署在单个名称空间中),从而允许动词获取 Endpoint资源:
{{- if .Values.rbacEnabled }} kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get"] {{- end }}
- RoleBinding将
ServiceAccount
连接到角色:
{{- if .Values.rbacEnabled }} kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" subjects: - kind: ServiceAccount name: {{ template "rabbitmq.fullname" . }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ template "rabbitmq.fullname" . }}-endpoint-reader {{- end }}

该图显示了我们允许运行在RabbitMQ pod中的进程对
Endpoint对象执行
get操作。 这是一切正常工作所需的最少一组操作。 同时,我们知道已部署的图表是安全的,不会在Kubernetes集群内部执行不必要的操作。
最后的想法
要在生产中使用Kubernetes,RBAC策略不是可选的。 它们不能被视为只有管理员应该知道的一组API对象。 开发人员实际上需要他们部署安全的应用程序,并充分利用Kubernetes API为云原生应用程序提供的潜力。 在以下链接上可以找到有关RBAC的更多信息:
译者的PS
另请参阅我们的博客: