API Server做爲Kubernetes網關,是訪問和管理資源對象的惟一入口,其各類集羣組件訪問資源都須要通過網關才能進行正常訪問和管理。每一次的訪問請求都須要進行合法性的檢驗,其中包括身份驗證、操做權限驗證以及操做規範驗證等,須要經過一系列驗證經過以後才能訪問或者存儲數據到etcd當中。以下圖:node
Service account是爲了方便Pod裏面的進程調用Kubernetes API或其餘外部服務而設計的。它與User account不一樣nginx
當建立 pod 的時候,若是沒有指定一個 service account,系統會自動在與該pod 相同的 namespace 下爲其指派一個default service account。而pod和apiserver之間進行通訊的帳號,稱爲serviceAccountName。以下:git
[root@k8s-master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 34d filebeat-ds-s466l 1/1 Running 2 34d myapp-0 1/1 Running 0 3h myapp-1 1/1 Running 0 3h myapp-2 1/1 Running 0 4h myapp-3 1/1 Running 0 4h pod-vol-demo 2/2 Running 0 2d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 2d [root@k8s-master ~]# kubectl get pods/myapp-0 -o yaml |grep "serviceAccountName" serviceAccountName: default [root@k8s-master ~]# kubectl describe pods myapp-0 Name: myapp-0 Namespace: default ...... Volumes: ...... default-token-j5pf5: Type: Secret (a volume populated by a Secret) SecretName: default-token-j5pf5 Optional: false
從上面能夠看到每一個Pod不管定義與否都會有個存儲卷,這個存儲卷爲default-token-*** token令牌,這就是pod和serviceaccount認證信息。經過secret進行定義,因爲認證信息屬於敏感信息,因此須要保存在secret資源當中,並以存儲卷的方式掛載到Pod當中。從而讓Pod內運行的應用經過對應的secret中的信息來鏈接apiserver,並完成認證。每一個 namespace 中都有一個默認的叫作 default 的 service account 資源。進行查看名稱空間內的secret,也能夠看到對應的default-token。讓當前名稱空間中全部的pod在鏈接apiserver時可使用的預製認證信息,從而保證pod之間的通訊。golang
[root@k8s-master ~]# kubectl get sa NAME SECRETS AGE default 1 50d [root@k8s-master ~]# kubectl get sa -n ingress-nginx #前期建立的ingress-nginx名稱空間也存在這樣的serviceaccount NAME SECRETS AGE default 1 11d nginx-ingress-serviceaccount 1 11d [root@k8s-master ~]# kubectl get secret NAME TYPE DATA AGE default-token-j5pf5 kubernetes.io/service-account-token 3 50d mysecret Opaque 2 1d tomcat-ingress-secret kubernetes.io/tls 2 10d [root@k8s-master ~]# kubectl get secret -n ingress-nginx NAME TYPE DATA AGE default-token-zl49j kubernetes.io/service-account-token 3 11d nginx-ingress-serviceaccount-token-mcsf4 kubernetes.io/service-account-token 3 11d
而默認的service account 僅僅只能獲取當前Pod自身的相關屬性,沒法觀察到其餘名稱空間Pod的相關屬性信息。若是想要擴展Pod,假設有一個Pod須要用於管理其餘Pod或者是其餘資源對象,是沒法經過自身的名稱空間的serviceaccount進行獲取其餘Pod的相關屬性信息的,此時就須要進行手動建立一個serviceaccount,並在建立Pod時進行定義。那麼serviceaccount該如何進行定義呢???實際上,service accout也屬於一個k8s資源,以下查看service account的定義方式:redis
[root@k8s-master ~]# kubectl explain sa KIND: ServiceAccount VERSION: v1 DESCRIPTION: ServiceAccount binds together: * a name, understood by users, and perhaps by peripheral systems, for an identity * a principal that can be authenticated and authorized * a set of secrets FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources automountServiceAccountToken <boolean> AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted. Can be overridden at the pod level. imagePullSecrets <[]Object> ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata secrets <[]Object> Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: https://kubernetes.io/docs/concepts/configuration/secret
[root@k8s-master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run #不執行查看定義方式 apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: null name: mysa
[root@k8s-master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml #直接導出爲yaml定義文件,能夠節省敲鍵盤的時間 [root@k8s-master mainfests]# kubectl apply -f serviceaccount.yaml serviceaccount/mysa created [root@k8s-master mainfests]# kubectl get serviceaccount/mysa -o yaml apiVersion: v1 kind: ServiceAccount metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"mysa","namespace":"default"}} creationTimestamp: 2018-10-11T08:12:25Z name: mysa namespace: default resourceVersion: "432865" selfLink: /api/v1/namespaces/default/serviceaccounts/mysa uid: 62fc7782-cd2d-11e8-801a-000c2972dc1f secrets: - name: mysa-token-h2mgk
看到有一個 token 已經被自動建立,並被 service account 引用。設置非默認的 service account,只須要在 pod 的spec.serviceAccountName
字段中將name設置爲您想要用的 service account 名字便可。在 pod 建立之初 service account 就必須已經存在,不然建立將被拒絕。須要注意的是不能更新已建立的 pod 的 service account。json
這裏在default名稱空間建立了一個sa爲admin,能夠看到已經自動生成了一個Tokens:admin-token-7k5nr。vim
[root@k8s-master mainfests]# kubectl create serviceaccount admin serviceaccount/admin created [root@k8s-master mainfests]# kubectl get sa NAME SECRETS AGE admin 1 3s default 1 50d [root@k8s-master mainfests]# kubectl describe sa/admin Name: admin Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: admin-token-7k5nr Tokens: admin-token-7k5nr Events: <none> [root@k8s-master mainfests]# kubectl get secret NAME TYPE DATA AGE admin-token-7k5nr kubernetes.io/service-account-token 3 31s default-token-j5pf5 kubernetes.io/service-account-token 3 50d mysecret Opaque 2 1d tomcat-ingress-secret kubernetes.io/tls 2 10d [root@k8s-master mainfests]# vim pod-sa-demo.yaml #Pod中引用新建的serviceaccount apiVersion: v1 kind: Pod metadata: name: pod-sa-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 serviceAccountName: admin [root@k8s-master mainfests]# kubectl apply -f pod-sa-demo.yaml pod/pod-sa-demo created [root@k8s-master mainfests]# kubectl describe pods pod-sa-demo ...... Volumes: admin-token-7k5nr: Type: Secret (a volume populated by a Secret) SecretName: admin-token-7k5nr Optional: false ......
在K8S集羣當中,每個用戶對資源的訪問都是須要經過apiserver進行通訊認證才能進行訪問的,那麼在此機制當中,對資源的訪問能夠是token,也能夠是經過配置文件的方式進行保存和使用認證信息,能夠經過kubectl config進行查看配置,以下:api
[root@k8s-master mainfests]# kubectl config view apiVersion: v1 clusters: #集羣列表 - cluster: certificate-authority-data: REDACTED server: https://192.168.56.11:6443 name: kubernetes contexts: #上下文列表 - context: #定義哪一個集羣被哪一個用戶訪問 cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes #當前上下文 kind: Config preferences: {} users: #用戶列表 - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED
在上面的配置文件當中,定義了集羣、上下文以及用戶。其中Config也是K8S的標準資源之一,在該配置文件當中定義了一個集羣列表,指定的集羣能夠有多個;用戶列表也能夠有多個,指明集羣中的用戶;而在上下文列表當中,是進行定義可使用哪一個用戶對哪一個集羣進行訪問,以及當前使用的上下文是什麼。如圖:定義了用戶kubernetes-admin能夠對kubernetes該集羣的訪問,用戶kubernetes-user1對Clluster1集羣的訪問tomcat
(1)生成證書 [root@k8s-master pki]# (umask 077;openssl genrsa -out magedu.key 2048) Generating RSA private key, 2048 bit long modulus ............................................................................................+++ ...................................................................................+++ e is 65537 (0x10001) [root@k8s-master pki]# ll magedu.key -rw------- 1 root root 1675 Oct 12 23:52 magedu.key (2)使用ca.crt進行簽署 [root@k8s-master pki]# openssl req -new -key magedu.key -out magedu.csr -subj "/CN=magedu" 證書籤署請求 [root@k8s-master pki]# openssl x509 -req -in magedu.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out magedu.crt -days 365 #證書籤署 Signature ok subject=/CN=magedu Getting CA Private Key [root@k8s-master pki]# openssl x509 -in magedu.crt -text -noout (3)添加到用戶認證 [root@k8s-master pki]# kubectl config set-credentials magedu --client-certificate=./magedu.crt --client-key=./magedu.key --embed-certs=true User "magedu" set. [root@k8s-master pki]# kubectl config set-context magedu@kubernetes --cluster=kubernetes --user=magedu Context "magedu@kubernetes" created. [root@k8s-master pki]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://192.168.56.11:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: magedu name: magedu@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED - name: magedu user: client-certificate-data: REDACTED client-key-data: REDACTED [root@k8s-master pki]# kubectl config use-context magedu@kubernetes Switched to context "magedu@kubernetes". [root@k8s-master pki]# kubectl get pods No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default"
從上面的演示,當切換成magedu用戶進行訪問集羣時,因爲magedu該帳戶沒有管理集羣的權限,因此在獲取pods資源信息時,會提示Forrbidden。那麼下面就再來了解一下怎麼對帳戶進行受權!!!app
Kubernetes的受權是基於插件形式的,其經常使用的受權插件有如下幾種:
讓一個用戶(Users)扮演一個角色(Role),角色擁有權限,從而讓用戶擁有這樣的權限,隨後在受權機制當中,只須要將權限授予某個角色,此時用戶將獲取對應角色的權限,從而實現角色的訪問控制。如圖:
基於角色的訪問控制(Role-Based Access Control, 即」RBAC」)使用」rbac.authorization.k8s.io」 API Group實現受權決策,容許管理員經過Kubernetes API動態配置策略。
在k8s的受權機制當中,採用RBAC的方式進行受權,其工做邏輯是 把對對象的操做權限定義到一個角色當中,再將用戶綁定到該角色,從而使用戶獲得對應角色的權限。此種方式僅做用於名稱空間當中,這是什麼意思呢?當User1綁定到Role角色當中,User1就獲取了對該NamespaceA的操做權限,可是對NamespaceB是沒有權限進行操做的,如get,list等操做。
另外,k8s爲此還有一種集羣級別的受權機制,就是定義一個集羣角色(ClusterRole),對集羣內的全部資源都有可操做的權限,從而將User2,User3經過ClusterRoleBinding到ClusterRole,從而使User二、User3擁有集羣的操做權限。Role、RoleBinding、ClusterRole和ClusterRoleBinding的關係以下圖:
可是這裏有2種綁定ClusterRoleBinding、RoleBinding。也可使用RoleBinding去綁定ClusterRole。
當使用這種方式進行綁定時,用戶僅能獲取當前名稱空間的全部權限。爲何這麼繞呢??舉例有10個名稱空間,每一個名稱空間都須要一個管理員,而該管理員的權限都是一致的。那麼此時須要去定義這樣的管理員,使用RoleBinding就須要建立10個Role,這樣顯得更加繁重。爲此當使用RoleBinding去綁定一個ClusterRole時,該User僅僅擁有對當前名稱空間的集羣操做權限,換句話說,此時只須要建立一個ClusterRole就解決了以上的需求。
這裏要注意的是:RoleBinding僅僅對當前名稱空間有對應的權限。
在RBAC API中,一個角色包含了一套表示一組權限的規則。 權限以純粹的累加形式累積(沒有」否認」的規則)。 角色能夠由命名空間(namespace)內的Role
對象定義,而整個Kubernetes集羣範圍內有效的角色則經過ClusterRole
對象實現。
一個Role
對象只能用於授予對某一單一命名空間中資源的訪問權限
[root@k8s-master ~]# kubectl create role -h #查看角色建立幫助 Create a role with single rule. Examples: # Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods # Create a Role named "pod-reader" with ResourceName specified kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod # Create a Role named "foo" with API Group specified kubectl create role foo --verb=get,list,watch --resource=rs.extensions # Create a Role named "foo" with SubResource specified kubectl create role foo --verb=get,list,watch --resource=pods,pods/status Options: --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. --dry-run=false: If true, only print the object that would be sent, without sending it. -o, --output='': Output format. One of: json|yaml|name|go-template|go-template-file|templatefile|template|jsonpath|jsonpath-file. --resource=[]: Resource that the rule applies to --resource-name=[]: Resource in the white list that the rule applies to, repeat this flag for multiple items --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future. --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. --validate=true: If true, use a schema to validate the input before sending it --verb=[]: Verb that applies to the resources contained in the rule Usage: kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run] [options] 使用kubectl create進行建立角色,指定角色名稱,--verb指定權限,--resource指定資源或者資源組,--dry-run單跑模式並不會建立
Use "kubectl options" for a list of global command-line options (applies to all commands). [root@k8s-master ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml #幹跑模式查看role的定義 apiVersion: rbac.authorization.k8s.io/v1 kind: Role #資源類型 metadata: creationTimestamp: null name: pods-reader rules: - apiGroups: #對那些api組內的資源進行操做 - "" resources: #對那些資源定義 - pods verbs: #操做權限定義 - get - list - watch [root@k8s-master ~]# cd mainfests/ [root@k8s-master mainfests]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml [root@k8s-master mainfests]# vim role-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pods-reader namespace: default rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch [root@k8s-master mainfests]# kubectl apply -f role-demo.yaml #角色建立 role.rbac.authorization.k8s.io/pods-reader created [root@k8s-master mainfests]# kubectl get role NAME AGE pods-reader 3s [root@k8s-master mainfests]# kubectl describe role pods-reader Name: pods-reader Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"default"},"rules":[{"apiGroup... PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch] #此處已經定義了pods-reader這個角色對pods資源擁有get、list、watch的權限
RoleBinding
能夠引用在同一命名空間內定義的Role
對象。
[root@k8s-master ~]# kubectl create rolebinding -h #角色綁定建立幫助 Create a RoleBinding for a particular Role or ClusterRole. Examples: # Create a RoleBinding for user1, user2, and group1 using the admin ClusterRole kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1 Options: --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. --clusterrole='': ClusterRole this RoleBinding should reference --dry-run=false: If true, only print the object that would be sent, without sending it. --generator='rolebinding.rbac.authorization.k8s.io/v1alpha1': The name of the API generator to use. --group=[]: Groups to bind to the role -o, --output='': Output format. One of: json|yaml|name|templatefile|template|go-template|go-template-file|jsonpath-file|jsonpath. --role='': Role this RoleBinding should reference --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future. --serviceaccount=[]: Service accounts to bind to the role, in the format <namespace>:<name> --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. --validate=true: If true, use a schema to validate the input before sending it Usage: kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] [options] 使用kubectl create進行建立角色綁定,指定角色綁定的名稱,--role|--clusterrole指定綁定哪一個角色,--user指定哪一個用戶
Use "kubectl options" for a list of global command-line options (applies to all commands). [root@k8s-master mainfests]# kubectl create rolebinding magedu-read-pods --role=pods-reader --user=magedu --dry-run -o yaml > rolebinding-demo.yaml [root@k8s-master mainfests]# cat rolebinding-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: magedu-read-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pods-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: magedu [root@k8s-master mainfests]# kubectl apply -f rolebinding-demo.yaml #建立角色綁定 rolebinding.rbac.authorization.k8s.io/magedu-read-pods created [root@k8s-master mainfests]# kubectl describe rolebinding magedu-read-pods #查看角色綁定的信息,這裏能夠看到user:magedu綁定到了pods-reader這個角色上 Name: magedu-read-pods Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name":"magedu-read-pods","name... Role: Kind: Role Name: pods-reader Subjects: Kind Name Namespace ---- ---- --------- User magedu [root@k8s-master ~]# kubectl config use-context magedu@kubernetes #切換magedu這個用戶,並使用get獲取pods資源信息 Switched to context "magedu@kubernetes". [root@k8s-master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 36d filebeat-ds-s466l 1/1 Running 2 36d myapp-0 1/1 Running 0 2d myapp-1 1/1 Running 0 2d myapp-2 1/1 Running 0 2d myapp-3 1/1 Running 0 2d pod-sa-demo 1/1 Running 0 1d pod-vol-demo 2/2 Running 0 3d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 4d [root@k8s-master ~]# kubectl get pods -n ingress-nginx #測試獲取ingress-nginx這個名稱空間的pods信息 No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "ingress-nginx"
從上面的操做,能夠總結出,role的定義和綁定,僅做用於當前名稱空間,在獲取ingress-nginx名稱空間時,同樣會出現Forbidden!!!
ClusterRole
對象能夠授予與Role
對象相同的權限,但因爲它們屬於集羣範圍對象, 也可使用它們授予對如下幾種資源的訪問權限:
kubectl get pods --all-namespaces
來查詢集羣中全部的pod)[root@k8s-master mainfests]# kubectl config use-context kubernetes-admin@kubernetes #切換會kubernetes-admin用戶 Switched to context "kubernetes-admin@kubernetes". [root@k8s-master mainfests]# kubectl create clusterrole cluster-read --verb=get,list,watch --resource=pods -o yaml > clusterrole-demo.yaml [root@k8s-master mainfests]# vim clusterrole-demo.yaml #定義clusterrole和權限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-read rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch [root@k8s-master mainfests]# kubectl apply -f clusterrole-demo.yaml #建立clusterrole clusterrole.rbac.authorization.k8s.io/cluster-read configured
這裏咱們須要切換回kubernetes-admin帳戶,是因爲magedu帳戶不具有建立的權限,這也說明普通用戶是沒法進行建立K8S資源的,除非進行受權。以下,咱們另開一個終端,將配置到一個普通用戶ik8s上,使其使用magedu帳戶進行通訊
[root@k8s-master ~]# useradd ik8s [root@k8s-master ~]# cp -rp .kube/ /home/ik8s/ [root@k8s-master ~]# chown -R ik8s.ik8s /home/ik8s/ [root@k8s-master ~]# su - ik8s [ik8s@k8s-master ~]$ kubectl config use-context magedu@kubernetes Switched to context "magedu@kubernetes". [ik8s@k8s-master ~]$ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://192.168.56.11:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: magedu name: magedu@kubernetes current-context: magedu@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED - name: magedu user: client-certificate-data: REDACTED client-key-data: REDACTED
[root@k8s-master mainfests]# kubectl get rolebinding #獲取角色綁定信息 NAME AGE magedu-read-pods 1h [root@k8s-master mainfests]# kubectl delete rolebinding magedu-read-pods #刪除前面的綁定 rolebinding.rbac.authorization.k8s.io "magedu-read-pods" deleted [ik8s@k8s-master ~]$ kubectl get pods #刪除後,在ik8s普通用戶上進行獲取pods資源信息,就立馬出現forbidden了 No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default" [root@k8s-master mainfests]# kubectl create clusterrolebinding magedu-read-all-pods --clusterrole=cluster-read --user=magedu --dry-run -o yaml > clusterrolebinding-demo.yaml [root@k8s-master mainfests]# vim clusterrolebinding-demo.yaml #建立角色綁定,將magedu綁定到clusterrole:magedu-read-all-pods上 apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: magedu-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-read subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: magedu [root@k8s-master mainfests]# kubectl get clusterrole NAME AGE admin 52d cluster-admin 52d cluster-read 13m ...... [root@k8s-master mainfests]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/magedu-read-all-pods created [root@k8s-master mainfests]# kubectl get clusterrolebinding NAME AGE ...... magedu-read-all-pods 10s [root@k8s-master mainfests]# kubectl describe clusterrolebinding magedu-read-all-pods Name: magedu-read-all-pods Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"magedu-read-all-pods","namespace":""... Role: Kind: ClusterRole Name: cluster-read Subjects: Kind Name Namespace ---- ---- --------- User magedu [ik8s@k8s-master ~]$ kubectl get pods #角色綁定後在ik8s終端上進行獲取pods信息,已經不會出現forbidden了 NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 36d filebeat-ds-s466l 1/1 Running 2 36d myapp-0 1/1 Running 0 2d myapp-1 1/1 Running 0 2d myapp-2 1/1 Running 0 2d myapp-3 1/1 Running 0 2d pod-sa-demo 1/1 Running 0 1d pod-vol-demo 2/2 Running 0 4d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 4d [ik8s@k8s-master ~]$ kubectl get pods -n ingress-nginx #更換名稱空間進行查看也是可行的 NAME READY STATUS RESTARTS AGE default-http-backend-7db7c45b69-nqxw9 1/1 Running 1 4d nginx-ingress-controller-6bd7c597cb-9fzbw 1/1 Running 0 4d [ik8s@k8s-master ~]$ kubectl delete pods pod-sa-demo #可是進行刪除pod就沒法進行,由於在受權時是沒有delete權限的 Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "magedu" cannot delete pods in the namespace "default"
從上面的實驗,咱們能夠知道對用戶magedu進行集羣角色綁定,用戶magedu將會獲取對集羣內全部資源的對應權限。
將maedu經過rolebinding到集羣角色magedu-read-pods當中,此時,magedu僅做用於當前名稱空間的全部pods資源的權限
[root@k8s-master mainfests]# kubectl delete clusterrolebinding magedu-read-all-pods clusterrolebinding.rbac.authorization.k8s.io "magedu-read-all-pods" deleted
[root@k8s-master mainfests]# kubectl create rolebinding magedu-read-pods --clusterrole=cluster-read --user=magedu --dry-run -o yaml > rolebinding-clusterrole-demo.yaml [root@k8s-master mainfests]# vim rolebinding-clusterrole-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: magedu-read-pods namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-read subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: magedu [root@k8s-master mainfests]# kubectl apply -f rolebinding-clusterrole-demo.yaml rolebinding.rbac.authorization.k8s.io/magedu-read-pods created [ik8s@k8s-master ~]$ kubectl get pods NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 36d filebeat-ds-s466l 1/1 Running 2 36d myapp-0 1/1 Running 0 2d myapp-1 1/1 Running 0 2d myapp-2 1/1 Running 0 2d myapp-3 1/1 Running 0 2d pod-sa-demo 1/1 Running 0 1d pod-vol-demo 2/2 Running 0 4d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 4d [ik8s@k8s-master ~]$ kubectl get pods -n ingress-nginx No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "ingress-nginx"
RBAC不只僅能夠對user進行訪問權限的控制,還能夠經過group和serviceaccount進行訪問權限控制。當咱們想對一組用戶進行權限分配時,便可將這一組用戶歸併到一個組內,從而經過對group進行訪問權限的分配,達到訪問權限控制的效果。
從前面serviceaccount咱們能夠了解到,Pod能夠經過 spec.serviceAccountName來定義其是以某個serviceaccount的身份進行運行,當咱們經過RBAC對serviceaccount進行訪問受權時,便可以實現Pod對其餘資源的訪問權限進行控制。也就是說,當咱們對serviceaccount進行rolebinding或clusterrolebinding,會使建立Pod擁有對應角色的權限和apiserver進行通訊。如圖: