RBAC
RBAC:Role-Based Access Control,基于角色的访问控制
Kubernetes中的所有API对象都保存在Etcd中的,而对这些API操作都是通过kube-apiserver来实现的,这是因为需要kube-apiserver来帮我们完成授权,而在Kubernetes中完成授权的机制就是RBAC。其中RBAC中的基本概念为:
其意义为:它允许被作用者在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
这就给joker用户和role-demo的Role建立了绑定关系,其中joker这个User只是一个授权系统中的逻辑概念,它需要通过外部认证服务,比如Keystone,或者直接给API Server指定一个用户名,密码文件。 上面的YAML文件中其中一个重要的字段是Subjects字段,它定义"被作用者",其中的kind表示被作用者的类型,其有以下三种类型:
上面定义的就是joker这个用户对所有namespace里的Pod都有watch,list,get的操作权限。如果要定义所有权限,可以将verbs字段定义如下:
类似的在Role和ClusterRole对象中的rules字段也可以更加细致化,比如要对某一个具体的对象进行操作,如下:
这条规则定义被作用者只对名字为myconfig的configMap对象有get权限。 上面我们都使用Subjects中User类型得用户功能,但是在实际中我们很少使用,而是经常使用另外一个内置用户:ServiceAccount,下面对ServiceAccount进行介绍。
一个简单的ServiceAccount只需要简单的namespace和name即可。 2、编写RoleBinding的YAML文件来为这个ServiceAccount分配权限:
然后我们创建上面定义的YAML文件,查看创建完成后的信息:
然后创建这个Pod,查看Pod的信息:
其中ca,crt就是用来访问API Server的。 如果一个Pod在定义时没有指定spec.serviceAccountName属性,则系统会自动为其赋值为default,即大家都使用同一个Namespace下的默认Service Account。 Subjects的kind类型除了User,ServiceAccount之外,还有一个Group,就是一组用户的意思。如果你为Kubernetes配置了外部认证服务的话,这个用户组就由外部认证服务提供。而对于Kubernetes内置用户ServiceAccount来说,其也有用户和用户组的概念,其中对于一个ServiceAccount,其在Kubernetes中对应的用户是:
而对于其用户组是:
比如我们定义下面这个RoleBinding:
这就意味着Role这个角色的权限规则作用与devops的namespace中的所有ServiceAccount。 再比如:
这就意味着Role这个角色规则作用与整个集群的所有ServiceAccount。 kubernetes已经内置了许多ClusterRole,以system:开头,可以用kubectl get clusterrole查看。 另外,Kubernetes还提供了四个预先定义好的ClusterRole来供用户直接使用,它们是:
- Rule:规则,一组属于不同API Group的操作集合;
- Role:角色,用于定义一组对Kubernetes API对象操作的一组规则,作用于当个namespace;
- ClusterRole:集群角色,该角色不受namespace的限制;
- Subject:被作用者,也就是规则作用的对象;
- RoleBinding:将角色和被作用者进行绑定,作用于当个namespace;
- ClusterRoleBinding:将集群角色和作用者进行绑定,不受namespace限制;
一、Role和RoleBinding
Role本身就是一个Kubernetest API对象,其定义如下:role-demo.yamlapiVersion: rbac.authorization.k8s.io/v1 kind: Role name: role-demo namespace: devops rules: - apiGroups: [""] resources: ["pods", "deployment"] verbs: ["creat", "delete", "watch", "list", "get"]
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
- User:用户,这是由外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表,对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理。
- Group:组,这是用来关联多个账户,集群中有一个默认的组,比如cluster-admin。
- ServiceAccount:服务帐号,通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到 ServiceAccount。
二、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
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
rules: - apiGroups: [""] resources: ["configMap"] resourceName: ["myconfig"] verbs: ["get"]
三、ServiceAccount
Service Account也是一种账号,但它并不是给Kubernetes集群的用户(系统管理员、运维人员、租户用户等)用的,而是给运行在Pod里的进程用的,它为Pod里的进程提供了必要的身份证明。 我们通过一个例子来了解ServiceAccount的授权过程。1、首先定义一个ServiceAccount:apiVersion: v1 kind: ServiceAccount metadata: namespace: devops name: sa-demo
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
[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
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
system:serviceaccount:<ServiceAccount名字>
system:serviceaccounts:<Namespace名字>
subjects:
- kind: Group
name: system:serviceaccounts:devops
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
- cluster-admin:超管
- admin:普通管理权限
- edit:修改权限
- view:只读权限
与人善言,暖于布锦,伤人之言,深于矛戟