打赏 jQuery火箭图标返回顶部代码

RBAC

RBAC:Role-Based Access Control,基于角色的访问控制

Kubernetes中的所有API对象都保存在Etcd中的,而对这些API操作都是通过kube-apiserver来实现的,这是因为需要kube-apiserver来帮我们完成授权,而在Kubernetes中完成授权的机制就是RBAC。其中RBAC中的基本概念为:
  1. Rule:规则,一组属于不同API Group的操作集合;
  2. Role:角色,用于定义一组对Kubernetes API对象操作的一组规则,作用于当个namespace;
  3. ClusterRole:集群角色,该角色不受namespace的限制;
  4. Subject:被作用者,也就是规则作用的对象;
  5. RoleBinding:将角色和被作用者进行绑定,作用于当个namespace;
  6. ClusterRoleBinding:将集群角色和作用者进行绑定,不受namespace限制;

一、Role和RoleBinding

Role本身就是一个Kubernetest API对象,其定义如下:role-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
  name: role-demo
  namespace: devops
rules:
- apiGroups: [""]
  resources: ["pods", "deployment"]
  verbs: ["creat", "delete", "watch", "list", "get"]
其意义为:它允许被作用者在devops的namespace中对pod和deployment有creat,delete,watch,list,get操作。注意,其只对devops的namespace有效,在这里的namespace不同于我们docker中的namespace,这里的namespace是kubernetes中的逻辑管理单位,不同的namespace的API对象,在通过kubectl命令进行操作的时候是相互隔离的,这种隔离仅限逻辑上的隔离,并不会提供任何实际的隔离或者多租户能力。 上面就是对Role对象的定义,可以通过kubectl explain role来获取更多帮助。现在角色已经指定,那么Subject该如何指定呢?这就要通过RoleBinding来实现。 RoleBinding也是Kubernetes API对象,我们为joker用于绑定Role角色,定义如下:joker-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: joker-rolebinding
  namespace: devops
subjects:
- kind: User
  name: joker
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: role-demo
  apiGroup: rbac.authorization.k8s.io
这就给joker用户和role-demo的Role建立了绑定关系,其中joker这个User只是一个授权系统中的逻辑概念,它需要通过外部认证服务,比如Keystone,或者直接给API Server指定一个用户名,密码文件。 上面的YAML文件中其中一个重要的字段是Subjects字段,它定义"被作用者",其中的kind表示被作用者的类型,其有以下三种类型:
  • User:用户,这是由外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表,对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理。
  • Group:组,这是用来关联多个账户,集群中有一个默认的组,比如cluster-admin。
  • ServiceAccount:服务帐号,通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到 ServiceAccount。
 另外一个重要字段是roleRef,它定义RoleBing对象可以直接通过Role的名字来引用我们定义的Role对象,从而定义被作业者和角色之间的绑定关系。 Role和RoleBinding的作用范围仅限单个namespace,而对于集群来说就要使用ClusterRole和ClusterRuleBinding了。 

二、ClusterRole和ClusterRoleBinding

ClusterRole和ClusterRoleBinding的定义与Role和RoleBinding一样,只不过它们的定义中没有namespace字段而已,如下:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-role-demo
rules:
- apiGroups: [""]
  resources: [""]
  verbs: ["watch", "list", "get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: joker-clusterrolebinding
subjects:
- kind: User
  name: joker
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-role-demo
  apiGroup: rbac.authorization.k8s.io
上面定义的就是joker这个用户对所有namespace里的Pod都有watch,list,get的操作权限。如果要定义所有权限,可以将verbs字段定义如下:
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
 类似的在Role和ClusterRole对象中的rules字段也可以更加细致化,比如要对某一个具体的对象进行操作,如下:
rules:
- apiGroups: [""]
  resources: ["configMap"]
  resourceName: ["myconfig"]
  verbs: ["get"]
这条规则定义被作用者只对名字为myconfig的configMap对象有get权限。 上面我们都使用Subjects中User类型得用户功能,但是在实际中我们很少使用,而是经常使用另外一个内置用户:ServiceAccount,下面对ServiceAccount进行介绍。 

三、ServiceAccount

Service Account也是一种账号,但它并不是给Kubernetes集群的用户(系统管理员、运维人员、租户用户等)用的,而是给运行在Pod里的进程用的,它为Pod里的进程提供了必要的身份证明。 我们通过一个例子来了解ServiceAccount的授权过程。1、首先定义一个ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: devops
  name: sa-demo
一个简单的ServiceAccount只需要简单的namespace和name即可。 2、编写RoleBinding的YAML文件来为这个ServiceAccount分配权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-rolebinding
  namespace: devops
subjects:
- kind: ServiceAccount
  name: sa-demo
  namespace: devops
roleRef:
  kind: Role
  name: role-demo
  apiGroup: rbac.authorization.k8s.io
然后我们创建上面定义的YAML文件,查看创建完成后的信息:

[root@master rbac]# kubectl describe sa sa-demo -n devops 
Name:                sa-demo
Namespace:           devops
Labels:              <none>
Annotations:         kubectl.kubernetes.io/last-applied-configuration:
                       {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"sa-demo","namespace":"devops"}}
Image pull secrets:  <none>
Mountable secrets:   sa-demo-token-bh5t6
Tokens:              sa-demo-token-bh5t6
Events:              <none>

我们可以看到Kubernetes会自动创建一个Secret对象,这个Secret对象就是引用sa-demo的ServiceAccount对象与API Server进行交互的授权文件。它的内容一般是证书文件或者密码,以Secret对象的形式保存在Etcd中。 然后我们创建一个Pod,来使用ServiceAccount进行权限管理,如下:pod-sa-demo.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: devops
spec:
  serviceAccountName: sa-demo
  containers:
  - name: pod-sa-demo
    image: nginx
    imagePullPolicy: IfNotPresent
 然后创建这个Pod,查看Pod的信息:

kubectl describe pod pod-sa-demo -n devops 

我们可以看到ServiceAccount的Secret对象自动挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount目录。我们进入容器查看:

[root@master rbac]# kubectl exec -it pod-sa-demo -n devops -- /bin/bash
root@pod-sa-demo:/# ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt  namespace  token
其中ca,crt就是用来访问API Server的。 如果一个Pod在定义时没有指定spec.serviceAccountName属性,则系统会自动为其赋值为default,即大家都使用同一个Namespace下的默认Service Account。 Subjects的kind类型除了User,ServiceAccount之外,还有一个Group,就是一组用户的意思。如果你为Kubernetes配置了外部认证服务的话,这个用户组就由外部认证服务提供。而对于Kubernetes内置用户ServiceAccount来说,其也有用户和用户组的概念,其中对于一个ServiceAccount,其在Kubernetes中对应的用户是:
system:serviceaccount:<ServiceAccount名字>
 而对于其用户组是:
system:serviceaccounts:<Namespace名字>
 比如我们定义下面这个RoleBinding:
subjects:
- kind: Group
  name: system:serviceaccounts:devops
  apiGroup: rbac.authorization.k8s.io
这就意味着Role这个角色的权限规则作用与devops的namespace中的所有ServiceAccount。 再比如:
subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io
这就意味着Role这个角色规则作用与整个集群的所有ServiceAccount。 kubernetes已经内置了许多ClusterRole,以system:开头,可以用kubectl get clusterrole查看。 另外,Kubernetes还提供了四个预先定义好的ClusterRole来供用户直接使用,它们是:
  • cluster-admin:超管
  • admin:普通管理权限
  • edit:修改权限
  • view:只读权限
 我们在定义RoleBinding或ClusterRolebinding的时候可以直接使用。
posted @ 2020-12-07 12:17  浪漫De刺猬  阅读(190)  评论(0编辑  收藏  举报