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。