ITPub博客

首页 > 数据库 > 数据库开发技术 > kuberntes的权限控制是怎么样的

kuberntes的权限控制是怎么样的

原创 数据库开发技术 作者:步步运维步步坑 时间:2023-11-02 11:43:32 0 删除 编辑

RBAC介绍

基于角色的访问控制 (RBAC) 是一种根据组织内各个用户的角色来管理对计算机或网络资源的访问的方法。

RBAC授权使用rbac.authorization.k8s.io API组驱动授权决策,允许您通过 Kubernetes API 动态配置策略。

要启用 RBAC,请启动API服务器 将--authorization-mode标志设置为逗号分隔的列表,其中包括RBAC; 例如:

kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options


在RBAC API中,可以通过下面你的方式进行授权

1)定义角色:在定义角色时指定此角色对于资源的访问控制的规则;

2)绑定角色:将主体与角色进行绑定,对用户进行访问授权。

api对象

RBAC API 声明了四种 Kubernetes 对象分别是:

Role、ClusterRole、 RoleBinding和ClusterRoleBinding。

角色和集群角色()

RBAC角色或ClusterRole包含表示一组权限的规则,在RBAC API中,角色包含代表权限集合的规则。在这里,权限只有被授予,而没有被拒绝的设置。在Kubernetes中有两类角色,即普通角色和集群角色。可以通过Role定义在一个命名空间中的角色,或者可以使用ClusterRole定义集群范围的角色。一个角色只能被用来授予访问单一命令空间中的资源。

角色总是在特定范围内设置权限名称空间; 创建角色时,必须指定它所属的命名空间


ClusterRole 是一种非命名空间资源。资源具有不同的名称(Role 和 ClusterRole)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: test
rules:
- apiGroups: [""]  
resources: ["pods"]  # 资源对象
verbs: ["get", "watch", "list"] # 权限列表

以上是在“default”命令空间中定义了一个名为test的角色,此角色能够对在“default”命名空间中访问Pod


集群角色(ClusterRole)能够被授予如下资源的权限:

  • 集群范围的资源(类似于Node)

  • 非资源端点(类似于”/healthz”)

  • 集群中所有命名空间的资源(类似Pod)

下面是授予集群角色读取秘密字典文件访问权限的例子:

kind:ClusterRole
apiVersion:rbac.authorization.k8s.io/v1
metadata:
name:secret-reader
rules:
- apiGroups:[""]
resources:["secrets"] 
verbs:["get","watch","list"]

角色绑定和集群角色绑定(RoleBinding 和 ClusterRoleBinding)

角色绑定将角色中定义的权限授予一个用户或一组用户。它包含主体列表(用户、组或服务帐户)以及对所授予角色的引用。RoleBinding 授予特定命名空间内的权限,或者,RoleBinding 可以引用 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 的命名空间。

ClusterRoleBinding 授予集群范围内的访问权限

例在”default”命名空间中角色绑定将‘jane’用户和“pod-reader”角色进行了绑定,这就授予了“jane”能够访问“default”命名空间下的Pod。

apiVersion: rbac.authorization.k8s.io/v1
 namespace.
kind:RoleBinding
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),当主体对资源的访问仅限与本命名空间,这就允许管理员定义整个集群的公共角色集合,然后在多个命名空间中进行复用。

例下面的rolebinding引用了clusterRole角色,但是“dave”用户也仅仅只能读取“development”命名空间中的secrets资源,因为 RoleBinding 的命名空间(在其元数据中)是“development” 。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: development
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

集群角色可以被用来在集群层面和整个命名空间进行授权。要在整个集群中授予权限,可以使用 ClusterRoleBinding。以下 ClusterRoleBinding 允许组“manager”中的任何用户读取任何命名空间中的保密字典资源。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

创建绑定后,您无法更改它引用的 Role 或 ClusterRole。会收到验证错误。如果确实想要更改roleRef绑定,则需要删除绑定对象并创建一个替换对象。

这种限制有两个原因:

  1. 使roleRef不可变允许授予某人update对现有绑定对象的权限,以便他们可以管理主题列表,而无法更改授予这些主题的角色。

  2. 与不同角色的绑定是根本不同的绑定。要求删除/重新创建绑定以更改可确保roleRef 绑定中主题的完整列表旨在被授予新角色(而不是仅启用或意外修改 roleRef 而不验证所有现有主题)给定新角色的权限)。

命令kubectl auth reconcile

资源

我们都知道在k8s中,主要的资源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。另外,有些资源下面存在子资源,

例如:对 Pod 日志的请求如下所示:

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

下面的例子显示,“pod-and-pod-logs-reader”角色能够对“pods”和“pods/log”进行访问:

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

可以通过列表按某些请求的名称引用资源resourceNames。指定后,请求可以限制为资源的各个实例。

get这是一个将其主题限制为 only或updatea 的 示例配置映射表命名my-configmap:

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

不能通过资源名称来限制create或请求。deletecollection对于create,此限制是因为新对象的名称在授权时可能未知。如果您通过resourceName 进行限制list,则客户端必须在其或请求中watch包含与指定resourceName 匹配的字段选择器才能获得授权。

例如,metadata.namelistwatchkubectl get configmaps --field-selector=metadata.name=my-configmap

主体

RBAC授权中的主体可以是组,用户或者服务帐户。用户通过字符串表示,比如“alice”、 “test@example.com”等,具体的形式取决于管理员在认证模块中所配置的用户名。system:被保留作为用来Kubernetes系统使用,因此不能作为用户的前缀。组也有认证模块提供,格式与用户类似。

在角色绑定主体的例子:

名称为 “alice@example.com”用户:

subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io

对于名为 的组frontend-admins:

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

在kube-system命名空间中,名称为“default”的服务帐户:

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

在“qa”命名空间中,所有的服务帐户:

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

对于任何命名空间中的所有服务帐户:

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

对于所有经过身份验证的用户

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

对于所有未经身份验证的用户

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

所有用户

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

命令行工具

Kubernetes可以通过命令工具进行角色绑定。

  1. 在指定的命名空间中进行角色绑定:

  • “acme”命名空间中,将“admin”集群角色授予“test”用户

kubectl create rolebinding test-admin-binding --clusterrole=admin --user=test --namespace=acme
  • 在“acme”命名空间中,将“admin”集群角色授予“acme:myapp”服务帐户:

kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme

B.在整个集群中进行角色绑定

  • 在整个集群中,授予”cluster-admin”集群角色给”root”用户:

kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
  • 在整个集群中,授予”system:node”集群角色给“kubelet”用户:

kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
  • 在整个集群中,授予”view”集群角色给”acme:myapp”服务帐户:

kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp

服务帐户权限

默认情况下,RBAC策略授予控制板组件、Node和控制器作用域的权限,但是未授予“kube-system”命名空间外服务帐户的访问权限。这就允许管理员按照需要将特定角色授予服务帐户。默认 RBAC 策略向控制平面组件、节点和控制器授予范围权限,但不向命名空间之外的服务帐户授予任何权限kube-system(除了授予所有经过身份验证的用户的发现权限之外)

从最安全到最不安全的顺序,方法如下:

  • 授予角色给一个指定应用的服务帐户(最佳实践)

这要求在Pod规格中指定serviveAccountName,同时此服务帐户已被创建(通过API、kubectl create serviceaccount等)。

例如:

在my-namespace命名空间内,授予my-sa服务帐户view集群角色:

kubectl create rolebinding my-sa-view \
--clusterrole=view \
--serviceaccount=my-namespace:my-sa \
--namespace=my-namespace
  • 将角色授予命名空间中的“默认”服务帐户,如果应用程序未指定serviceAccountName,它将使用“默认”服务帐户。

注意 :授予“默认”服务帐户的权限可用于命名空间中未指定serviceAccountName

例如,在“my-namespace”命名空间内,授予”default”服务帐户“view”集群角色:

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

启用此功能意味着kube-system命名空间包含授予超级用户对集群 API 访问权限的 Secret

当前,在”kube-system“命名空间中,很多插件作为”default“服务帐户进行运行。为了允许超级用户访问这些插件,在“kube-system”命名空间中授予”cluster-admin“角色给”default”帐户。

kubectl create clusterrolebinding add-on-cluster-admin \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:default
  • 在一个命名空间中,授予角色给所有的服务帐户:

如果希望在一个命名空间中的所有应用都拥有一个角色,而不管它们所使用的服务帐户,可以授予角色给服务帐户组。

例如,在“my-namespace”命名空间中,将”view“集群角色授予“system:serviceaccounts:my-namespace“组:

kubectl create rolebinding serviceaccounts-view \
--clusterrole=view \
--group=system:serviceaccounts:my-namespace \
--namespace=my-namespace
  • 在整个集群中授予一个角色给所有的服务帐户(不推荐使用)

如果不想按照每个命名空间管理权限,可以在整个集群的访问进行授权。

例如,在整个集群层面,将”view“集群角色授予“sytem:serviceaccounts“:

kubectl create clusterrolebinding serviceaccounts-view \
--clusterrole=view \
--group=system:serviceaccounts
  • 在整个集群中授予超级用户访问所有的服务帐(强烈建议不要这样做)

这允许任何应用程序完全访问您的集群,并且还授予任何具有 Secrets 读取权限(或创建任何 Pod 的能力)的用户对集群的完全访问权限。

如果根本不关心分区权限,则可以向所有服务帐户授予超级用户访问权限。

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

EndpointSlices 和 Endpoints 的写访问权限(version 1.22-)

缓解  CVE-2021-25740

在 Kubernetes v1.22 之前创建的 Kubernetes 集群在聚合的“编辑”和“管理”角色中包含对 EndpointSlices(和 Endpoints)的写访问权限

如果需要保存可使用下面方式

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
  kubernetes.io/description: |-
    Add endpoints write permissions to the edit and admin roles. This was
    removed by default in 1.22 because of CVE-2021-25740. See
    https://issue.k8s.io/103675. This can allow writers to direct LoadBalancer
    or Ingress implementations to expose backend IPs that would not otherwise
    be accessible, and can circumvent network policies or security controls
    intended to prevent/isolate access to those backends.
    EndpointSlices were never included in the edit or admin roles, so there
    is nothing to restore for the EndpointSlice API.      
labels:
  rbac.authorization.k8s.io/aggregate-to-edit: "true"
name: custom:aggregate-to-edit:endpoints # you can change this if you wish
rules:
 - apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["create", "delete", "deletecollection", "patch", "update"]

宽松的 ABAC 策略

默认 RBAC 策略向控制平面组件、节点和控制器授予范围权限,但不向命名空间之外的服务帐户授予任何权限kube-system(除了授予所有经过身份验证的用户的发现权限之外)。

虽然更加安全,但这可能会破坏期望自动接收 API 权限的现有工作负载。以下是管理此转变的两种方法核心组件

1: 并行授权者

运行 RBAC 和 ABAC 授权程序,并指定包含旧版 ABAC 策略的策略文件

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

如果早期授权者(例如 Node)拒绝请求,则 RBAC 授权者会尝试授权 API 请求。如果 RBAC 也拒绝该 API 请求,则运行 ABAC 授权方。这意味着RBAC 或 ABAC 策略允许的任何请求都是允许的

一旦您向服务帐户授予角色并且工作负载正在运行并且服务器日志中没有 RBAC 拒绝消息,您就可以删除 ABAC 授权者

以下策略允许所有服务帐户充当集群管理员。容器中运行的任何应用程序都会自动接收服务帐户凭据,并且可以针对 API 执行任何操作,包括查看机密和修改权限。所以并不推荐次策略

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



原文作者:步步运维步步坑;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-10-08

  • 博文量
    100
  • 访问量
    51733