在介绍源码之前还是解释一下这个RBAC吧,RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。 在kubernetes1.6以后正式引入RBAC这个东西,其实这个事情要分两个方面看,在增加了安全性的同时降低了易用性,应为在真实的环境中不会直接把kubernetes放到公网环境中,内网环境中的网络也是隔离的,当然你可以可以选择关闭RBAC这个服务。 开启服务,在apiserver启动参数设定
--authorization-mode=RBAC --runtime-config=rbac.authorization.k8s.io/v1beta1RBAC首先看角色定义,Role是命名空间级别的
type Role struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` }集群角色是集群级别的
type ClusterRole struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"` }角色里面关联的是Rules规则,一个角色有哪些权限,通过rule去定义,下面是rule的属性,这些主要事控制访问的资源、访问URL限制。
type PolicyRule struct { Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,4,rep,name=resourceNames"` NonResourceURLs []string `json:"nonResourceURLs,omitempty" protobuf:"bytes,5,rep,name=nonResourceURLs"` }那角色是怎么和绑定的呢,这就要看RoleBinding和ClusterRoleBinding
type RoleBinding struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` Subjects []Subject `json:"subjects" protobuf:"bytes,2,rep,name=subjects"` RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` }相同属性的的结构体
type ClusterRoleBinding struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` Subjects []Subject `json:"subjects" protobuf:"bytes,2,rep,name=subjects"` RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"` }主要看两个,第一个是Subjects,它就是关联的对象(”User”, “Group”, 和指定命名空间下的: “ServiceAccount”),第二个是RoleRef,他是是角色的关联。可以看上一篇heapster的rbac就理解怎样使用了。 kubernetes系统自身组件的运行也是需要这些权限管理的,所以系统初始了一些角色和默认的权限,看代码plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go:
先看读写权限的定义
ReadWrite = []string{"get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"} Read = []string{"get", "list", "watch"}对应于API的各种操作。
{ // a "root" role which can do absolutely anything ObjectMeta: metav1.ObjectMeta{Name: "cluster-admin"}, Rules: []rbac.PolicyRule{ rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie(), rbac.NewRule("*").URLs("*").RuleOrDie(), }, }, { // a role which provides just enough power to determine if the server is ready and discover API versions for negotiation ObjectMeta: metav1.ObjectMeta{Name: "system:discovery"}, Rules: []rbac.PolicyRule{ rbac.NewRule("get").URLs("/healthz", "/version", "/swaggerapi", "/swaggerapi/*", "/api", "/api/*", "/apis", "/apis/*").RuleOrDie(), }, }, { // a role which provides minimal resource access to allow a "normal" user to learn information about themselves ObjectMeta: metav1.ObjectMeta{Name: "system:basic-user"}, Rules: []rbac.PolicyRule{ // TODO add future selfsubjectrulesreview, project request APIs, project listing APIs rbac.NewRule("create").Groups(authorizationGroup).Resources("selfsubjectaccessreviews").RuleOrDie(), }, }, ....上面截取了部分代码,他们是系统角色的定义,譬如cluster-admin角色,它的权限是
rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie(), rbac.NewRule("*").URLs("*").RuleOrDie(),匹配所有规则,所有URL,所有资源,那么它将是一个“root”级别,最高权限,所以在kubernetes中kubectl的证书里面”O”: “system:masters”,这个用户组管理的就是cluster-admin这个角色,下面会细说。 先简单分析一下系统里面主要角色: 1.cluster-admin:最高管理角色 2.system:discovery:接口发现角色,主要是接口查询
rbac.NewRule("get").URLs("/healthz", "/version", "/swaggerapi", "/swaggerapi/*", "/api", "/api/*", "/apis", "/apis/*")3.system:basic-user基础角色,最少访问权限 4.admin 空间级别的管理员,有基础资源的增删改查
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(), rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers","replicationcontrollers/scale","serviceaccounts","services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie() ...5.edit空间级别修改角色 6.view空间级别查看角色 7.system:heapster集群级别heapster角色,提供资源查询权限
rbac.NewRule(Read...).Groups(legacyGroup).Resources("events", "pods", "nodes", "namespaces").RuleOrDie(),8.system:node系统级别node节点操作角色 9.system:node-proxier系统级别proxy操作角色 10.system:node-bootstrapper系统级别node启动操作角色,启动时候证书签名用
rbac.NewRule("create", "get", "list", "watch").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),11.system:kube-controller-manager系统级别kube-controller-manager操作角色 12.system:kube-scheduler系统级别kube-scheduler操作角色 13.system:kube-dns系统级别kube-dns操作角色,看过之前源码阅读的就理解了这里为啥是endpoints和services的listwatch了。
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("endpoints", "services").RuleOrDie(),14.system:persistent-volume-provisioner系统级别PV、PVC操作。 看完系统初始化的这些角色和对应的权限后,看看系统初始化的角色绑定
func ClusterRoleBindings() []rbac.ClusterRoleBinding { rolebindings := []rbac.ClusterRoleBinding{ rbac.NewClusterBinding("cluster-admin").Groups(user.SystemPrivilegedGroup).BindingOrDie(), rbac.NewClusterBinding("system:discovery").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(), rbac.NewClusterBinding("system:basic-user").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(), rbac.NewClusterBinding("system:node").Groups(user.NodesGroup).BindingOrDie(), rbac.NewClusterBinding("system:node-proxier").Users(user.KubeProxy).BindingOrDie(), rbac.NewClusterBinding("system:kube-controller-manager").Users(user.KubeControllerManager).BindingOrDie(), rbac.NewClusterBinding("system:kube-dns").SAs("kube-system", "kube-dns").BindingOrDie(), rbac.NewClusterBinding("system:kube-scheduler").Users(user.KubeScheduler).BindingOrDie(), } addClusterRoleBindingLabel(rolebindings) return rolebindings }这样就可以看到cluster-admin这个角色关联到system:masters这个用户组,system:node-proxier关联到system:kube-proxy这个用户,其它也都是类似的。