kubernetes API 访问控制之:授权

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes API 访问控制之:授权相关的知识,希望对你有一定的参考价值。

文章目录

API访问控制

可以使用kubectl、客户端库方式对REST API的访问,Kubernetes的普通账户和Service帐户都可以实现授权访问API。API的请求会经过多个阶段的访问控制才会被接受处理,其中包含认证、授权以及准入控制(Admission Control)等。如下图所示:

需要注意:认证授权过程只存在HTTPS形式的API中。也就是说,如果客户端使用HTTP连接到kube-apiserver,是不会进行认证授权的。所以说,可以这么设置,在集群内部组件间通信使用HTTP,集群外部就使用HTTPS,这样既增加了安全性,也不至于太复杂。


授权

Kubernetes使用API server授权API请求。它根据策略来评估所有请求属性,是否给于通过。

(Kubernetes使用API server,访问控制和依赖特定资源对象的策略由(Admission Controllers)准入控制器处理。)

当配置多个授权模块时,会按顺序检查每个模块,如果有任何模块授权通过,则继续执行下一步的请求。如果所有模块拒绝,则该请求授权失败(返回HTTP 403)。

Kubernetes只对以下的API请求属性进行检查:

user-认证期间提供的user字符串
group - 认证用户所属的组名列表
“extra”- 由认证层提供的任意字符串键到字符串值的映射
API- 指示请求是否为API resource
Request path- 到其他非request端点的路径,如/api或/healthz。
API request verb- API verbs get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用于请求resource。要确定resource API端点的请求verbs 。
HTTP request verb- HTTP verbs get,post,put,和delete用于非资源请求
Resource-被访问(仅用于resource请求)的resource的ID或名字- *对于使用resource的请求get,update,patch,和delete,必须提供resource名称。
Subresource- 正在访问的subresource (仅用于请求resource)
Namespace- 正在访问对象的命名空间(仅针对命名空间的请求资源)
API group- 正在访问的API组(仅用于请求资源)。空字符串指定核心API组。

策略中需要包含一个flag,来指定你的策略包含的哪种授权模块:

使用以下flags:

---authorization-mode=ABAC 基于属性的访问控制(ABAC)模式允许使用本地文件配置策略。
---authorization-mode=RBAC 基于角色的访问控制(RBAC)模式允许使用Kubernetes API创建和存储策略。
---authorization-mode=WebhookWebHook 是一种HTTP回调模式,允许使用远程REST管理授权。
---authorization-mode=AlwaysDeny 此flag 阻止所有请求。仅使用此flag进行测试。
---authorization-mode=AlwaysAllow 此标志允许所有请求。只有在不需要API请求授权的情况下才能使用此标志。
可以选择多个授权模块。如果其中一种模式是AlwaysAllow,则覆盖其他模式,并允许所有的API请求。

Node授权

Node授权是一种特殊授权模式,专门授权由kubelet访问的API请求。

Node授权器允许kubelet执行的API操作包括:

读:

services
endpoints
nodes
pods
secrets
configmaps
persistent volume claims and persistent volumes related to pods bound to the kubelet’s node

写:

Node和Node status(启用NodeRestriction准入插件限制kubelet仅修改当前的Node)
Pod和Pod status(启用NodeRestriction准入插件限制kubelet仅修改与当前绑定的pod)
events

Auth-related:

read/write access to the certificationsigningrequests API for TLS bootstrapping
the ability to create tokenreviews and subjectaccessreviews for delegated authentication/authorization checks

在以后的版本中,Node授权器支持添加或删除的权限。

为获得Node授权器的授权,kubelet需要使用system:nodes组中的用户名system:node:。

启用Node授权器方法:apiserver --authorization-mode=Node。

为了限制kubelets能够写入的API对象,可以启动–admission-control=…,NodeRestriction,…准入(admission)插件。


ABAC模式

基于属性的访问控制(ABAC)定义了访问控制范例,通过将属性组合在一起的策略来授予用户访问权限。ABAC策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。

使用ABAC模式指定策略文件:–authorization-policy-file=SOME_FILENAME。

文件格式是JSON, one JSON object per line。

每一行都是一个“policy 对象”,policy对象具有以下属性:

Versioning 属性:
    apiVersion,字符串类型; 有效值为“abac.authorization.kubernetes.io/v1beta1”。允许版本控制和对策略格式进行转换。
    kind,字符串类型:有效值为“Policy”。允许版本控制和对策略格式进行转换。
spec 属性:
    Subject-matching 属性:
        user,字符串类型;
        group,字符串类型;
    Resource-matching 属性:
        apiGroup,字符串类型; 一个API Group。
            例如: extensions
            通配符:*匹配所有API Group。
        namespace,字符串类型;一个(namespace)命名空间
            例如: kube-system
            通配符:*匹配所有资源请求。
        resource,字符串类型;  资源类型
            例如: pods
            通配符:*匹配所有资源请求。
    Non-resource-matching 属性:
        nonResourcePath,字符串类型; non-resource request paths。
            例如:/version 或 /apis
            通配符:
                * 匹配所有non-resource 请求。
                /foo/* matches all subpaths of /foo/
    readonly,boolean类型,如果为true,表示该策略仅用于操作get,list和watch。
    授权方法:
属性设置为"*"将匹配所有属性值。
检查属性的元组以匹配策略文件中的每个策略。如果有一行匹配了请求属性,则请求被授权(但可能会在稍后的认证中失败)。
要允许认证过的用户执行操作,请将Group属性设置"system:authenticated"。
要允许未认证的用户执行操作,请将Group属性设置"system:unauthenticated"。
要允许用户执行任何操作,请编写一个策略,使用apiGroup,namespace,resource和nonResourcePath属性设置为"*"

示例:

Alice对所有资源进行操作

"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": "user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"

Kubelet可以读取任何pod:

"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": "user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true

Kubelet可以读/写事件:

"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": "user": "kubelet", "namespace": "*", "resource": "events"

Bob可以在namespace“projectCaribou”中读取pod:

"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": "user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true

RBAC模式

基于角色的访问控制(“RBAC”)使用“rbac.authorization.k8s.io”API 组来实现授权控制,允许管理员通过Kubernetes API动态配置策略。

启用RBAC:

apiserver --authorization-mode=RBAC。

RBAC API声明了四个最高级别的类型,RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。

Role 和 ClusterRole

Role是一系列的权限的集合,例如一个Role可以包含读取 Pod 的权限和列出 Pod 的权限, ClusterRole 跟 Role 类似,但是可以在集群中全局使用。

Role只能授予单个namespace 中资源的访问权限。以下是Role“default”namespace 中的示例,用于授予对pod的访问权限:

kind: Role

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  namespace: default

  name: pod-reader

rules:

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

  resources: ["pods"]

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

ClusterRole授权 >= Role授予(与Role类似),但ClusterRole属于集群级别对象:

集群范围(cluster-scoped)的资源访问控制(如:节点访问权限)
非资源类型(如“/ healthz”)
所有namespaces 中的namespaced 资源(如 pod)

ClusterRole示例:

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  # "namespace" omitted since ClusterRoles are not namespaced

  name: secret-reader

rules:

- apiGroups: [""]

  resources: ["secrets"]

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

RoleBinding和ClusterRoleBinding

RoleBinding是将Role中定义的权限授予给用户或用户组。它包含一个subjects列表(users,groups ,service accounts),并引用该Role。RoleBinding在某个namespace 内授权,ClusterRoleBinding适用在集群范围内使用。

RoleBinding可以引用相同namespace下定义的Role。以下的RoleBinding在“default”namespace中将“pod-reader”Role授予用户“jane”。将允许“jane”在“default”namespace中读取pod权限。

# This role binding allows "jane" to read pods in the "default" namespace.

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1beta1

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。将允许管理员为整个集群定义一组通用Role,然后在不同namespace中使用RoleBinding引用。

# This role binding allows "dave" to read secrets in the "development" namespace.

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  name: read-secrets

  namespace: development # This only grants permissions within the "development" namespace.

subjects:

- kind: User

  name: dave

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: ClusterRole

  name: secret-reader

  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding可以用于集群中所有命名空间中授予权限。以下ClusterRoleBinding允许组“manager”中的任何用户在任何命名空间中读取secrets。

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  name: read-secrets-global

subjects:

- kind: Group

  name: manager

  apiGroup: rbac.authorization.k8s.io

roleRef:

  kind: ClusterRole

  name: secret-reader

  apiGroup: rbac.authorization.k8s.io

子资源的授权

大多数资源由name字符串的形式表示,例如“pod”。然而,一些Kubernetes API 涉及“子资源”,例如Pod的logs ,pod log endpoint 的URL:

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

在这种情况下,“pod”是namespace中资源,“log”是pod的子资源,这种情况要在RBAC角色中表示,可以使用斜杠来划分资源和子资源。如下例子:

kind: Role

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  namespace: default

  name: pod-and-pod-logs-reader

rules:

- apiGroups: [""]

  resources: ["pods", "pods/log"]

  verbs: ["get", "list"]

资源也可以通过resourceNames列表的某些请求的资源名称来引用。如下例子:

kind: Role

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

  namespace: default

  name: configmap-updater

rules:

- apiGroups: [""]

  resources: ["configmap"]

  resourceNames: ["my-configmap"]

  verbs: ["update", "get"]

需要注意如果设置了resourceNames,那么verbs不能指定为list、watch、create或deletecollection。

以上是关于kubernetes API 访问控制之:授权的主要内容,如果未能解决你的问题,请参考以下文章

kubernetes集群的认证授权准入控制

技术中台干货Kubernetes之RBAC授权控制

Kubernetes API 访问控制之认证鉴权准入控制的介绍

Kubernetes(k8s)集群安全机制之访问控制

K8s之认证,授权及准入控制

kubernetes 核心组件之 APIServer