kubernetes API Server 权限管理实践
API Server权限控制方式介绍
API Server权限控制分为三种:Authentication(身份认证)、Authorization(授权)、AdmissionControl(准入控制)。
身份认证:
当客户端向Kubernetes非只读端口发起API请求时,Kubernetes通过三种方式来认证用户的合法性。kubernetes中,验证用户是否有权限操作api的方式有三种:证书认证,token认证,基本信息认证。
证书认证
设置apiserver的启动参数:--client_ca_file=SOMEFILE ,这个被引用的文件中包含的验证client的证书,如果被验证通过,那么这个验证记录中的主体对象将会作为请求的username。
Token认证
设置apiserver的启动参数:--token_auth_file=SOMEFILE。 token file的格式包含三列:token,username,userid。当使用token作为验证方式时,在对apiserver的http请求中,增加 一个Header字段:Authorization ,将它的值设置为:Bearer SOMETOKEN。
基本信息认证
设置apiserver的启动参数:--basic_auth_file=SOMEFILE,如果更改了文件中的密码,只有重新启动apiserver使 其重新生效。其文件的基本格式包含三列:passwork,username,userid。当使用此作为认证方式时,在对apiserver的http 请求中,增加一个Header字段:Authorization,将它的值设置为: Basic BASE64ENCODEDUSER:PASSWORD。
授权:
在Kubernetes中,认证和授权是分开的,而且授权发生在认证完成之后,认证过程是检验发起API请求的用户是不是他所声称的那个人。而授权过程则 判断此用户是否有执行该API请求的权限,因此授权是以认证的结果作为基础的。Kubernetes授权模块应用于所有对APIServer的HTTP访 问请求(只读端口除外),访问只读端口不需要认证和授权过程。APIServer启动时默认将authorization_mode设置为 AlwaysAllow模式,即永远允许。
Kubernetes授权模块检查每个HTTP请求并提取请求上下文中的所需属性(例如:user,resource kind,namespace)与访问控制规则进行比较。任何一个API请求在被处理前都需要通过一个或多个访问控制规则的验证。
目前Kubernetes支持并实现了以下的授权模式(authorization_mode),这些授权模式可以通过在apiserver启动时传入参数进行选择。
--authorization_mode=AlwaysDeny
--authorization_mode=AlwaysAllow
--authorization_mode=ABAC
AlwaysDeny 模式屏蔽所有的请求(一般用于测试)。AlwaysAllow模式允许所有请求,默认apiserver启动时采用的便是AlwaysAllow模式)。 ABAC(Attribute-Based Access Control,即基于属性的访问控制)模式则允许用户自定义授权访问控制规则。
准入控制:
准入控制admission controller本质上为一段准入代码,在对kubernetes api的请求过程中,顺序为 先经过 认证 & 授权,然后执行准入操作,再对目标对象进行操作。这个准入代码在apiserver中,而且必须被编译到二进制文件中才能被执行。
在对集群进行请求时,每个准入控制代码都按照一定顺序执行。如果有一个准入控制拒绝了此次请求,那么整个请求的结果将会立即返回,并提示用户相应的error信息。
在某些情况下,为了适用于应用系统的配置,准入逻辑可能会改变目标对象。此外,准入逻辑也会改变请求操作的一部分相关资源。
作用
在kubernetes中,一些高级特性正常运行的前提条件为,将一些准入模块处于enable状态。总结下,对于kubernetes apiserver,如果不适当的配置准入控制模块,它就不能称作是一个完整的server,某些功能也不会正常的生效。
开启方式
在kubernetes apiserver中有一个参数:admission_control,他的值为一串用逗号连接的 有序的 准入模块列表,设置后,就可在对象被操作前执行一定顺序的准入模块调用。
模块功能
AlwaysAdmit:允许所有请求
AlwaysDeny:禁止所有请求,多用于测试环境。
DenyExecOnPrivileged:它会拦截所有想在privileged container上执行命令的请求。如果自己的集群支持privileged container,自己又希望限制用户在这些privileged container上执行命令,那么强烈推荐使用它。
ServiceAccount:这个plug-in将 serviceAccounts实现了自动化,如果想要使用ServiceAccount 对象,那么强烈推荐使用它。
关于serviceAccount的描述如下: 一个serviceAccount为运行在pod内的进程添加了相应的认证信息。当准入模块中开启了此插件(默认开启),那么当pod创建或修改时他会做一下事情:
如果pod没有serviceAccount属性,将这个pod的serviceAccount属性设为“default”;
确保pod使用de serviceAccount始终存在;
如果LimitSecretReferences 设置为true,当这个pod引用了Secret对象却没引用ServiceAccount对象,弃置这个pod;
如果这个pod没有包含任何ImagePullSecrets,则serviceAccount的ImagePullSecrets被添加给这个pod;
如果MountServiceAccountToken为true,则将pod中的container添加一个VolumeMount 。
SecurityContextDeny:这个插件将会将使用了 SecurityContext的pod中定义的选项全部失效。SecurityContext 在container中定义了操作系统级别的安全设定(uid, gid, capabilities, SELinux等等)。
ResourceQuota:它会观察所有的请求,确保在namespace中ResourceQuota对象处列举的container没有任何异常。 如果在kubernetes中使用了ResourceQuota对象,就必须使用这个插件来约束container。推荐在admission control参数列表中,这个插件排最后一个。
LimitRanger:他会观察所有的请求,确保没有违反已经定义好的约束条件,这些条件定义在namespace中LimitRange对象中。如果在kubernetes中使用LimitRange对象,则必须使用这个插件。
NamespaceExists:它会观察所有的请求,如果请求尝试创建一个不存在的namespace,则这个请求被拒绝。
推荐插件顺序
--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount, ResourceQuota
验证流程
1. API Server的初始化参数中设置了一些与权限认证相关的默认属性:
安全监听端口: SecurePort: 8443 读/写 权限,支持x509安全证书和x509私钥认证
非安全监听端口:InsecurePort: 8080 没有用户身份认证和授权,有读/写 权限
授权模式: AuthorizationMode: "AlwaysAllow",
准入控制插件: AdmissionControl: "AlwaysAdmit"
2. API Server启动时可以设置与权限认证相关的参数:
--insecure_port 自定义非安全监听端口
--secure_port 自定义安全监听端口
--tls_cert_file 设置安全证书文件
--tls_private_key_file 设置私钥文件
--cert_dir 安全证书文件和私钥文件被设置时,此属性忽略。安全证书文件和私钥文件未设置时,apiserver会自动为该
端口绑定的公有IP地址分别生成一个自注册的证书文件和密钥并将它们存储在/var/run/kubernetes下
--service_account_key_file 服务账号文件,包含x509 公私钥
--client_ca_file client证书文件
--token_auth_file token文件
--basic_auth_file 基本信息认证文件
--authorization_mode 授权模式
--ahtuorization_policy_file 授权文件
--admission_control 准入控制模块列表
--admission_control_config_file 准入控制配置文件
3. 解析入参,进行认证信息提取:
公 私钥文件设置:查看ServerAccountKeyFile是否已指定,如果未指定,并且TLSPrivateKeyFile被指定,则判断 TLSPrivateKeyFile中是否包含有效的RSA key,包含时,将TLSPrivateKeyFile作为ServerAccountKeyFile。
身份认证信息提取:从参 数设置的CSV文件中取出username,userID,password(或者token)封装成map结构,key为username,value 为三种属性的struct。从basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile(serviceAccountLookup) 中取user信息,得到一个验证信息的map数组。
授 权信息提取:读取设置的授权文件,解析字符串,返回授权信息数组。(包含 username,group,resource,read only,namespace)Make the "cluster" Kinds be one API group (minions, bindings,events,endpoints)。The "user" Kinds are another (pods,services,replicationControllers,operations)。
准入控制插件:获取所有插件名,返回准入控制接口(执行所有插件)
4. 将身份认证信息、授权信息、准入控制插件作为Master的配置,New Master。
5. 请求认证:
调apiserver的NewRequestAttributeGetter方法,从请求中提取授权信息,调用WithAuthorizationCheck方法(授权验证)。
调 用handler的NewRequestAuthenticator方法,Request中提取authencate信息,调用 AuthenticateRequest方法(对client certificates,token,basic auth分别有不同的验证方法)。
补充
身份认证:
token认证,请求时,在请求头中加入 Authorization:bearer token字符串。CSV文件中,三列分别为 token,username,userid。当CSV中有与请求的Authorization匹配行时,认证成功。
basic auth认证,请求时,在请求头中加入 Authorization:basic base64编码的user:password字符串。CSV文件中,三列分别为 password,username,userid。当CSV文件中有与请求的Ahtuorization匹配行时,认证成功。
证书校验:
API Server启动时,指定服务端数字证书和密钥(如果不指定,会在server启动时自动生成),指定客户端ca文件,server启动时,会解析ca文 件,遍历其中的cert,加入certpool。在Server的TLSConfig中指定认证模式:目前使用的是 RequestClientCert(不强制认证,无认证时不拒绝连接,允许其他认证),此外还有其他认证模式 requireAndVerifyClientCert(强制校验)。使用ListenAndServeTLS(将服务端数字证书和密钥作为参数)监听在 安全端口。
API Server权限控制操作(暂时未加入namespace)测试:
启动server:指定token验证文件、授权方式、授权文件
./_output/local/bin/linux/amd64/canary-apiserver --logtostderr=true --log-dir=/tmp --v=4 --etcd_servers=http://127.0.0.1:4001 --insecure_bind_address=127.0.0.1 --insecure_port=8088 --secure_port=6443 --kubelet_port=10250 --service-cluster-ip-range=10.1.1.0/24 --allow_privileged=true --runtime-config="api/v1beta3=false" --redis-addr=localhost:6379 --profiling=true --token_auth_file=token.csv --authorization_mode=ABAC --authorization_policy_file=abac.csv
Token文件内容:
abcdef,hankai,123456
abcdefg,hk,123457
abcd,admin,1234
abc,hhh,111
授权文件内容:
{“user”:”admin”}
{“user”:”hankai”,”readonly”:true}
{“user”:”hhh”,”resource”:”apps”}
{“user”:”hk”,”readonly”:true,”resource”:”namespaces”}
验证:admin(有读写所有resource的权限)
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcd" -k https://10.57.104.59:6443/api/v1/apps
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcd" -k https://10.57.104.59:6443/api/v1/namespaces
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcd" -d@'n1.json' -k https://10.57.104.59:6443/api/v1/namespaces
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcd" -d@'app_demo1.json' -k https://10.57.104.59:6443/api/v1/apps
验证 hankai (只有读权限GET)
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcdef" -d@'app_demo1.json' -k https://10.57.104.59:6443/api/v1/appsforbidden
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcdef" -d@'n1.json' -k https://10.57.104.59:6443/api/v1/namespaces forbidden
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcdef" -k https://10.57.104.59:6443/api/v1/namespaces
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcdef" -k https://10.57.104.59:6443/api/v1/apps
验证 hk (只有对namespaces的GET权)
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcdefg" -k https://10.57.104.59:6443/api/v1/apps
forbidden
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abcdefg" -khttps://10.57.104.59:6443/api/v1/namespaces
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcdefg" -d@'n1.json' -k https://10.57.104.59:6443/api/v1/namespaces forbidden
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abcdefg" -d@'app_demo1.json' -khttps://10.57.104.59:6443/api/v1/apps forbidden
验证hhh(拥有对apps的读写权)
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abc" -d@'app_demo1.json' -khttps://10.57.104.59:6443/api/v1/apps
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abc" -k https://10.57.104.59:6443/api/v1/apps
curl -X GET -H "Content-Type: application/json" -H "Authorization: bearer abc" -k https://10.57.104.59:6443/api/v1/namespaces
forbidden
curl -X POST -H "Content-Type: application/json" -H "Authorization: bearer abc" -d@'n1.json' -k https://10.57.104.59:6443/api/v1/namespaces
forbidden
注:后续只需要在abac.csv文件的每列中,指定namespace,就可以实现user对指定namespace的操作权限。
新增:TSL 客户端证书认证
使用自生成证书测试:使用openssl生成server.crt,server.key,ca.key,ca.crt。Server启动时,传入 --tls_cert_file=server.crt --tls_private_key_file=server.key --client_ca_file=ca.crt
./_output/local/bin/linux/amd64/canary-apiserver --logtostderr=true --log-dir=/tmp --v=4 --etcd_servers=http://127.0.0.1:4001 --insecure_bind_address=7.0.0.1 --insecure_port=8088 --secure_port=8442 --kubelet_port=10250 --service-cluster-ip-range=10.1.1.0/24 --allow_privileged=true --runtime-config="api/v1beta3=false" --redis-addr=localhost:6379 --profiling=true --tls_cert_file=server.crt --tls_private_key_file=server.key --client_ca_file=ca.crt --token_auth_file=token.csv --authorization_mode=ABAC --authorization_policy_file=abac.csv
请求时,通过-cacert 指定客户端证书 (可以通过修改opnessl的配置文件指定客户端证书的路径,或者浏览器中导入客户端证书) curl -X GET --cacert ca.crt -H "Content-Type: application/json" -H "Authorization: bearer abcd" -k https://10.57.104.59:6443/api/v1/apps 即可实现认证。
kubernetes API Server 权限管理实践的更多相关文章
- 资深专家深度剖析Kubernetes API Server第1章(共3章)
欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现.如果你对Kubernetes的内部实现机制比较 ...
- 深度剖析Kubernetes API Server三部曲 - part 1
欢迎来到深入学习Kubernetes API Server的系列文章,在本系列文章中我们将深入的探究Kubernetes API Server的相关实现.如果你对Kubernetes 的内部实现机制比 ...
- Kubernetes API server工作原理
作为Kubernetes的使用者,每天用得最多的命令就是kubectl XXX了. kubectl其实就是一个控制台,主要提供的功能: 1. 提供Kubernetes集群管理的REST API接口,包 ...
- 资深专家深度剖析Kubernetes API Server第2章(共3章)
欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...
- 深度剖析Kubernetes API Server三部曲 - part 2
欢迎来到深入学习Kubernetes API Server的系列文章的第二部分.在上一部分中我们对APIserver总体,相关术语及request请求流进行探讨说明.在本部分文章中,我们主要聚焦于探究 ...
- kubernetes API Server安全
用户访问API Server(以下简称Server),K8S的安全检查步骤:认证和授权. 认证解决用户是谁的问题,就是验证用户名密码;授权解决用户能做什么的问题,就是检查该用户是否拥有权限访问请求的资 ...
- 阿里云上万个 Kubernetes 集群大规模管理实践
点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 汤志敏,阿里 ...
- 资深专家深度剖析Kubernetes API Server第3章(共3章)
在本系列的前两部分中我们介绍了API Server的总体流程,以及API对象如何存储到etcd中.在本文中我们将探讨如何扩展API资源. 在一开始的时候,扩展API资源的唯一方法是扩展相关API源代码 ...
- 深度剖析Kubernetes API Server三部曲 - part 3
在本系列的前两部分中我们介绍了API Server的总体流程,以及API对象如何存储到etcd中.在本文中我们将探讨如何扩展API资源. 在一开始的时候,扩展API资源的唯一方法是扩展相关API源代码 ...
随机推荐
- scala 编程思想—学习笔记
方法 方法是打包在某个名字下的小程序.在使用方法时,也就是调用方法时就会执行 这个小程序.方法将一组活动组合起来并赋予一个名字,这就是组织程序的最基本方式. scala 中方法的基本形式为 def m ...
- 【 js 模块加载 】【源码学习】深入学习模块化加载(node.js 模块源码)
文章提纲: 第一部分:介绍模块规范及之间区别 第二部分:以 node.js 实现模块化规范 源码,深入学习. 一.模块规范 说到模块化加载,就不得先说一说模块规范.模块规范是用来约束每个模块,让其必须 ...
- hello Groovy
Groovy [rocky@www ~]$ curl -s get.sdkman.io 1. 下载 [rocky@www Downloads]$ wget https://dl.bintray.com ...
- css-扩展选择器
(1)关联选择器 <div><p>aaaaaaaaaaaa</p></div> * 设置div标签里面p标签的样式,嵌套标签里面的样式 div p{ b ...
- CSS3D动画制作一个3d旋转的筛子
希望这个demo能让大家理解CSS3的3d空间动画(其实是个假3D) 首先给一个3d的解剖图,x/y/z轴线轴线已经标出 下面附上添加特效的动画旋转 可以根据demo并参考上面解剖图进行理解 < ...
- CSS实现各类分栏布局
在CSS中,实现分栏布局有两种方法.第一种方法是使用四种CSS定位选项(absolute .static.relative和fixed)中的绝对定位(absolute positioning),它可以 ...
- 在生产环境中安全执行更新删除SQL脚本的技巧
今天在生产环境上解决问题,由于广发银行的管理制度是开发公司是不允许确生产环境的,所以我们只能把要更新的语句发给运营中心,由运营中心的投产人员执行,我们则在旁边看着:在他执行的时候发现了一个很有趣的技巧 ...
- 深度研究Oracle数据库临时数据的处理方法
在Oracle数据库中进行排序.分组汇总.索引等到作时,会产生很多的临时数据.如有一张员工信息表,数据库中是安装记录建立的时间来保存的.如果用户查询时,使用Order BY排序语句指定按员工编号来排序 ...
- sqlserver为数据库表增加自增字段
需求: 数据库为SQLServer.对已有的数据库表customer加一个序号字段,一次性对所有现存客户加上编号,并在新建客户时自动增加一个编号,数值自增1. 解决方法: 1. 复制表结构.把原 ...
- Ubunt 安装mysql
apt-get install mysql-client-core-5.6apt-get install mysql-client-5.6apt-get install mysql-server-5. ...