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 日
如果觉得我的文章对你有用,请随意赞赏