1 总览
client发起apiserver调用时,apiserver先认证(Authentication)用户,再给用户授权(Authorization),最后执行准入控制(Admission Control)
- 认证:鉴别发起请求的用户是否合法
- 授权:授予用户api请求权限,并鉴别用户访问的api请求是否合法
- 准入控制:一些额外的检查机制,用于做最后的拦截
2 认证
认证就是识别用户身份的过程
2.1 client证书
2.1.1 原理
基于CA根证书签名的双向数字证书认证
- client和server向CA机构申请证书
- client->server,server下发服务端证书,client利用证书验证server是否合法
- client发送客户端证书给server,server利用证书校验client是否合法
- client和server利用随机密钥加密消息,然后通信
2.1.2 操作
apiserver启动的时候通过--client-ca-file=XXXX
配置签发client证书的CA,当client发送证书过来时,apiserver使用CA验证,如果证书合法,提取Common Name字段作为用户名
2.1.3 优点
- 安全
2.1.4 缺点
- 使用稍复杂
- 无法撤销用户证书
2.2 静态Token文件
2.2.1 原理
生成一个长串token,并放入header发起http请求,apiserver依据token识别用户
2.2.2 操作
apiserver启动通过--token-auth-file=XXXXX
加载所有用户token,client请求的时候Header加上token即可
2.2.3 优点
- 简单
2.2.4 缺点
- 需要重启apiserver才能更新,不灵活
- 不安全
2.3 引导Token
保证token动态生成,但是该方案正在试验阶段,不太成熟
2.4 静态密码文件
2.4.1 原理
将[username:password]进行加密存入http request中的Header Authorization域,并发送给apiserver,apiserver依据这个域中的信息识别用户
2.4.2 操作
apiserver启动时通过参数--basic-auth-file=XXXX
指定用户信息的文件路径,client请求的时候Header带上base64(user:password)
即可
如果是通过kubectl,请参考,带上用户名密码,去除证书认证
kubectl --server=https://10.20.46.113:6443 --insecure-skip-tls-verify=true --username=xxx --password=xxx get nodes
2.4.3 优点
- 简单
2.4.4 缺点
- 需要重启apiserver才能更新,不灵活
- 不安全
2.5 Service Account Tokens
主要面向pod内部访问apiserver的鉴权方式。controller manager和apiserver会利用server端的私钥为每个pod创建一个token,并挂载到/run/secrets/kubernetes.io/serviceaccount/
路径下。pod在访问apiserver的时候带上该token就行
备注:当使用pod访问apiserver的安全端口时,只能采用这种方式
2.6 openId
基于OAuth2协议认证,受各大云提供商青睐
2.7 Webhook Token
按照规定k8s的接口规范,自定义token认证
2.8 keystone password
openstack提供的认证和授权方案,适合采用openstack体系搭建k8s的团队,处于试验阶段
2.9 匿名请求
当开启匿名请求时,所有没有被拒绝的请求都被认为是匿名请求,在授权阶段,这些请求都被统一处理
3 授权
授权就是授予用户请求权限,并鉴别用户的api请求是否合法的过程
目前支持的几种授权策略:
- AlwaysDeny:拒绝所有请求,用于测试
- AlwaysAllow:允许所有请求,k8s默认策略
- ABAC:基于属性的访问控制。表示使用用户配置的规则对用户请求进行控制
- RBAC:基于角色的访问控制
- Webhook:通过调用外部rest服务对用户授权
主要详解后三个策略
3.1 ABAC授权模式
启动ABAC,需要apiserver指定授权策略文件的路径和名字(--authorization-policy-file=XXXX),文件中的每一行代表一个策略对象
思路:用户发送请求到apiserver,用户识别用户所拥有的权限策略信息,并与authorization-policy-file中的策略一一匹配,如果至少一行匹配成功,该请求就通过了授权
添加新的ABAC策略,需要重启apiserver
3.2 Webhook授权模式
需要提供一个https接口,并按照指定规规范处理request和响应response
3.3 RBAC授权模式
在k8s中比较推荐的实现方式
优势:
- 对集群资源和非资源权限都有完整的覆盖
- 可以通过kubectl或者api来操作
- 可以运行时调整,无需重启apiserver
启动RBAC,需要apiserver启动参数加上-authorization-mode=RBAC
RBAC的四个资源对象:
- Role:一个角色就是一组权限的集合,拥有某个namespace下的权限
- ClusterRole:集群角色,拥有整个cluster下的权限
- RoleBinding:将Role绑定目标(user、group、service account)
- ClusterRoleBinding:将ClusterRoleBinding绑定目标
一个典型的映射关系
4 准入控制
经过认证和授权后,还需要经过多个准入控制器的审核,client到apiserver的请求才能成功得到相应
目前提供的准入控制器有这些(这些插件并不是都启用了):
- AlwaysAdmint:允许所有请求
- AlwaysPullImages:每次扩容都要重新下载镜像
- AlwaysDeny:禁止所有请求
- DenyExecOnPrivileged:弃用,拦截所有Privileged Container上执行命令的请求
- DenyEscalatingExec:拦截所有exec和attach到特权pod上的请求
- ImagePolicyWebhook:允许后端的Webhook程序完成准入控制的功能
- ServiceAccount:让ServiceAccount实现自动化
- SecurityContextDeny:让pod定义的SecurityContext失效,禁用容器设置的非安全访问权限
- ResourceQuota:拦截会让namespace超标的请求
- LimitRanger:限制namespace中所有pod请求的资源数量
- InitialResources:dev阶段,为没有限制资源的pod设置默认限制
- NamespaceLifecycle:禁止在不存在的namespace中创建资源;删除namespace会级联删除底下的所有pod、service等
- DefaultStorageClass:给未指定StorageClass或PV的PVC匹配默认StorageClass
- DefaultTolerationSeconds:给pod设置默认容忍时间
- PodSecurityPolicy:根据可用的PodSecuirityPolicy和pod的security context来进行安全控制
5 注意
- 通过curl来测试权限是否生效的时候,请确保使用高版本的curl(已知低版本7.19.7)
- 主要参考资料为【Kubernetes权威指南:从Docker到Kubernetes实践全接触(纪念版)】。官方文档略坑,很多东西只介绍了片段,很难基于它实践