RBAC:
角色(Role):基于角色的访问控制,基于角色完成权限的授予或者分配
许可(permission)
一个用户扮演一个角色,而角色拥有相对应的权限,所以用户也会拥有角色的所有权限
许可:对象列表(Objects)+操作(Operations)又被称为权限
定义权限:在K8S中有三类定义:

对象: k8s中绝大部分资源皆为对象; 对象列表: 顾名思义就是多个资源; 非对象资源:指的是一些非资源Url,

因此在K8S中所有的定义权限操作都是指在某个对象(Objects)中施加的某种行为(action),我们把这个操作叫做Operations。在一个对象上施加的所有操作组合起来称之为许可权限(Permissioons)然后在角色(Role)之上去授予这个角色(Role)拥有许可权限(Permissioons),因此如果想要实现基于角色的访问控制应该有用户(user)、 角色(Role)、许可权限(Permissioons)在基于角色的访问控制当中,可以简单抽象的理解为我们定义的用户对某些对象施加的某种操作action(verb)。官方语言是Subject(主语)对Object(对象)施加的某些操作action(verb)。

在基于角色访问控制中用户可以被分为两类:

User和Pod中的Service Account User Human User GET=> /api/v1/pods/pod1 HEAD=> /api/v1/pods/pod2 PUT=> /api/v1/pods/pod3 POST=> /api/v1/pods/pod4 PATCH=> /api/v1/services/svc1 DELETE=> ............ Pod Service Account

以上httpURL路径是举例省略了K8S中的一些参数,标准书写应该是:

/api/<GROUP>/<VERSION>/namespaces/<NAMESPACE_NAME>/<KIND>[/OBJECT_ID]/

因此在K8S之上有两类发出的动作,我们称之为主语,以上的GET、HEAD、PUT、POST.....称之为操作(verb),/api/v1/pods....称之为对象列表(Objects)或者一组对象 然后把操作(verb)和对象列表(Objects)
绑定到一起形成许可权限(permission),之后把许可权限(permission)授予到角色(Role)中,最后让用户扮演角色(Role)就完成了授权!
定义角色(Role):
许可权限(Permissioons)
对象列表(Objects)
角色绑定:Rolebinding User account OR Service account Role

意为用户或者Service扮演到角色(role)(User account OR Service account)而这个角色(role)拥有我们定义的权限(Permissioons)所以这个用户(User account)就拥有了这个角色的所有权限。
角色(Role)和Rolebinding主要是在名称空间级别(namespace),授予名称空间范围内的许可权限,除了role和rolebinding外还有ClusterRole(集群角色)、ClusterRoleBinding(集群角色绑定)
举例:
当前有两个名称空间分别为ns1、ns2,在名称空间ns1当中定义了一个角色名为role,假设当前有一个用户名为user1,通过rolebinding绑定到role,也就是user1扮演角色role,这时user1拥有role的所有权限,而user1当前拥有的权限一定只能在ns1名称空间有效
如果想拥有集群级别的权限只能通过ClusterRoleBinding(集群角色绑定)把user1和ClusterRole(集群角色)绑定到一起,也就是user1扮演ClusterRole(集群角色)故而实现集权权限的授予
在K8S中也可以使用RoleBinding(角色绑定)把user和ClusterRole(集群角色)绑定到一起,但是权限和上方例子一样,权限只能在某一个名称空间有效
此操作应用场景:
比如我想授权多个用户对当前名称空间拥有管理权限,这时需要使用user通过rolebinding来绑定ClusterRole(集群角色)。到第二个用户时,直接复用ClusterRole(集群角色)就可,无论什么情况下rolebinding只对当前namespace生效,Role不可复用,ClusterRole(集群角色)可复用
创建role:
语法格式:

kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]

示例:

kubectl create role pods-reader --verb=get,list,watch --resource=pods NAME:pods-reader --verb:动作,做什么操作,示例中是get,list,watch 分别是获取,列出,查看 --resource:资源类别,对什么资源进行操作,示例中是pods 意为可以操作当前namespace的所有pod

建议在示例后方加--dry-run和-o yaml 测试一下是否可行并输出到yaml中,以便以后使用和验证是否正确

kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: pods-reader rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch

如果想更改namespace,需要在metadata下添加namespace:NAMESPACE_NAME不指定就默认为default

验证创建是否正确:

kubectl describe role pods-reader Name: pods-reader Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"creationTimestamp":null,"name":"pods-reader","nam... PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch]

上面信息分别为Labels(标签),上面示例没有定义标签,所以此处标签显示<none>,当然没定义的可以直接忽略,只看我们定义的,Resources(资源类别)对应pods,Verbs(操作)对应get list watch,
证明配置正确,当然也可以定义一类资源中的某一个资源,Resource Names在yaml文件中resources下添加Resource Names并指定名称即可

限制资源范围时有三种方式:

第一:Resources(资源类别)意为对这一类别的所有资源进行操作 第二:Resource Names(子资源名称)意为对某一类别的资源中的某一个或者某些特定资源进行操作 第三:Non-Resource URLs(非资源URL)是一些不能够定义为对象的资源,在K8S中表示对某一些资源进行一些操作或者定义一些特殊操作的,这个不常用到,暂时不关心,知道有这个东西就好了

创建rolebinding:

语法格式:

kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname][--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]

示例:

kubectl create rolebinding qwx-reader-pods --user=qwx --role=pods-reader -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: qwx-reader-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pods-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: qwx

验证创建是否正确:

kubectl describe rolebinding qwx-reader-pods Name: qwx-reader-pods Labels: <none> Annotations: <none> Role: Kind: Role Name: pods-reader #绑定的role Subjects: Kind Name Namespace ---- ---- --------- User qwx #绑定的用户

查看rolebinding信息,刚才我们定义的用户qwx和绑定的role pods-reader是否正确
其中Subjects可以是用户名,组名和ServiceAccount。同时还可以指定namespace
创建clusterrole(集群角色):
语法格式:

kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--dry-run]

示例:

kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: cluster-reader rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch

示例的-o yaml可以去除,添加只是为了可以看到详细配置,结尾也可以添加--dry-run来测试是否语法正确

验证是否创建成功:

kubectl describe clusterrole cluster-reader Name: cluster-reader Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch]

需要验证qwx用户是否可以查看全集群Pods,上方示例中已经绑定了rolebinding,现在要通过绑定clusterrolebinding来绑定用户和role,只能把role给删掉然后绑定clusterrolebinding。

创建clusterrolebinding:
语法格式:

kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname][--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]

示例:

kubectl create clusterrolebinding qwx-read-all-pods --clusterrole=cluster-reader --user=qwx apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: creationTimestamp: null name: qwx-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: qwx

验证是否创建成功:

kubectl describe clusterrolebinding qwx-read-all-pods Name: qwx-read-all-pods Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: cluster-reader Subjects: Kind Name Namespace ---- ---- --------- User qwx

测试权限是否生效:
另开一个session,创建宿主机用户和新kubernetes用户,把root目录下的.kube复制到创建的宿主机家目录下,使用su - NOWUSERNAME 切换宿主机,kubectl config user-contest KUBEUSERNAME@kubernetes切换K8S用户 这样的操作只是方便测试

[qwx@master ~]$ kubectl get pods NAME READY STATUS RESTARTS AGE pod-sa-demo 1/1 Running 1 80d

能查到Pod证明权限生效成功

user通过rolebinding来绑定ClusterRole(集群角色):
因为上方示例已经绑定了clusterrolebinding,所以我们要先把clusterrolebinding删除

kubectl delete clusterrolebinding CLUSTERROLEBINDINGNAME

创建rolebinding绑定cluster-reader和qwx。

kubectl create rolebinding qwx-read-pods --clusterrole=cluster-reader --user=qwx --dry-run -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: qwx-read-pods #rolebindingNAME roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader #绑定的role subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: qwx #绑定的用户

如果在rolebinding中的matadata下添加namespace,表示只对这个namespace生效,默认是default,所以不添加就是只对default生效

检查role是否创建成功:

[root@master ~]# kubectl describe rolebinding qwx-read-pods Name: qwx-read-pods Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: cluster-reader Subjects: Kind Name Namespace ---- ---- --------- User qwx

在kubernetes中有一些内嵌的clusterrole(集群角色)
其中有一个名为admin的clusterrole可以用来设定用户为当前名称空间的管理员,用上方示例中的rolebinding绑定admin
示例:

kubectl create rolebinding ROLEBINDINGNAME --clusterrole=admin --user=NAME

上方已经创建了一个rolebinding,此处不用删除,因为default-ns-admin已经把我们创建的名为qwx-read-pods的rolebinding包含了,当然如果追求美观也可以删除掉,default-ns-admin是创建rolebinding书写的名字,关于clusterrole的admin配置的什么,可以使用kubectl get clusterrole admin -o yaml,进行查看。

在k8S中创建Pod会需要指定一个ServiceAccount,而Pod是通过ServiceAccount来和api通讯的,而有些Pod是需要有管理员权限的,例如flannel插件,查看flannel的yaml文件,会发现他的文件中
是用的ServiceAccount来进行授权的,通过clusterrolebinding来绑定clusterrole和ServiceAccount,从而使ServiceAccount拥有clusterrole权限

Kubernetes:认证、授权总结
在K8S中简单来讲API Server采用的是RESTful风格的接口,因此主要就是某个用户对某个对象执行了某些操作,同时不允许别的用户随意去访问我们的K8S因此有了认证, 用户账号

API Server: subject -->action-->object

认证有三种方式,第一种是token(承载令牌),第二种是tls(证书认证又称为SSL认证),第三种user/password(用户密码认证)。同时账号又分为两种第一种是UserAccount(用户帐户)UA,第二种是ServiceAccount(服务帐户)SA。

认证:

token,tls,user/password 账号:UserAccount ,ServiceAccount

授权:RBAC
RBAC工作逻辑:subject(主题)对object(客题)使用什么样的action(访问方法)

RBAC:subject -->action-->object

在kubernetes之上RBAC有四种标准的资源:

role(角色),rolebinding(角色绑定) clusterrole(集群角色),clusterrolebinding(集群角色绑定)

能够作为授权中的subject(主题)来使用的大概有三个主题:

subject(主题): user(用户) group(组) ServiceAccount(服务帐户)

同事也是定义role(角色)和clusterrole(集群角色)时的重要组件

object(对象): resource group resource non-resource Url

在role(角色)和clusterrole(集群角色)之上我们定义的能够对那些对象(object)进行那些操作(action)

action: get,list,watch,patch,delete,deletecollection...

而rolebinding(角色绑定)和clusterrolebinding(集群角色绑定)指明了那些主题(subject)可绑定到那些角色(role)之上。而role可以使用rolebinding(角色绑定)和clusterrolebinding(集群角色绑定)来绑定,clusterrole(集群角色)只能使用clusterrolebinding(集群角色绑定)来绑定。

最后修改:2023 年 06 月 09 日
如果觉得我的文章对你有用,请随意赞赏