Kubernetes中提供了良好的多租戶認證管理機制,如RBAC、ServiceAccount還有各類Policy等。html
Service Account爲Pod中的進程提供身份信息。node
當用戶訪問集羣(例如使用kubectl
命令)時,apiserver 會將用戶認證爲一個特定的 User Account(目前一般是admin
,除非系統管理員自定義了集羣配置)。Pod 容器中的進程也能夠與 apiserver 聯繫。 當它們在聯繫 apiserver 的時候,它們會被認證爲一個特定的 Service Account(例如default
)。nginx
當建立 pod 的時候,若是沒有指定一個 service account,系統會自動得在與該pod 相同的 namespace 下爲其指派一個default
service account。若是獲取剛建立的 pod 的原始 json 或 yaml 信息(例如使用kubectl get pods podename -o yaml
命令),將看到spec.serviceAccountName
字段已經被設置爲 default
。git
能夠在 pod 中使用自動掛載的 service account 憑證來訪問 API,如 Accessing the Cluster 中所描述。github
Service account 是否可以取得訪問 API 的許可取決於您使用的 受權插件和策略。docker
在 1.6 以上版本中,能夠選擇取消爲 service account 自動掛載 API 憑證,只需在 service account 中設置 automountServiceAccountToken: false
:json
apiVersion: v1 kind: ServiceAccount metadata: name: build-robot automountServiceAccountToken: false ...
在 1.6 以上版本中,也能夠選擇只取消單個 pod 的 API 憑證自動掛載:bootstrap
apiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: build-robot automountServiceAccountToken: false ...
若是在 pod 和 service account 中同時設置了 automountServiceAccountToken
, pod 設置中的優先級更高。api
建立服務帳號(serviceAccount)安全
kubectl create serviceaccount sample-sc
這時候將獲得一個在 default namespace 的 serviceaccount 帳號;運行kubectl get serviceaccount sample-sc
將獲得以下結果:
apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2018-09-03T02:00:37Z labels: from: mofang name: mofang-viewer-sc namespace: default resourceVersion: "18914458" selfLink: /api/v1/namespaces/default/serviceaccounts/sample-sc uid: 26e129dc-af1d-11e8-9453-00163e0efab0 secrets: - name: sample-sc-token-9x7nk
由於在使用 serviceaccount 帳號配置 kubeconfig 的時候須要使用到 sample-sc 的 token, 該 token 保存在該 serviceaccount 保存的 secret 中;
運行kubectl get secret sample-sc-token-9x7nk
或者kubectl describe serviceaccount sample-sc
將會獲得以下結果:
apiVersion: v1 data: ca.crt: Ci0tLS0tQkVHSU4gQ0VSVcvfUNBVEUtLS0tLQpNSUlDL3pDQ0FtaWdBd0lCQWdJREJzdFlNQTBHQ1NxR1NJYjNEUUVCQ3dVQU1HSXhDekFKQmdOVkJBWVRBa05PCk1SRXdEd1lEVlFRSURBaGFhR1ZLYVdGdVp6RVJNQThHQTFVRUJ3d0lTR0Z1WjFwb2IzVXhFREFPQmdOVkJBb00KQjBGc2FXSmhZbUV4RERBS0JnTlZCQXNNQTBGRFV6RU5NQXNHQTFVRUF3d0VjbTl2ZERBZUZ3MHhPREExTWprdwpNelF3TURCYUZ3MHpPREExTWpRd016UTFOVGxhTUdveEtqQW9CZ05WQkFvVElXTTJaVGxqTm1KallUY3pZakUwClkyTTBZV0UzT1RNd1lqTTROREV4TkRaallURVFNQTRHQTFVRUN4TUhaR1ZtWVhWc2RERXFNQ2dHQTFVRUF4TWgKWXpabE9XTTJZbU5oTnpOaU1UUmpZelJoWVRjNU16QmlNemcwTVRFME5tTmhNSUdmTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRHTkFEQ0JpUUtCZ1FETGNFWmJycCtBa0taNHU4TklVM25jaFU4YkExMnhKR0pJMzlxdTd4aFFsR3lHCmZqQTFqdXV4cVMyaE4vTGpwM21XNkdIaW0zd2lJd2N1WUtUN3RGOW9UejgrTzhBQzZHYnpkWExIL1RQTWtCZ2YKOVNYaEdod1hndklMb3YzbnZlS1MzRElxU3UreS9OK1huMzhOOW53SHF6S0p2WE1ROWtJaUJuTXgwVnlzSFFJRApBUUFCbzRHNk1JRzNNQTRHQTFVZER3RUIvd1FFQXdJQ3JEQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01COEdBMVVkCkl3UVlNQmFBRklWYS85MGp6U1Z2V0VGdm5tMUZPWnRZZlhYL01Ed0dDQ3NHQVFVRkJ3RUJCREF3TGpBc0JnZ3IKQmdFRkJRY3dBWVlnYUhSMGNEb3ZMMk5sY25SekxtRmpjeTVoYkdsNWRXNHVZMjl0TDI5amMzQXdOUVlEVlIwZgpCQzR3TERBcW9DaWdKb1lrYUhSMGNEb3ZMMk5sY25SekxtRmpjeTVoYkdsNWRXNHl0TDNKdmIzUXVZM0pzCk1BMEdDU3FHU0liM0RRRUJDd1VBQTRHQkFKWFRpWElvQ1VYODFFSU5idVRTay9PanRJeDM0ckV0eVBuTytBU2oKakszaTR3d1BRMEt5MDhmTlNuU2Z4Q1EyeEY1NTIxNVNvUzMxU3dMellJVEp1WFpBN2xXT29RU1RZL2lBTHVQQgovazNCbDhOUGNmejhGNXlZNy9uY1N6WDRwTXgxOHIwY29PTE1iZlpUUXJtSHBmQ053bWRjQmVCK0JuRFJMUEpGCmgzSUQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKCg== namespace: ZGVmYXAsdA== token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhppppppo5LmV5SnBjM01pT2lKcmRXSmxjbTVsZddekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbTF2Wm1GdVp5MTJhV1YzWlhJdGMyTXRkRzlyWlc0dE9YZzNibXNpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYlc5bVlXNW5MWFpwWlhkbGNpMXpZeUlzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJakkyWlRFeU9XUmpMV0ZtTVdRdE1URmxPQzA1TkRVekxUQXdNVFl6WlRCbFptRmlNQ0lzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwa1pXWmhkV3gwT20xdlptRnVaeTEyYVdWM1pYSXRjMk1pZlEuQWpudnZueXRaWHJ1UndSdEJ3S3RFdzZWNzJpWU1vOUI2LVh3VmkzRWhReXNOM21PLXJvdGFJQnZHUFlNMGZNVDlWRzVjTFFKYmJWUmhLR0FyclUyQ1FNVl9JQ3NpbjFzMjFxTXJ5dngzNm9abzFYZkpWZlVVMEtqeWxndEQ0NTNmWU84SlFfWFF3OGNwVWc5NGE2WnZvcDZHcXNGNGhzT0sxTjFMaGRrSFBpWHA4TzRQUzJ6eDFXNklfeGs2ZUNBcjUxRVpwSktEWTZHMmhmZ1A5emxROGdPV21nbS1EVjZPZzNobjJ4UFprZUktVk1nYUF3amdFUGtVZFJDSndYRk9QRG5UcXlqUmtZVzdLVU1GLTVDTHdBNDZMNk5PYjJ6YUR0Uy16Zm5hdVFwLVdIcFNQdDNEdFc0UmRLZDVDZzE3Z3RGaWhRZzI3dnVqYWJNMGpmQmp3 kind: Secret metadata: annotations: kubernetes.io/service-account.name: sample-sc kubernetes.io/service-account.uid: 26e129dc-af1d-11e8-9453-00163e0efab0 creationTimestamp: 2018-09-03T02:00:37Z name: mofang-viewer-sc-token-9x7nk namespace: default resourceVersion: "18914310" selfLink: /api/v1/namespaces/default/secrets/sample-sc-token-9x7nk uid: 26e58b7c-af1d-11e8-9453-00163e0efab0 type: kubernetes.io/service-account-token
其中 {data.token}
就會是咱們的用戶 token 的 base64 編碼,以後咱們配置 kubeconfig 的時候將會用到它;
建立角色
好比想建立一個只能夠查看集羣deployments
,services
,pods
相關的角色,應該使用以下配置
apiVersion: rbac.authorization.k8s.io/v1 ## 這裏也可使用 Role kind: ClusterRole metadata: name: mofang-viewer-role labels: from: mofang rules: - apiGroups: - "" resources: - pods - pods/status - pods/log - services - services/status - endpoints - endpoints/status - deployments verbs: - get - list - watch
建立角色綁定
apiVersion: rbac.authorization.k8s.io/v1 ## 這裏也可使用 RoleBinding kind: ClusterRoleBinding metadata: name: sample-role-binding labels: from: mofang roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: mofang-viewer-role #這裏即綁定上面建立的clusterrole subjects: - kind: ServiceAccount #將clusterrole綁定到這個服務帳戶上 name: sample-sc namespace: default
配置 kubeconfig
通過以上的步驟,最開始建立的 serviceaccount 就能夠用來訪問咱們的集羣了, 同時咱們能夠動態更改 ClusterRole
的受權來及時控制某個帳號的權限(這也是使用 serviceaccount 的好處);
配置應該以下:
apiVersion: v1 clusters: - cluster: ## 這個是集羣的 TLS 證書,與受權無關,使用同一的就能夠 certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvekNDQW1pZ0F3SUJBZ0lEQnN0WU1BMEdDU3FHU0liM0RRRUJDd1VBTUdJeEN6QUpCZ05WQkFZVEFrTk8KTVJFd0R3WURWUVFJREFoYWFHVkthV0Z1WnpFUk1BOEdBMVVFQnd3SVNHRnVaMXBvYjNVeEVEQU9CZ05WQkFvTQpCMEZzYVdKaFltRXhEREFLQmdOVkJBc01BMEZEVXpFTk1Bc0dBMVVFQXd3RWNtOXZkREFlRncweE9EQTFNamt3Ck16UXdNREJhRncwek9EQTFNalF3TXpRMU5UbGFNR294S2pBb0JnTlZCQW9USVdNMlpUbGpObUpqWVRjellqRTAKWTJNMFlXRTNPVE13WWpNNE5ERXhORFpqWVRFUU1BNEdBMVVFQ3hNSFpHVm1ZWFZzZERFcU1DZ0dBMVVFQXhNaApZelpsT1dNMlltTmhOek5pTVRSall6UmhZVGM1TXpCaU16ZzBNVEUwTm1OaE1JR2ZNQTBHQ1NxR1NJYjNEUUVCCkFRVUFBNEdOQURDQmlRS0JnUURMY0VaYnJwK0FrS1o0dThOSVUzbmNoVThiQTEyeEpHSkkzOXF1N3hoUWxHeUcKZmpBMWp1dXhxUzJoTi9ManAzbVc2R0hpbTN3aUl3Y3VZS1Q3dEY5b1R6OCtPOEFDNkdiemRYTEgvVFBNa0JnZgo5U1hoR2h3WGd2SUxvdjNudmVLUzNESXFTdSt5L04rWG4zOE45bndIcXpLSnZYTVE5a0lpQm5NeDBWeXNIUUlECkFRQUJvNEc2TUlHM01BNEdBMVVkRHdFQi93UUVBd0lDckRBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUI4R0ExVWQKSXdRWU1CYUFGSVZhLzkwanpTVnZXRUZ2bm0xRk9adFlmWFgvTUR3R0NDc0dBUVVGQndFQkJEQXdMakFzQmdncgpCZ0VGQlFjd0FZWWdhSFIwY0RvdkwyTmxjblJ6TG1GamN5NWhiR2w1ZFc0dVkyOXRMMjlqYzNBd05RWURWUjBmCkJDNHdMREFxb0NpZ0pvWWthSFIwY0RvdkwyTmxjblJ6TG1GamN5NWhiR2w1ZFc0dVkyOXRMM0p2YjNRdVkzSnMKTUEwR0NTcUdTSWIzRFFFQkN3VUFBNEdCQUpYVGlYSW9DVVg4MUVJTmJ1VFNrL09qdEl4MzRyRXR5UG5PK0FTagpqSzNpNHd3UFEwS3kwOGZOU25TZnhDUTJ4RjU1MjE1U29TMzFTd0x6WUlUSnVYWkE3bFdPb1FTVFkvaUFMdVBCCi9rM0JsOE5QY2Z6OEY1eVk3L25jU3pYNHBNeDE4cjBjb09MTWJmWlRRcm1IcGZDTndtZGNCZUIrQm5EUkxQSkYKaDNJRAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== server: https://10.10.10.165:6443 name: beta contexts: - context: cluster: beta user: beta-viewer name: beta-viewer current-context: beta-viewer kind: Config preferences: {} users: - name: beta-viewer user: ## 這個使咱們在建立 serviceaccount 生成相關 secret 以後的 data.token 的 base64 解碼字符,它本質是一個 jwt token token: eyJhbGciOiJSUzI1NiIsInR5dffg6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Im1vZmFuZy12aWV3ZXItc2MtdG9rZW4tOXg3bmsiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoibW9mYW5nLXZpZXdlci1zYyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjxZTEyOWRjLWFmMWQtMTFlOC05NDUzLTAwMTYzZTBlZmFiMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Om1vZmFuZy12aWV3ZXItc2MifQ.AjnvvnytZXruRwRtBwKtEw6V72iYMo9B6-XwVi3EhQysN3mO-rotaIBvGPYM0fMT9VG5cLQJbbVRhKGArrU2CQMV_ICsin1s21qMryvx36oZo1XfJVfUU0KjylgtD453fYO8JQ_XQw8cpUg94a6Zvop6GqsF4hsOK1N1LhdkHPiXp8O4PS2zx1W6I_xk6eCAr51EZpJKDY6G2hfgP9zlQ8gOWmgm-DV6Og3hn2xPZkeI-VMgaAwjgEPkUdRCJwXFOPDnTqyjRkYW7KUMF-5CLwA46L6NOb2zaDtS-zfnauQp-WHpSPt3DtW4RdKd5Cg17gtFihQg27vujabM0jfBjw
每一個 namespace 中都有一個默認的叫作 default
的 service account 資源。
可使用如下命令列出 namespace 下的全部 serviceAccount 資源。
$ kubectl get serviceAccounts NAME SECRETS AGE default 1 1d [root@bogon ingress-test]# kubectl get serviceaccounts --all-namespaces NAMESPACE NAME SECRETS AGE default default 1 26d ingress-nginx default 1 11d ingress-nginx nginx-ingress-serviceaccount 1 3d kube-public default 1 26d kube-system dashboard 1 22d kube-system default 1 26d kube-system heapster 1 21d kube-system jenkins-admin 1 3d kube-system kube-dns 1 23d
能夠像這樣建立一個 ServiceAccount 對象:
$ cat > /tmp/serviceaccount.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: build-robot EOF
$ kubectl create -f /tmp/serviceaccount.yaml serviceaccount "build-robot" created
若是看到以下的 service account 對象的完整輸出信息:
$ kubectl get serviceaccounts/build-robot -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2015-06-16T00:12:59Z name: build-robot namespace: default resourceVersion: "272500" selfLink: /api/v1/namespaces/default/serviceaccounts/build-robot uid: 721ab723-13bc-11e5-aec2-42010af0021e secrets: - name: build-robot-token-bvbk5
而後將看到有一個 token 已經被自動建立,並被 service account 引用。可使用受權插件來 設置 service account 的權限
在 pod 建立之初 service account 就必須已經存在,不然建立將被拒絕。設置非默認的 service account,只須要在 pod 的spec.serviceAccountName
字段中將name設置爲想要用的 service account 名字便可。
不能更新已建立的 pod 的 service account。能夠清理 service account,以下所示:
$ kubectl delete serviceaccount/build-robot
假設已經有了一個如上文提到的名爲 」build-robot「 的 service account,如今手動建立一個新的 secret。
$ cat > /tmp/build-robot-secret.yaml <<EOF apiVersion: v1 kind: Secret metadata: name: build-robot-secret annotations: kubernetes.io/service-account.name: build-robot type: kubernetes.io/service-account-token EOF
$ kubectl create -f /tmp/build-robot-secret.yaml secret "build-robot-secret" created
如今能夠確認下新建立的 secret 取代了 「build-robot」 這個 service account 原來的 API token。
全部已不存在的 service account 的 token 將被 token controller 清理掉。獲取token內容命令以下
[root@bogon tmp]# kubectl describe secrets/build-robot-secret Name: build-robot-secret Namespace: default Labels: <none> Annotations: kubernetes.io/service-account.name=build-robot kubernetes.io/service-account.uid=fcf67da4-cd58-11e8-8e6e-00505693e5c6 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1359 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJ1aWxkLXJvYm90LXNlY3JldCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJidWlsZC1yb2JvdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImZjZjY3ZGE0LWNkNTgtMTFlOC04ZTZlLTAwNTA1NjkzZTVjNiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmJ1aWxkLXJvYm90In0.dH-Xxj0drOjhvQlWF37n2Q61fGXG26xRkklIWw6wHH0s8Msdf5FIOfD_E9OFez9nbIPO4efMG5ZK79Rc1vtmdBIfHUSi_tsHhsoGJwqtkoj1wXTJTaum4RtXQVyaVxqLsPjFaP0EL-5_YTy2Q9Ay5hBBqjUGRJ1KiuRKHNoLuSO3L7oYZcPXX0BCrSFyTqlYfvcNqv3P-hT-TKLB25uBw2eE90iguDk1cGCCfCeKtLVuZ6iFNOBEZOYCErOiboPAH55e3wl98Uuze6MOAbsZRIaALISCxyR0W_heyYES90MU8IOvgQW7Z0WkxSNLTsknPL7nMykvkHXJay1J-18ZGw
ImagePullSecret用於從私有倉庫pull鏡像
$ kubectl create secret docker-registry myregistrykey --docker-server=10.10.10.12 --docker-username=admin --docker-password=HarBor12345 --docker-email=xxxx secret/myregistrykey created.
說明 : --docker 開頭的參數分別指定了私有倉庫的地址用戶和密碼
首先,建立一個 imagePullSecret,詳見這裏(或者上面)。而後,確認已建立。如:
$ kubectl get secrets myregistrykey NAME TYPE DATA AGE myregistrykey kubernetes.io/.dockerconfigjson 1 1d
而後,修改 namespace 中的默認 service account 使用該 secret 做爲 imagePullSecret。
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
或者使用Vi 交互過程當中須要手動編輯:
$ kubectl get serviceaccounts default -o yaml > ./sa.yaml
$ cat sa.yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2015-08-07T22:02:39Z name: default namespace: default resourceVersion: "243024" selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 secrets: - name: default-token-uudge
$ vi sa.yaml [editor session not shown] [delete line with key "resourceVersion"] [add lines with "imagePullSecret:"]
$ cat sa.yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2015-08-07T22:02:39Z name: default namespace: default selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 secrets: - name: default-token-uudge imagePullSecrets: - name: myregistrykey
$ kubectl replace serviceaccount default -f ./sa.yaml serviceaccounts/default
如今,全部當前 namespace 中新建立的 pod 的 spec 中都會增長以下內容:
spec: imagePullSecrets: - name: myregistrykey
基於角色的訪問控制(Role-Based Access Control, 即」RBAC」)使用」rbac.authorization.k8s.io」 API Group實現受權決策,容許管理員經過Kubernetes API動態配置策略。
要啓用RBAC,請使用--authorization-mode=RBAC
啓動API Server。
在RBAC API中,一個角色包含了一套表示一組權限的規則。 權限以純粹的累加形式累積(沒有」否認」的規則)。 角色能夠由命名空間(namespace)內的Role
對象定義,而整個Kubernetes集羣範圍內有效的角色則經過ClusterRole
對象實現。
一個Role
對象只能用於授予對某一單一命名空間中資源的訪問權限。 如下示例描述了」default」命名空間中的一個Role
對象的定義,用於授予對pod的讀訪問權限:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # 空字符串""代表使用core API group resources: ["pods"] verbs: ["get", "watch", "list"]
下面示例中的ClusterRole
定義可用於授予用戶對某一特定命名空間,或者全部命名空間中的secret(取決於其綁定方式)的讀訪問權限:
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: # 鑑於ClusterRole是集羣範圍對象,因此這裏不須要定義"namespace"字段 name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
角色綁定將一個角色中定義的各類權限授予一個或者一組用戶。 角色綁定包含了一組相關主體(即subject, 包括用戶——User、用戶組——Group、或者服務帳戶——Service Account)以及對被授予角色的引用。 在命名空間中能夠經過RoleBinding
對象授予權限,而集羣範圍的權限授予則經過ClusterRoleBinding
對象完成。
RoleBinding
能夠引用在同一命名空間內定義的Role
對象。 下面示例中定義的RoleBinding
對象在」default」命名空間中將」pod-reader」角色授予用戶」jane」。 這一受權將容許用戶」jane」從」default」命名空間中讀取pod。
# 如下角色綁定定義將容許用戶"jane"從"default"命名空間中讀取pod。
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-pods namespace: default subjects: - kind: User #賦予用戶jane pod-reader角色權限 name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader #引用上面定義的role apiGroup: rbac.authorization.k8s.io
RoleBinding
對象也能夠引用一個ClusterRole
對象用於在RoleBinding
所在的命名空間內授予用戶對所引用的ClusterRole
中 定義的命名空間資源的訪問權限。這一點容許管理員在整個集羣範圍內首先定義一組通用的角色,而後再在不一樣的命名空間中複用這些角色。
例如,儘管下面示例中的RoleBinding
引用的是一個ClusterRole
對象,可是用戶」dave」(即角色綁定主體)仍是隻能讀取」development」 命名空間中的secret(即RoleBinding
所在的命名空間)。
# 如下角色綁定容許用戶"dave"讀取"development"命名空間中的secret。
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-secrets namespace: development # 這裏代表僅受權讀取"development"命名空間中的資源。 subjects: - kind: User name: dave apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader #引用上面定義的clusterRole 名稱(clusterRole沒有指定命名空間,默承認以應用全部,可是在rolebinding時,指定了命名空間,因此只能讀取本命名空間的文件) apiGroup: rbac.authorization.k8s.io
最後,可使用ClusterRoleBinding
在集羣級別和全部命名空間中授予權限。下面示例中所定義的ClusterRoleBinding
容許在用戶組」manager」中的任何用戶均可以讀取集羣中任何命名空間中的secret。
# 如下`ClusterRoleBinding`對象容許在用戶組"manager"中的任何用戶均可以讀取集羣中任何命名空間中的secret。
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-secrets-global subjects: - kind: Group name: manager apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
大多數資源由表明其名字的字符串表示,例如」pods」,就像它們出如今相關API endpoint的URL中同樣。然而,有一些Kubernetes API還 包含了」子資源」,好比pod的logs。在Kubernetes中,pod logs endpoint的URL格式爲:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在這種狀況下,」pods」是命名空間資源,而」log」是pods的子資源。爲了在RBAC角色中表示出這一點,咱們須要使用斜線來劃分資源 與子資源。若是須要角色綁定主體讀取pods以及pod log,您須要定義如下角色:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: pod-and-pod-logs-reader rules: - apiGroups: [""] resources: ["pods", "pods/log"] #根據上面意思表示授予讀取pods下log的權限 verbs: ["get", "list"]
經過resourceNames
列表,角色能夠針對不一樣種類的請求根據資源名引用資源實例。當指定了resourceNames
列表時,不一樣動做 種類的請求的權限,如使用」get」、」delete」、」update」以及」patch」等動詞的請求,將被限定到資源列表中所包含的資源實例上。 例如,若是須要限定一個角色綁定主體只能」get」或者」update」一個configmap時,您能夠定義如下角色:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: configmap-updater rules: - apiGroups: [""] resources: ["configmap"] resourceNames: ["my-configmap"] verbs: ["update", "get"]
值得注意的是,若是設置了resourceNames
,則請求所使用的動詞不能是list、watch、create或者deletecollection。 因爲資源名不會出如今create、list、watch和deletecollection等API請求的URL中,因此這些請求動詞不會被設置了resourceNames
的規則所容許,由於規則中的resourceNames
部分不會匹配這些請求。
在如下示例中,僅截取展現了rules
部分的定義。
容許讀取core API Group中定義的資源」pods」:
rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"]
容許讀寫在」extensions」和」apps」 API Group中定義的」deployments」:
rules: - apiGroups: ["extensions", "apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
容許讀取」pods」以及讀寫」jobs」:
rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] - apiGroups: ["batch", "extensions"] resources: ["jobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
容許讀取一個名爲」my-config」的ConfigMap
實例(須要將其經過RoleBinding
綁定從而限制針對某一個命名空間中定義的一個ConfigMap
實例的訪問):
rules: - apiGroups: [""] resources: ["configmaps"] resourceNames: ["my-config"] verbs: ["get"]
容許讀取core API Group中的」nodes」資源(因爲Node
是集羣級別資源,因此此ClusterRole
定義須要與一個ClusterRoleBinding
綁定纔能有效):
rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"]
容許對非資源endpoint 「/healthz」及其全部子路徑的」GET」和」POST」請求(此ClusterRole
定義須要與一個ClusterRoleBinding
綁定纔能有效):
rules: - nonResourceURLs: ["/healthz", "/healthz/*"] # 在非資源URL中,'*'表明後綴通配符 verbs: ["get", "post"]
RoleBinding
或者ClusterRoleBinding
將角色綁定到角色綁定主體(Subject)。 角色綁定主體(kind指定)能夠是用戶組(Group)、用戶(User)或者服務帳戶(Service Accounts)。
用戶由字符串表示。能夠是純粹的用戶名,例如」alice」、電子郵件風格的名字,如 「bob@example.com」 或者是用字符串表示的數字id。由Kubernetes管理員配置認證模塊 以產生所需格式的用戶名。對於用戶名,RBAC受權系統不要求任何特定的格式。然而,前綴system:
是 爲Kubernetes系統使用而保留的,因此管理員應該確保用戶名不會意外地包含這個前綴。
Kubernetes中的用戶組信息由受權模塊提供。用戶組與用戶同樣由字符串表示。Kubernetes對用戶組 字符串沒有格式要求,但前綴system:
一樣是被系統保留的。
服務帳戶(serviceAccount)擁有包含 system:serviceaccount:
前綴的用戶名,並屬於擁有system:serviceaccounts:
前綴的用戶組。
如下示例中,僅截取展現了RoleBinding
的subjects
字段。
一個名爲」alice@example.com」的用戶:
subjects: - kind: User name: "alice@example.com" apiGroup: rbac.authorization.k8s.io
一個名爲」frontend-admins」的用戶組:
subjects: - kind: Group name: "frontend-admins" apiGroup: rbac.authorization.k8s.io
kube-system命名空間中的默認服務帳戶:
subjects: - kind: ServiceAccount name: default namespace: kube-system
名爲」qa」命名空間中的全部服務帳戶:
subjects: - kind: Group name: system:serviceaccounts:qa apiGroup: rbac.authorization.k8s.io
在集羣中的全部服務帳戶:
subjects: - kind: Group name: system:serviceaccounts apiGroup: rbac.authorization.k8s.io
全部認證過的用戶(version 1.5+):
subjects: - kind: Group name: system:authenticated apiGroup: rbac.authorization.k8s.io
全部未認證的用戶(version 1.5+):
subjects: - kind: Group name: system:unauthenticated apiGroup: rbac.authorization.k8s.io
全部用戶(version 1.5+):
subjects: - kind: Group name: system:authenticated apiGroup: rbac.authorization.k8s.io - kind: Group name: system:unauthenticated apiGroup: rbac.authorization.k8s.io
API Server會建立一組默認的ClusterRole
和ClusterRoleBinding
對象。 這些默認對象中有許多包含system:
前綴,代表這些資源由Kubernetes基礎組件」擁有」。 對這些資源的修改可能致使非功能性集羣(non-functional cluster)。一個例子是system:node
ClusterRole對象。 這個角色定義了kubelets的權限。若是這個角色被修改,可能會致使kubelets沒法正常工做。
全部默認的ClusterRole和ClusterRoleBinding對象都會被標記爲kubernetes.io/bootstrapping=rbac-defaults
。
每次啓動時,API Server都會更新默認ClusterRole所缺少的各類權限,並更新默認ClusterRoleBinding所缺少的各個角色綁定主體。 這種自動更新機制容許集羣修復一些意外的修改。因爲權限和角色綁定主體在新的Kubernetes釋出版本中可能變化,這也可以保證角色和角色 綁定始終保持是最新的。
若是須要禁用自動更新,請將默認ClusterRole以及ClusterRoleBinding的rbac.authorization.kubernetes.io/autoupdate
設置成爲false
。 請注意,缺少默認權限和角色綁定主體可能會致使非功能性集羣問題。
自Kubernetes 1.6+起,當集羣RBAC受權器(RBAC Authorizer)處於開啓狀態時,能夠啓用自動更新功能
默認ClusterRole | 默認ClusterRoleBinding | 描述 |
---|---|---|
system:basic-user | system:authenticated and system:unauthenticatedgroups | 容許用戶只讀訪問有關本身的基本信息。 |
system:discovery | system:authenticated and system:unauthenticatedgroups | 容許只讀訪問API discovery endpoints, 用於在API級別進行發現和協商。 |
一些默認角色並不包含system:
前綴,它們是面向用戶的角色。 這些角色包含超級用戶角色(cluster-admin
),即旨在利用ClusterRoleBinding(cluster-status
)在集羣範圍內受權的角色, 以及那些使用RoleBinding(admin
、edit
和view
)在特定命名空間中受權的角色。
默認ClusterRole | 默認ClusterRoleBinding | 描述 |
---|---|---|
cluster-admin | system:mastersgroup | 超級用戶權限,容許對任何資源執行任何操做。 在ClusterRoleBinding中使用時,能夠徹底控制集羣和全部命名空間中的全部資源。 在RoleBinding中使用時,能夠徹底控制RoleBinding所在命名空間中的全部資源,包括命名空間本身。 |
admin | None | 管理員權限,利用RoleBinding在某一命名空間內部授予。 在RoleBinding中使用時,容許針對命名空間內大部分資源的讀寫訪問, 包括在命名空間內建立角色與角色綁定的能力。 但不容許對資源配額(resource quota)或者命名空間自己的寫訪問。 |
edit | None | 容許對某一個命名空間內大部分對象的讀寫訪問,但不容許查看或者修改角色或者角色綁定。 |
view | None | 容許對某一個命名空間內大部分對象的只讀訪問。 不容許查看角色或者角色綁定。 因爲可擴散性等緣由,不容許查看secret資源。 |
默認ClusterRole | 默認ClusterRoleBinding | 描述 |
---|---|---|
system:kube-scheduler | system:kube-scheduler user | 容許訪問kube-scheduler組件所須要的資源。 |
system:kube-controller-manager | system:kube-controller-manageruser | 容許訪問kube-controller-manager組件所須要的資源。 單個控制循環所須要的權限請參閱控制器(controller)角色. |
system:node | system:nodesgroup (deprecated in 1.7) | 容許對kubelet組件所須要的資源的訪問,包括讀取全部secret和對全部pod的寫訪問。 自Kubernetes 1.7開始, 相比較於這個角色,更推薦使用Node authorizer 以及NodeRestriction admission plugin, 並容許根據調度運行在節點上的pod授予kubelets API訪問的權限。 自Kubernetes 1.7開始,當啓用Node 受權模式時,對system:nodes 用戶組的綁定將不會被自動建立。 |
system:node-proxier | system:kube-proxyuser | 容許對kube-proxy組件所須要資源的訪問。 |
默認ClusterRole | 默認ClusterRoleBinding | 描述 |
---|---|---|
system:auth-delegator | None | 容許委託認證和受權檢查。 一般由附加API Server用於統一認證和受權。 |
system:heapster | None | Heapster組件的角色。 |
system:kube-aggregator | None | kube-aggregator組件的角色。 |
system:kube-dns | kube-dns service account in the kube-systemnamespace | kube-dns組件的角色。 |
system:node-bootstrapper | None | 容許對執行Kubelet TLS引導(Kubelet TLS bootstrapping)所須要資源的訪問. |
system:node-problem-detector | None | node-problem-detector組件的角色。 |
system:persistent-volume-provisioner | None | 容許對大部分動態存儲卷建立組件(dynamic volume provisioner)所須要資源的訪問。 |
Kubernetes controller manager負責運行核心控制循環。 當使用--use-service-account-credentials
選項運行controller manager時,每一個控制循環都將使用單獨的服務帳戶啓動。 而每一個控制循環都存在對應的角色,前綴名爲system:controller:
。 若是不使用--use-service-account-credentials
選項時,controller manager將會使用本身的憑證運行全部控制循環,而這些憑證必須被授予相關的角色。 這些角色包括:
RBAC API會阻止用戶經過編輯角色或者角色綁定來升級權限。 因爲這一點是在API級別實現的,因此在RBAC受權器(RBAC authorizer)未啓用的狀態下依然能夠正常工做。
用戶只有在擁有了角色所包含的全部權限的條件下才能建立/更新一個角色,這些操做還必須在角色所處的相同範圍內進行(對於ClusterRole
來講是集羣範圍,對於Role
來講是在與角色相同的命名空間或者集羣範圍)。 例如,若是用戶」user-1」沒有權限讀取集羣範圍內的secret列表,那麼他也不能建立包含這種權限的ClusterRole
。爲了可以讓用戶建立/更新角色,須要:
Role
或者ClusterRole
對象。Role
或者ClusterRole
中所可以設置的全部權限。若是用戶嘗試建立或者修改Role
或者ClusterRole
以設置那些他們未被受權的權限時,這些API請求將被禁止。
用戶只有在擁有所引用的角色中包含的全部權限時才能夠建立/更新角色綁定(這些操做也必須在角色綁定所處的相同範圍內進行)或者用戶被明確受權能夠在所引用的角色上執行綁定操做。 例如,若是用戶」user-1」沒有權限讀取集羣範圍內的secret列表,那麼他將不能建立ClusterRole
來引用那些授予了此項權限的角色。爲了可以讓用戶建立/更新角色綁定,須要:
RoleBinding
或者ClusterRoleBinding
對象。隱式地,經過授予用戶全部所引用的角色中所包含的權限
顯式地,經過授予用戶在特定Role(或者ClusterRole)對象上執行bind
操做的權限
例如,下面例子中的ClusterRole和RoleBinding將容許用戶」user-1」授予其它用戶」user-1-namespace」命名空間內的admin
、edit
和view
等角色和角色綁定。
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: role-grantor rules: - apiGroups: ["rbac.authorization.k8s.io"] resources: ["rolebindings"] verbs: ["create"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterroles"] verbs: ["bind"] resourceNames: ["admin","edit","view"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: role-grantor-binding namespace: user-1-namespace roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: role-grantor subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: user-1
當初始化第一個角色和角色綁定時,初始用戶須要可以授予他們還沒有擁有的權限。 初始化初始角色和角色綁定時須要:
system:masters
用戶組的憑證,該用戶組經過默認綁定綁定到cluster-admin
超級用戶角色。--insecure-port
),您也能夠經過這個沒有施行認證或者受權的端口發送角色或者角色綁定請求。
有兩個kubectl
命令能夠用於在命名空間內或者整個集羣內授予角色。
kubectl create rolebinding
在某一特定命名空間內授予Role
或者ClusterRole
。示例以下:
在名爲」acme」的命名空間中將admin
ClusterRole
授予用戶」bob」:
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
在名爲」acme」的命名空間中將view
ClusterRole
授予服務帳戶」myapp」:
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
kubectl create clusterrolebinding
在整個集羣中授予ClusterRole
,包括全部命名空間。示例以下:
在整個集羣範圍內將cluster-admin
ClusterRole
授予用戶」root」:
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
在整個集羣範圍內將system:node
ClusterRole
授予用戶」kubelet」:
kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
在整個集羣範圍內將view
ClusterRole
授予命名空間」acme」內的服務帳戶」myapp」:
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
默認的RBAC策略將授予控制平面組件(control-plane component)、節點(node)和控制器(controller)一組範圍受限的權限, 但對於」kube-system」命名空間之外的服務帳戶,則不授予任何權限(超出授予全部認證用戶的發現權限)。
從最安全到最不安全能夠排序如下方法:
對某一特定應用程序的服務帳戶授予角色(最佳實踐)
要求應用程序在其pod規範(pod spec)中指定serviceAccountName
字段,而且要建立相應服務帳戶(例如經過API、應用程序清單或者命令kubectl create serviceaccount
等)。
例如,在」my-namespace」命名空間中授予服務帳戶」my-sa」只讀權限:
kubectl create rolebinding my-sa-view \ --clusterrole=view \ --serviceaccount=my-namespace:my-sa \ --namespace=my-namespace
換成yaml文件大概以下
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: my-sa-view namespace: my-namespace subjects: - kind: ServiceAccount name: my-sa apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: view #這裏view爲clusterrole名稱,其中berbs須要給view apiGroup: rbac.authorization.k8s.io
在某一命名空間中授予」default」服務帳號一個角色
若是一個應用程序沒有在其pod規範中指定serviceAccountName
,它將默認使用」default」服務帳號。
注意:授予」default」服務帳號的權限將可用於命名空間內任何沒有指定serviceAccountName
的pod。
下面的例子將在」my-namespace」命名空間內授予」default」服務帳號只讀權限:
kubectl create rolebinding default-view \ --clusterrole=view \ --serviceaccount=my-namespace:default \ --namespace=my-namespace
目前,許多加載項(addon)做爲」kube-system」命名空間中的」default」服務賬戶運行。 要容許這些加載項使用超級用戶訪問權限,請將cluster-admin權限授予」kube-system」命名空間中的」default」服務賬戶。 注意:啓用上述操做意味着」kube-system」命名空間將包含容許超級用戶訪問API的祕鑰。
kubectl create clusterrolebinding add-on-cluster-admin \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:default
爲命名空間中全部的服務帳號授予角色
若是您但願命名空間內的全部應用程序都擁有同一個角色,不管它們使用什麼服務帳戶,您能夠爲該命名空間的服務帳戶用戶組授予角色。
下面的例子將授予」my-namespace」命名空間中的全部服務帳戶只讀權限:
kubectl create rolebinding serviceaccounts-view \ --clusterrole=view \ --group=system:serviceaccounts:my-namespace \ --namespace=my-namespace
對集羣範圍內的全部服務帳戶授予一個受限角色(不鼓勵)
若是您不想管理每一個命名空間的權限,則能夠將集羣範圍角色授予全部服務賬戶。
下面的例子將全部命名空間中的只讀權限授予集羣中的全部服務帳戶:
kubectl create clusterrolebinding serviceaccounts-view \ --clusterrole=view \ --group=system:serviceaccounts
授予超級用戶訪問權限給集羣範圍內的全部服務賬戶(強烈不鼓勵)
若是您根本不關心權限分塊,您能夠對全部服務帳戶授予超級用戶訪問權限。
警告:這種作法將容許任何具備讀取權限的用戶訪問secret或者經過建立一個容器的方式來訪問超級用戶的憑據。
kubectl create clusterrolebinding serviceaccounts-cluster-admin \ --clusterrole=cluster-admin \ --group=system:serviceaccounts
同時運行RBAC和ABAC受權器,幷包括舊版ABAC策略:
--authorization-mode=RBAC,ABAC --authorization-policy-file=mypolicy.jsonl
RBAC受權器將嘗試首先受權請求。若是RBAC受權器拒絕API請求,則ABAC受權器將被運行。這意味着RBAC策略或者ABAC策略所容許的任何請求都是可經過的。
當以日誌級別爲2或更高(--v = 2
)運行時,您能夠在API Server日誌中看到RBAC拒絕請求信息(以RBAC DENY:
爲前綴)。 您可使用該信息來肯定哪些角色須要授予哪些用戶,用戶組或服務賬戶。 一旦授予服務賬戶角色,而且服務器日誌中沒有RBAC拒絕消息的工做負載正在運行,您能夠刪除ABAC受權器。