1、知識準備
● 上一節描述了k8s的帳戶管理,本文描述基於角色的訪問控制
● 網上RBAC的文章很是多,具體概念大神們也解釋得很詳細,本文沒有站在高屋建瓴的角度去描述RBAC,而是站在一個普通程序員的視角,去看待RBAC
● 我理解的基於角色的訪問控制,如圖:node
+------------+ +------------>|all:resource|-+ | +------------+ | +----------------+ +----+---+ | | | +------+ |role: | +------>+ namespaces | |user1 |------------>|admin | | | +------+ +--------+ +------------+ | pod | +---->|get:pod |-------->+ | | +------------+ | service | | | | +------+ +--------+ | | deployment | |user2 |------------>|role: |---+ | | +------+ |guest | .... | daemonsets | +--------+ | | | ... | +------------+ | | |list:service| +----------------+ +------------+
帳戶:請求kube-api必要的身份驗證。身份驗證以後只是被容許進入集羣,可是不必定有訪問資源的權限
角色:帳戶登陸以後扮演的角色
規則:在k8s集羣內容許的操做。好比get namespace、get pod等
資源:k8s各類各樣的資源
角色綁定:資源與規則組成訪問權限,將角色綁定在訪問權限上,最後帳戶登陸以後扮演不一樣的角色nginx
2、環境準備
組件 | 版本 |
---|---|
OS | Ubuntu 18.04.1 LTS |
docker | 18.06.0-ce |
k8s | v1.10.1 |
3、建立角色
角色分爲role與clusterrole,區別在於前者是namespace級別,後者是整個k8s cluster級別程序員
(1)建立role
建立一個default namespace的普通角色,權限是對pod的get、list、watchdocker
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: po_r namespace: default rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
(2)建立clusterrole
建立一個具備pod的get、list、watch的clusterrole,這個角色是cluster級別的,也就是全部的namespaceapi
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster_po_r rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
4、userAccount角色綁定
(1)role綁定
先將上一節的mrvolleyball帳號綁定一個namespace級別的role,使用rolebindingui
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: mrvolleyball roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_r subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
再看mrvolleyball的帳戶,已經擁有了對default namespace的get pod權限spa
root@k8s-master:~# kubectl get pod NAME READY STATUS RESTARTS AGE busybox 1/1 Running 89 3d nginx-deployment-77d7f55978-lvfkf 1/1 Running 0 21h
不過他既沒有service的訪問權限,更沒有別的namespace的訪問權限3d
root@k8s-master:~# kubectl get svc Error from server (Forbidden): services is forbidden: User "mrvolleyball" cannot list services in the namespace "default" root@k8s-master:~# kubectl get pod -n kube-system Error from server (Forbidden): pods is forbidden: User "mrvolleyball" cannot list pods in the namespace "kube-system"
(2)clusterrole綁定
綁定clusterrole,讓mrvollerball可以讀取全部namespace的podcode
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: mrvolleyball roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_r subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
這時候mrvolleyball也能夠讀取其餘namespace的podserver
root@k8s-master:~# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-55c94797d7-vr9k6 1/1 Running 0 15d calico-node-86xgg 1/1 Running 0 7d calico-node-drsl2 1/1 Running 0 7d calico-node-l67h4 1/1 Running 0 7d coredns-794b5f8589-vgclz 1/1 Running 4809 15d coredns-794b5f8589-xzpxd 1/1 Running 0 130d default-http-backend-6cb5c56987-tcx92 1/1 Running 0 139d kubernetes-dashboard-77c46fc984-djdd4 1/1 Running 0 139d nginx-ingress-controller-6d95468cc8-ft6nn 1/1 Running 0 140d
這裏須要注意幾種資源的綁定:
rolebinding --> role
clusterrolebinding --> clusterrole
rolebinding --> clusterrole
● 第一種是namespace級別的綁定,只對role所在的namespace生效
● 第二種是cluster級別的綁定,對於集羣全部的namespace都生效
● 第三種是namespace級別的綁定,只對role所在的namespace生效
有同窗要問,第一種和第三種有什麼區別:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: mrvolleyball namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_r subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
區別主要是爲了方便管理:
● 好比有10個namespace,分配給了10個不一樣的團隊,那每一個團隊都須要使用本身的userAccount操做本身所在的namespace
● 最簡單的作法,就是在10個不一樣namespace建立10個role,而後經過rolebinding將role綁定userAccount。若是須要添加userAccount,那這個管理成本就會升高
● 這時候建立一個clusterrole,因爲他們對各自的namespace的行爲都是同樣的,那就只須要經過rolebinding將clusterrole綁定在userAccount,只須要建立1次clusterrole
5、serviceAccount角色綁定
serviceAccount要提供給pod內訪問,或者是外部服務的訪問。爲了驗證serviceAccount,咱們來模擬pod去訪問api
首先先建立一個serviceAccount
root@k8s-master:/etc/kubernetes/ssl# kubectl create serviceaccount helloworld serviceaccount "helloworld" created root@k8s-master:/etc/kubernetes/ssl# kubectl get sa helloworld -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2019-03-12T06:36:00Z name: helloworld namespace: default resourceVersion: "24381027" selfLink: /api/v1/namespaces/default/serviceaccounts/helloworld uid: 1987b4e6-4491-11e9-96bc-525400c34cf1 secrets: - name: helloworld-token-sr9xb
serviceAccount獲取默認生成一個token,該token是用於pod訪問kube-api的身份驗證(詳情訪問上一篇文章)
root@k8s-master:/etc/kubernetes/ssl# kubectl get secret helloworld-token-sr9xb -o yaml apiVersion: v1 data: ... token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltaGxiR3h2ZDI5eWJHUXRkRzlyWlc0dGMzSTVlR0lpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYUdWc2JHOTNiM0pzWkNJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExuVnBaQ0k2SWpFNU9EZGlOR1UyTFRRME9URXRNVEZsT1MwNU5tSmpMVFV5TlRRd01HTXpOR05tTVNJc0luTjFZaUk2SW5ONWMzUmxiVHB6WlhKMmFXTmxZV05qYjNWdWREcGtaV1poZFd4ME9taGxiR3h2ZDI5eWJHUWlmUS5zTTQ3dnBMV25nVmZ1Q2c3RGRfNWlVSGFCa0loeHNvNXY1ZHotRzh3X3ctZUNaS05pZlRyUE9xd3R3QjR4MnZnS3dPaExXX2c0UWxtRDNXS3QyejhlNHVJeFV0cHZkc0lRYkdrYjVrUUdsV1p4cnZwTUZHbTF0eVRsU1lVc3gxa25GdnViWTV0bWU5Y2JkNExOc2RQQ1IxTXBBYnBkYjlqZFh6OWRxMVAyb1Z1LVVuYmVBTkFMcE5tSGJHZjFSdVRPUEJBcUNPNlI3Zm0zUUxpZFZOSDBjRUkwX1Joa0NKR2xPUi1rUlZ5bE5GYXJOVWhvQnJGSEJpTWJyOHd6UHpRNk42Z0hpblctWUc1ekFCY2JNaUR1QUZrRDBCXzBNbDlJandHaDgtbHlrSUZBTU1sbTktUS1hTjJTUjkwSnJyelRYcUtUV3NJU0ZQWHhCTUItX3BXTTlEMEhiZTU4TURCQ1VlSlp0SUcyNno4alBiU0Y1aHRuTy1YSFJRWm1CUzJoaXFLelE2aG9TMkxEa045WUdwcFRETkJUY0dySjg2U0ZQaDlkRWtaYWw0QU9XLWlfTHdEYnY0V2luQjBDOG1Pc3c1WkhDdEVxTVNUTE90aXFyOWZ3bEYzb2lldERqV3FSSXhKeG5rY1NRYTBOTHR4cENiQjFvOGRDTjlqaE1WLVRZMDdidUVNNUpJUGhzeERBMVpqTjNJenVpc3VTVWZMRjd5NkgwZ1JxaGdITzdyMVZvdU5ubGFybjNhSmxMYmF3NUk3RnIwM1ZrQ0pqSmotX0FFRmpSWGlNVmRtenM0el9nWVRfUGR0TXR4YnFfd1p5ZXJHWXpuUk9NQ3p0b2gtRlRCWktOT2dfZjBmTEN3c29rd2NJaEtWWFh2YXMtcjN0YXFBcXZEbWtOOA== kind: Secret metadata: annotations: kubernetes.io/service-account.name: helloworld kubernetes.io/service-account.uid: 1987b4e6-4491-11e9-96bc-525400c34cf1 creationTimestamp: 2019-03-12T06:36:00Z name: helloworld-token-sr9xb namespace: default resourceVersion: "24381026" selfLink: /api/v1/namespaces/default/secrets/helloworld-token-sr9xb uid: 198c824f-4491-11e9-96bc-525400c34cf1 type: kubernetes.io/service-account-token
拿到該token,將其轉碼以後做爲鏈接kube-api的身份驗證
root@k8s-master:/etc/kubernetes/ssl# token=`kubectl get secret helloworld-token-sr9xb -o yaml | grep "token:" | awk '{print $2}' | base64 -d` root@k8s-master:/etc/kubernetes/ssl# kubectl config set-credentials helloworld --token=$token User "helloworld" set.
配置rolebinding,po_r這個role只能對default namespace的pod有讀權限
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: helloworld-role-binding namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_r subjects: - kind: ServiceAccount name: helloworld namespace: default
嘗試訪問一下:
root@k8s-master:~# kubectl config use-context context@helloworld Switched to context "context@helloworld". root@k8s-master:~# kubectl get pod NAME READY STATUS RESTARTS AGE busybox 1/1 Running 187 7d
該serviceAccount也只有default namespace的訪問權限
root@k8s-master:~# kubectl get pod -n kube-system Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:helloworld" cannot list pods in the namespace "kube-system"
6、小結
● 本文介紹了k8s基於權限的訪問,詳細k8s當中role、clusterrole與rolebinding、clusterrolebinding
● 而且模擬了不一樣類型的帳戶訪問kube-api時不一樣的認證方式
至此,本文結束 在下才疏學淺,有撒湯漏水的,請各位不吝賜教...