在介绍源码之前还是解释一下这个RBAC吧,RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。
这里写图片描述
在kubernetes1.6以后正式引入RBAC这个东西,其实这个事情要分两个方面看,在增加了安全性的同时降低了易用性,应为在真实的环境中不会直接把kubernetes放到公网环境中,内网环境中的网络也是隔离的,当然你可以可以选择关闭RBAC这个服务。
开启服务,在apiserver启动参数设定

 --authorization-mode=RBAC --runtime-config=rbac.authorization.k8s.io/v1beta1

RBAC首先看角色定义,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这个用户,其它也都是类似的。

Logo

开源、云原生的融合云平台

更多推荐