Kubernetes中有不少種內置的編排對象,此外還能夠自定義API資源類型和控制器的編寫方式.那麼,我能不能本身寫一個編排對象呢?答案是確定的.而這,也正是Kubernetes項目最具吸引力的地方.
畢竟在互聯網級別的大規模集羣裏,Kubernetes內置的編排對象,很難作到徹底知足全部需求,因此不少實際的容器化工做,都會要求設計一個本身的編排對象,實現本身的控制器模式.
因此,咱們能夠基於插件機制來完成這些工做,而不須要修改任何一行代碼.可是,若是要經過外部插件,在Kubernetes中實現新增和操做API對象,那麼就必須先了解一個很是重要的知識:RBAC.
什麼是RBAC呢?咱們知道,Kubernetes中全部的API對象,都保存在Etcd裏,可是呢,對這些API對象的操做,卻必定都是經過訪問kube-apiserver來實現的.其中一個很是重要的緣由,就是你須要APIServer來幫助你作受權工做.而在Kubernetes項目中,負責完成受權(Authorization)工做的機制,就是RABC:基於角色的訪問控制(Role-Based Access Control).web
Role |
Role自己就是一個Kubernetes的API對象,定義以下所示:api
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: mynamespace name: example-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
若是對這個格式比較熟悉的話,應該可以一眼看出來:首先,這個Role對象指定了它能產生做用的Namespace是:mynamespace.
Namespace是Kubernetes項目裏的一個邏輯管理單位,不一樣Namespace的API對象,在經過kubectl命令進行操做的時候,是互相隔離開的.這只是邏輯上的"隔離".Namespace並不會提供任何實際的隔離或者多租戶能力.
Role對象的rules字段,就是它所定義的權限規則.在這裏規則的意思就是:容許"被做用者",對mynamespace下面的Pod對象,進行GET,WATCH和LIST操做.
那麼,這個具體的"被做用者"又是如何指定的呢?這就須要經過RoleBinding來實現了.svg
Subject與RoleBinding |
RoleBinding自己也是Kubernetes的API對象.定義以下:學習
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-rolebinding namespace: mynamespace subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: example-role apiGroup: rbac.authorization.k8s.io
由上,咱們可以看到,這個RoleBinding對象裏定義了一個subjects字段,即"被做用者".它的類型是User,即Kubernetes中的用戶,這個用戶的名字是example-user.可是,在Kubernetes中,並無一個叫作"User"的API對象,這個User究竟是從哪兒來的呢?
實際上,Kubernetes中的"User"就是"用戶",只是一個受權系統裏的邏輯概念.它須要經過外部認證服務來提供,或者也能夠直接給APIServer指定一個用戶名,密碼文件.那麼Kubernetes的受權系統,就能夠從這個文件裏找到對應的"用戶".其實在大多數私有的使用環境中,只要使用Kubernetes提供的內置"用戶",就足夠了.
好像有點兒扯遠了.這個等下再詳細說吧.spa
再往下看,可以看到roleRef字段.正是經過這個字段,RoleBinding對象就能夠直接經過名字,來引用咱們前面定義的Role對象(example-role),從而定義了"被做用者(Subject)"和"角色(Role)"之間的綁定關係.
在這裏須要強調一下:Role和RoleBinding對象都是Namespaced對象,它們對權限的限制規則僅在它們本身的Namespace內有效,roleRef也只能引用當前Namespace中的Role對象.
那麼,對於非Namespaced(Non-namespaced)對象(好比:Node),或者某一個Role想要做用於全部的Namespace時,咱們又該怎麼去作受權呢?
這時,就必需要使用ClusterRole和ClusterRoleBinding這兩個組合了.這兩個API對象的用法和Role與RoleBinding徹底同樣,只不過它們的定義裏,沒有了Namespace字段.
具體以下所示:插件
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrole rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrolebinding subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: example-clusterrole apiGroup: rbac.authorization.k8s.io
上面的例子中,意味着名叫example-user用戶,擁有對全部Namespace裏的Pod進行GET,WATCH和LIST操做的權限.更進一步的說,在Role或者ClusterRole裏面,若是要賦予用戶example-user全部權限,那麼就能夠給它指定一個verbs字段的全集,以下所示:設計
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
固然,也能夠根據本身的需求,只針對某一個具體的對象進行權限設置.好比:code
rules: - apiGroups: [""] resources: ["configmaps"] resourceNames: ["my-config"] verbs: ["get"]
這個例子就表示,這條規則的"被做用者",只對名叫"my-config"的ConfigMap對象,有進行GET操做權限.
在上面提了一下,大多數時候,咱們其實都不太使用"用戶"這個功能,而是直接使用Kubernetes中的"內置用戶",而這個"內置用戶"就是:ServiceAccount.server
ServiceAccount分配權限的過程 |
經過一個實例,來說解一下爲ServiceAccount分配權限的過程.
首先,須要定義一個ServiceAccount.它的API對象很是簡單,以下所示:xml
apiVersion: v1 kind: ServiceAccount metadata: namespace: mynamespace name: example-sa
能夠看到,一個最簡單的ServiceAccount對象,只須要Name和Namespace這兩個最基本的字段.
而後咱們經過編寫RoleBinding的YAML文件,來爲這個ServiceAccount分配權限:
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-rolebinding namespace: mynamespace subjects: - kind: ServiceAccount name: example-sa namespace: mynamespace roleRef: kind: Role name: example-role apiGroup: rbac.authorization.k8s.io
接下來,咱們用kubectl命令建立這三個對象:
$ kubectl create -f svc-account.yaml $ kubectl create -f role-binding.yaml $ kubectl create -f role.yaml
而後,來查看一下ServiceAccount的詳細信息:
$ kubectl get sa -n mynamespace -o yaml - apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2018-09-08T12:59:17Z name: example-sa namespace: mynamespace resourceVersion: "409327" ... secrets: - name: example-sa-token-vmfg6
能夠看到,Kubernetes會爲一個ServiceAccount自動建立並分配一個Secret對象.這個Secret就是這個ServiceAccount對應的,用來和APIServer進行交互的受權文件,通常稱它爲:Token.
Token文件的內容通常是證書或者密碼,它以一個Secret對象的方式,保存在Etcd當中.
此時,用戶的Pod就能夠聲明使用這個ServiceAccount了.
對以上內容的總結 |
上面內容有些多,最後來一個總結:
所謂角色(Role),其實就是一組權限規則列表.分配這些權限的方式,就是經過建立RoleBinding對象,將被做用者(Subject)和權限列表進行綁定.
另外,與之對應的ClusterRole和ClusterRoleBinding,則是Kubernetes集羣級別的Role和RoleBinding,它們的做用範圍不受Namespace限制.
儘管權限的被做用者能夠用不少種(好比,User,Group等),但在咱們日常的使用中,最廣泛的用法仍是ServiceAccount.因此,Role+RoleBinding+ServiceAccount的權限分配方式,是最應該掌握的內容.
以上內容來自我學習<深刻剖析Kubernetes>專欄文章以後的一些看法,有偏頗之處,還望指出. 感謝您的閱讀~