01、前言
众所周知,kubernetes API是kubernetes的核心组件,kubernetes API以REST接口的形式将Pods、Service、Deployment等信息定义为资源,而这些资源我们又是怎样操作它们的呢?在kubernetes 1.6之后社区逐渐使用RBAC的认证模式,下面将会详细介绍这种认证模式。
02、kubernetes的认证机制
1)如何访问kubernetes API
使用者可以通过kubectl客户端、各个代码语言的客户端库程序或者通过发送REST请求来访问kubernetes API接口。
2)Kubernetes API概览
Kubernetes API是标准的REST格式,kubernetes中所有资源的操作都是通过API操作完成的。为了消除字段或者重构,kubernetes支持多个API版本,每个版本都有不同的路径,如/api/v1 or /apis/extensions/v1beta1,而不同的资源在不同的API路径中,比如ingress在v1bea1中而不是在v1中。不同的API版本也有不同的安全级别。如Alpha版本可能存在bug,同时默认情况下有些功能是禁止的,Bata版本是稳定的经过测试的,所以大家在调用kubernetes API时要注意使用的版本。
3)访问kubernetes API的过程
如图所示,首先访问kubernetes API的主体大致分为两类:一类是User Account,以用户的身份访问API,另一类是Service Account,主要是kubernetes中的服务程序访问APi接口,比如创建calico网络插件、coredns等时会先创建对应的Service Account。Kubernetes API 为了保证传输层安全端口运行在6443上,同时使用证书认证,在构建kubernetes集群时,会将认证信息写入到$USER/.kube/config中。
Authentication认证,在TLS第一次建立时,就会开始完成认证操作步骤。身份认证的模块包括客户端证书、密码、Token令牌、JWT Tokens、Bootstrap Tokens等,如果请求认证不能通过,kubernetes会返回HTTP 401状态码。虽然kubernetes使用username作为认证主体,但是不会写入存储中。
Authorization授权,当请求通过认证之后,会经过授权操作步骤。一次授权操作必须包括请求者的用户名、请求的操作动作和受影响的对象,可以理解为语文语法的主谓宾结构,请求主体、有哪种权限操作、操作对象又是什么。Kubernetes支持多种授权模式,比如ABAC模式、RBAC模式、Webhook模式等。如果授权没有通过,会返回HTTP 403状态码。
Admission control准入控制,准入控制作为Authorization授权模式的补充操作,可以对请求对象实现创建、删除、更新操作,通过准入控制可以更灵活的操作整个认证过程。在完成上述操作后,请求信息会写入对象存储中。值得注意的是,在传统的3A认证中,最后一个为Accounting记账或审计,kubernetes面向的是云原生不是一个云计算厂商,不会实现记账系统的模块,但是可以通过准入控制来完成上述的功能。
03、kubernetes之RBAC模式
1)RBAC模式概述
RBAC的全称是Role Base Access Control,既是基于角色的访问控制,它是一种灵活的访问控制机制,可以将用户作为角色,通过角色绑定完成资源的权限分配。由于kubernetes API本身不需要有任何改动,所以在权限控制和重新定义时无需重启API server端。
RBAC使用rbac.authorization.k8s.io这个API Group,通过这个API Group可以允许用户动态配置策略,在kubernetes 1.8之后RBAC模式的API版为rbac.authorization.k8s.io/v1
在apiserver启动时可以通过--authorization-mode=RBAC启用RBAC模式
上图为RBAC模式的认证结构,在指定的namespace下,用户主体通过角色绑定将API资源赋予相应的权限。
2)Role和ClusterRole角色和集群角色
在RBAC的API中,Role包含一组权限的规则,它可以像Role作用于单个namespace,也可以像ClusterRole一样作用于整个集群中。
Role和ClusterRole示例对比如下:
Role会指定namespace,然后赋予pods资源类型相应的get、watch、list权限
ClusterRole不需要指定namespace,因为它作用于整个namespace上。ClusterRole与Role的主要区别有:
可以针对集群资源(如nodes)
可以作用于非资源类型endpoints(如/healthz)
可以作用于整个namespace上(如kubectl get pods --all-namespaces上的资源)
3)RoleBinding和ClusterRoleBinding绑定角色和集群角色
RoleBinding或ClusterRoleBinding主要的作用是将主体(如user、serviceaccount等)与Role或ClusterRole进行绑定,这样就可以使得user、group或serviceAccount主体具有指定角色的权限规则。
如图所示,subjects为作用的主体可以为user或者serviceAccount,roleRef代表与Role或者ClusterRole进行绑定,这样jane用户就具有pod-reader对应的权限了。
需要注意的是,如果想通过更改当前Role或者ClusterRole中的规则来改变权限规则,这样是错误的,可以通过删除现有规则重新绑定的方法来实现。可以使用kubectl auth命令更新现有规则。
可以使用kubectl get role, rolebinding -n kube-system查看现有集群role使用情况
4)Aggregated ClusterRoles聚会类ClusterRoles
在1.9版本之后,ClusterRoles可以使用aggregationRule规则,将具有相同标签的规则作为统一主体完成授权操作。
通过aggregationRule选项,将匹配matchLabels中包含monitoring标签的规则。
可以通过这种标签聚会的方式,将多个ClusterRole聚会成统一的规则策略。
04、RBAC模式下的实战操作
1)创建用户凭证
使用openssl创建用户私钥,如下所示:
#openssl genrsa -out liyinda.key 2048
为用户私钥创建一个证书签名请求文件,CN代表用户名,O代表组
#openssl req -new -key liyinda.key -out liyinda.csr -subj "/CN=liyinda/O=liyinda"
通过签名请求文件向kubernetes的CA生成证书文件crt,有效期为365天
#openssl x509 -req -in liyinda.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out liyinda.crt -days 365
查看当前目录下是否生成证书文件
#liyinda.crt liyinda.csr liyinda.key
通过创建好的证书文件和私钥文件生成kubernetes集群凭证
#kubectl config set-credentials liyinda --client-certificate=liyinda.crt --client-key=liyinda.key
通过创建好的凭证为kubernetes生成上下文context
#kubectl config set-context liyinda-context --cluster=kubernetes --namespace=kube-system --user=liyinda
查看kubernetes集群凭证信息
#kubectl config view
使用创建好的用户凭证使用kubectl命令查看默认namespace下的pods,可以发现该用户没有对应权限。
#kubectl get pods ——context=liyinda-context
2)创建Role角色
创建user之后,我们定义一个Role的yaml文件来定义权限规则,如下所示:
3)创建RoleBinding绑定角色
创建完Role规则后,就可以将user和Role规则进行绑定,如下所示:
#kubectl apply-f rolebinding.yaml
4)验证权限
使用之前创建好的上下文来查看名称为kube-system的namespace上的pods,可以看到已经添加对应权限。
#kubectl get pods——context=liyinda-context ——namespace=kube-system