一、客户端身份认证
Kubernetes集群提供三种客户端身份认证
- HTTPS:基于CA根证书签名的双向数字证书认证方式
- HTTP TOKEN:根据特殊的TOKEN来识别合法用户
- HTTP BASE:根据用户名+密码来进行认证
1.1、HTTPS
要使用https,则需要一个CA证书,这个证书可以购买第三方可信任的,也可以内部自搭,内部自搭的是不可信任的CA。
其中CA证书认证大概包括以下步骤:
1、服务端向CA申请证书,CA下发证书和私钥
2、客户端向CA申请证书,CA下发证书和私钥
3、客户端向服务端申请访问,服务端下发数字证书给客户端,数字证书中包含公钥信息
4、客户端验证数字证书,发送一个随机字符串和自己的公钥证书给服务端,服务端用自己的私钥加密随机字符串再发给客户端,客户端用公钥去解密,查看是否是自己发的随机字符串
4.1、用客户端的私钥加密一段随机字符串
4.2、将加密后的随机字符串和自己的公钥发送给服务端
4.3、服务端收到客户端发送过来的信息,先用客户端公钥解密信息
4.4、将解密的信息用服务端的私钥进行加密发送给客户端
4.5、客户端收到信息后用服务端的公钥对其进行解密
4.6、验证解密后的内容是否是发送过去的随机字符串
5、验证通过后就会生成一个加密算法和密钥,用于后面的加密解密
以上是双向认证,如果是单项认证,客户端则不需要CA机构签发证书,然后通过对称密钥进行通信。
1.2、HTTP TOKEN
Token是一个特殊的形式编码并且难以被模仿的字符串,每个Token对应一个用户名,然后存储在API Server能访问到的文件中,客户端在访问的时候需要在请求头里添加Token,这样API Server通过请求头里的Token和存储在文件中的Token进行比较来确定访问是否合法。
1.3、HTTP BASE
这种认证方式是把”用户名+冒号+密码”用BASE64算法进行编码后的字符串放在HTTP Request中的Header Authorization域里发送给服务端,服务端在收到后进行解码,获取用户名及密码,然后进行用户身份鉴权。
二、访问权限授权
当上面的身份认证结束后,就会到用户授权流程。即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。简单地说,授权就是授予不同的用户不同的访问权限。API Server目前支持以下几种授权策略(通过API Server的启动参数“—authorization-mode”设置)。
- ◎ AlwaysDeny:表示拒绝所有请求,一般用于测试。
- ◎ AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
- ◎ ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
- ◎ Webhook:通过调用外部REST服务对用户进行授权。
- ◎ RBAC:Role-Based Access Control,基于角色的访问控制。
- ◎ Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
API Server在接收到请求后,会读取该请求中的数据,生成一个访问策略对象,如果在该请求中不带某些属性(如Namespace),则这些属性的值将根据属性类型的不同,设置不同的默认值(例如,为字符串类型的属性设置一个空字符串;为布尔类型的属性设置false;为数值类型的属性设置0)。然后将这个访问策略对象和授权策略文件中的所有访问策略对象逐条匹配,如果至少有一个策略对象被匹配,则该请求被鉴权通过,否则终止API调用流程,并返回客户端的错误调用码。
2.1、ABAC
ABAC:Attribute-Based-Access Control,基于 属性 的权限认证。如果使用了这种模式,需要指定授权策略文件的路径和名称(—authorization-policy-file=SOME_FILENAME),授权策略文件里的每一行都以一个Map类型的JSON对象进行设置,这被称为“访问策略对象”。
spec指详细的策略设置,包括主题属性、资源属性、非资源属性这三个字段,如下所述。
(1)主体属性
- ◎ user(用户名):字符串类型,该字符串类型的用户名来源于Token文件(—token-auth-file参数设置的文件)或基本认证文件中用户名称段的值。
- ◎ group(用户组):在被设置为“system:authenticated”时表示匹配所有已认证的请求,在被设置为“system:unauthenticated”时表示匹配所有未认证的请求。
(2)资源属性
- ◎ apiGroup(API组):字符串类型,表明匹配哪些API Group,例如extensions或*(表示匹配所有API Group)。
- ◎ namespace(命名空间):字符串类型,表明该策略允许访问某个Namespace的资源,例如kube-system或*(表示匹配所有Namespace)。
- ◎ resource(资源):字符串类型,API资源对象,例如pods或*(表示匹配所有资源对象)。
(3)非资源属性
- ◎ nonResourcePath(非资源对象类路径):非资源对象类的URL路径,例如/version或/apis,表示匹配所有非资源对象类的请求路径,也可以设置为子路径,/foo/表示匹配所有/foo路径下的所有子路径。
- ◎ readonly(只读标识):布尔类型,当它的值为true时,表明仅允许GET请求通过。
其算法为:在API Server收到请求之后,首先识别出请求携带的策略对象的属性,然后根据在策略文件中定义的策略对这些属性进行逐条匹配,以判定是否允许授权。如果有至少一条匹配成功,那么这个请求就通过了授权(不过还是可能在后续其他授权校验中失败)。
2.2、Webhook
Webhook定义了一个HTTP回调接口,实现Webhook的应用会在指定事件发生时,向一个URL地址发送(POST)通知信息。启用Webhook授权模式后,Kubernetes会调用外部REST服务对用户进行授权。
Webhook模式用参数—authorization-webhook-config-file=SOME_FILENAME来设置远端授权服务的信息。配置文件使用的是kubeconfig文件格式。
2.3、RBAC
RBAC:Role-Based Access Control,基于角色的访问控制。
相对于其他访问控制方式,新的RBAC具有如下优势。
- ◎ 对集群中的资源和非资源权限均有完整的覆盖。
- ◎ 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作。
- ◎ 可以在运行时进行调整,无须重新启动API Server。
要使用RBAC授权模式,需要在API Server的启动参数中加上—authorization-mode=RBAC。
RBAC引入了4个新的顶级资源对象: Role 、 ClusterRole 、 RoleBinding和ClusterRoleBinding
2.3.1、Role
Role只能针对命名空间。
其资源对象中rules部分就是定义权限部分,其参数如下:
- apiGroups:支持的API组列表,例如“apiVersion: batch/v1”“apiVersion:extensions:v1beta1”“apiVersion: apps/v1beta1”等,详细的API组说明参见第9章的说明。
- resources:支持的资源对象列表,例如pods、deployments、jobs等。
- verbs:对资源对象的操作方法列表,例如get、watch、list、delete、replace、patch等
2.3.2、ClusterRole
ClusterRole除了具有和角色一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权。
- 集群范围的资源,例如Node。
- 非资源型的路径,例如“/healthz”。
- 包含全部命名空间的资源,例如pods。
2.3.3、RoleBinding
作用于命名空间的角色绑定,可以绑定Role,也可以绑定ClusterRole,如果绑定了ClusterRole,也仅能在绑定的命名空间下发挥作用,一种常见的做法是集群管理员为集群范围预先定义好一组ClusterRole,然后在多个命名空间中重复使用这些ClusterRole。
2.3.4、ClusterRoleBinding
集群范围内的角色绑定,作用于整个集群。
如果一个应用没有指定serviceAccountName,则会使用名为default的Service Account。注意,赋给Service Account“default”的权限会让所有没有指定serviceAccountName的Pod都具有这些权限。
2.3.4、自动恢复
自动恢复从Kubernetes 1.6版本开始引入。
每次启动时,API Server都会更新默认的集群角色的缺失权限,也会刷新在默认的角色绑定中缺失的主体,这样就防止了一些破坏性的修改,也保证了在集群升级的情况下相关内容能够及时更新。
如果不希望使用这一功能,则可以将一个默认的集群角色或者角色绑定的Annotation注解“rbac.authorization.kubernetes.io/autoupdate”值设置为false。
策略可以并行认证,比如如下设置:
--authorization-mode=RBAC,ABAC
这样首先会用RBAC进行鉴权,如果RBAC鉴权失败就会用ABAC进行鉴权,只要满足两者其中一个即可。
三、准入控制
Admission Control配备了一个准入控制器的插件列表,发送给API Server的任何请求都需要通过列表中每个准入控制器的检查,检查不通过,则API Server拒绝此调用请求。此外,准入控制器插件能够修改请求参数以完成一些自动化任务,比如ServiceAccount这个控制器插件。
可配置的准入插件有:
插件 | 用途 |
---|---|
AlwaysPullImages | 在启动容器之前总是尝试重新下载镜像 |
DefaultStorageClass | 会关注PersistentVolumeClaim资源对象的创建,如果其中没有包含任何针对特定Storage class的请求,则为其指派指定的Storage class |
DefaultTolerationSeconds | 针对没有设置容忍node.kubernetes.io/not-ready:NoExecute或者node.alpha.kubernetes.io/unreachable:NoExecute的Pod,设置5min的默认容忍时间。 |
DenyEscalatingExec | 拦截所有exec和attach到具有特权的Pod上的请求 |
EventReateLimit | 用于应对事件密集情况下对API Server造成的洪水攻击 |
ExtendedResourceToleration | 该控制器能够自动为申请这些特别资源的Pod加入Toleration定义,无须人工干预 |
ImagePolicyWebhook | 允许后端的一个Webhook程序来完成admissioncontroller的功能,ImagePolicyWebhook需要使用一个配置文件定义后端Webhook的参数 |
Initializers | 用于为动态准入控制提供支持,通过修改待创建资源的元数据来完成对该资源的修改 |
LimitPodHardAntiAffinityTopology | 该插件启用了Pod的反亲和性调度策略设置,在设置亲和性策略参数requiredDuringSchedulingRequiredDuringExecution时要求将topologyKey的值设置为“kubernetes.io/hostname”,否则Pod会被拒绝创建 |
LimitRanger | 这个插件会监控进入的请求,确保请求的内容符合在Namespace中定义的LimitRange对象里的资源限制 |
MutatingAdmissionWebhook | 变更符合要求的请求的内容,Webhook以串行的方式顺序执行 |
NamespaceAutoProvision | 检测所有进入的具备命名空间的资源请求,如果其中引用的命名空间不存在,就会自动创建命名空间 |
NamespaceExists | 检测所有进入的具备命名空间的资源请求,如果其中引用的命名空间不存在,就会拒绝这一创建过程 |
NamespaceLifecycle | 如果尝试在一个不存在的Namespace中创建资源对象,则该创建请求将被拒绝 |
NodeRestriction | 该插件会限制kubelet对Node和Pod的修改行为 |
OnwerReferencesPermissionEnforcement | 在该插件启用后,一个用户要想修改对象的metadata.ownerReferences,就必须具备delete权限。该插件还会保护对象的metadata.ownerReferences[x].blockOwnerDeletion字段,用户只有在对finalizers子资源拥有update权限的时候才能进行修改 |
PodNodeSelector | 该插件会读取命名空间的annotation字段及全局配置,来对一个命名空间中对象的节点选择器设置默认值或限制其取值 |
PersistentVolumeClaimResize | 该插件实现了对PersistentVolumeClaim发起的resize请求的额外校验 |
PodPreset | 该插件会使用PodSelector选择Pod,为符合条件的Pod进行注入 |
PodSecurityPolicy | 在创建或修改Pod时决定是否根据Pod的security context和可用的PodSecurityPolicy对Pod的安全策略进行控制 |
PodTolerationRestriction | 该插件首先会在Pod和其命名空间的Toleration中进行冲突检测,如果其中存在冲突,则拒绝该Pod的创建 |
Priority | 使用priorityClassName字段来确定优先级,如果没有找到对应的Priority Class,该Pod就会被拒绝 |
ResourceQuota | 用于资源配额管理目的,作用于Namespace |
SecurityContextDeny | 这个插件将在Pod中定义的SecurityContext选项全部失效 |
ServiceAccount | 将ServiceAccount实现了自动化 |
StorageObjectInUseProtection | 会在新创建的PVC或PV中加入kubernetes.io/pvc-protection或kubernetes.io/pv-protection的finalizer。如果想要删除PVC或者PV,则直到所有finalizer的工作都完成,删除动作才会执行 |
ValidatingAdmissionWebhook | 该插件会针对符合其选择要求的请求调用校验Webhook |
在API Server上设置参数即可定制我们需要的准入控制链,如果启用多种准入控制选项,则建议设置:在Kubernetes 1.9及之前的版本中使用的参数是—admission-control,并且其中的内容是顺序相关的;在Kubernetes 1.10及之后的版本中,该参数为—enable-admission-plugins,并且与顺序无关。