1. 程式人生 > >kubernetes原始碼分析之RBAC

kubernetes原始碼分析之RBAC

在介紹原始碼之前還是解釋一下這個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這個使用者,其它也都是類似的。