與Kubernetes交互一般有kubectl、客戶端(Dashboard)、REST API請求。html
用戶使用kubectl、客戶端(Web)、或者REST請求訪問API的時候,Kubernetes內部服務或外部訪問均可得到受權來訪問API。當一個請求達到API的時候,一般會通過如下階段:git
一般在Kubernetes集羣中,API在端口443上提供服務。且一般爲自簽名的證書,在$USER/.kube/config中包含API服務器證書的根證書,該證書在配置時用於代替系統默認根證書。所以須要自定義配置證書時,可將證書寫入$USER/.kube/config。當使用kube-up.sh建立集羣時,此證書會自動寫入$USER/.kube/config。若是羣集有多個用戶,則建立者須要與其餘用戶共享證書。github
創建TLS後,HTTP請求將進行身份驗證,API服務器可配置爲運行一個或多個身份驗證器模塊。json
身份驗證步驟的輸入是整個HTTP請求,可是,它一般只檢查標頭和/或客戶端證書。api
身份驗證模塊包括客戶端證書,Password和Plain Tokens,Bootstrap Tokens和JWT令牌(用於服務賬戶)。安全
能夠指定多個驗證模塊,在這種狀況下,每一個驗證模塊都按順序嘗試,直到其中一個成功。服務器
若是請求沒法經過身份驗證,則會被HTTP狀態碼401拒絕。不然,用戶將被認證爲特定username用戶。網絡
提示:雖然Kubernetes usernames用於訪問控制決策和請求日誌記錄,但它沒有user對象,也沒有在其對象庫中存儲用戶名或有關用戶的其餘信息。app
請求被認證爲來自特定用戶後,必須受權該請求。ide
請求必須包括請求者的用戶名,請求的操做以及受操做影響的對象。若是現有策略聲明用戶有權完成請求的操做,則受權該請求。
Kubernetes使用API服務器受權API請求,同時支持多種受權模塊,如ABAC模式,RBAC模式和Webhook模式。管理員建立集羣時,已配置了應在API服務器中使用的受權模塊。若是配置了多個受權模塊,Kubernetes將檢查每一個模塊,若是任何模塊受權該請求,則該請求能夠繼續。若是全部模塊拒絕該請求,則拒絕該請求(HTTP狀態代碼403)。
示例1:zhangsan
1 { 2 "apiVersion": "abac.authorization.kubernetes.io/v1beta1", 3 "kind": "Policy", 4 "spec": { 5 "user": "zhangsan", 6 "namespace": "projectCaribou", 7 "resource": "pods", 8 "readonly": true 9 } 10 }
解釋:如上所示zhangsan具有的策略,表明zhangsan只能在projectCaribou命名空間中讀取Pod。
請求操做:
1 { 2 "apiVersion": "authorization.k8s.io/v1beta1", 3 "kind": "SubjectAccessReview", 4 "spec": { 5 "resourceAttributes": { 6 "namespace": "projectCaribou", 7 "verb": "get", 8 "group": "unicorn.example.org", 9 "resource": "pods" 10 } 11 } 12 }
解釋:如上是get pods操做將被容許,但不能create或update projectCaribou,由於沒有獲得受權。
Kubernetes在接受到請求時,將對如下屬性進行審查:
Node:一種特殊用途的受權程序,它根據計劃運行的pod爲kubelet授予權限。
ABAC:基於屬性的訪問控制(ABAC)定義了一種訪問控制範例,經過使用將屬性組合在一塊兒的策略向用戶授予訪問權限。策略可使用任何類型的屬性(用戶屬性,資源屬性,對象,環境屬性等)。
RBAC:基於角色的訪問控制(RBAC)是一種根據企業中各個用戶的角色來管理對計算機或網絡資源的訪問的方法。在此上下文中,訪問是單個用戶執行特定任務的能力,例如查看,建立或修改文件。
Webhook:WebHook是一個HTTP回調:發生某些事情時發生的HTTP POST; 經過HTTP POST進行簡單的事件通知。實現WebHooks的Web應用程序會在發生某些事情時將消息發佈到URL。
須要在策略配置中包括一個flag做爲標識,指明須要使用的受權模塊:
提手:能夠選擇多個受權模塊,按順序檢查模塊,以便較早的模塊具備更高的優先級來容許或拒絕請求。
請求到達API server後,默認狀況下,Kubernetes API服務器在2個端口上提供HTTP服務:
從版本1.7開始,Dashboard支持基於如下內容的用戶身份驗證:
Authorization:Bearer <token>:每一個請求都傳遞給Dashboard的標頭。從1.6版開始支持。具備最高優先級。若是存在,則不會顯示登陸界面。
Bearer Token:能夠在Dashboard 登陸界面上使用的token。
Username/password:可在Dashboard 登陸界面上使用用戶名/密碼。
Kubeconfig:可在Dashboard 登陸界面上使用的Kubeconfig文件。
提示:登陸界面已在1.7版中引入,若是您使用的是最新推薦的安裝,則默認狀況下將啓用登陸功能。若手動配置證書,則須要傳遞--tls-cert-file和--tls-cert-key標誌到dashboard。HTTPS端點將在Dashboard容器的8443端口上暴露,能夠經過提供--port標誌進行修改。
Skip選項將設置dashboard使用dashboard服務賬戶的權限。Skip自1.10.1開放,但默認狀況下禁用按鈕。使用--enable-skip-login標誌顯示它。
在經過HTTP方式訪問Dashboard時,使用Authorization header是使Dashboard充當用戶的惟一方法。
提示:因爲普通HTTP流量容易受到MITM攻擊,所以存在一些風險。
要使Dashboard使用Authorization header,須要將Authorization: Bearer <token>每一個請求傳遞到Dashboard。能夠經過在Dashboard前配置反向代理來實現。Proxy將負責身份提供者的身份驗證,並將請求標頭中生成的令牌傳遞給Dashboard。
注意:須要正確配置Kubernetes API服務器才能接受這些令牌。
注意:若是經過apiserver代理訪問儀表板,則受權標頭將不起做用。不管是kubectl proxy和API Server的方式將沒法正常工做。這是由於一旦請求到達API服務器,全部其餘標頭都將被刪除。
每一個服務賬戶都有一個帶有有效承載令牌的機密,可用於登陸儀表板。
1 [root@master ~]# kubectl -n kube-system get secret #查看secret中令牌
提示:全部類型爲'kubernetes.io/service-account-token'的機密信息都容許登陸,它們具備不一樣的權限。
1 [root@master ~]# kubectl -n kube-system describe secrets replicaset-controller-token-vv8fd 2 #獲取replicaset-controller-token-vv8fd的令牌
手動建立一個最高權限名爲的admin的ServiceAccount,並綁定名爲cluster-admin的ClusterRole角色(該角色擁有集羣最高權限)。
1 [root@master ~]# cd dashboard/ 2 [root@master dashboard]# vi admin-token.yml 3 kind: ClusterRoleBinding 4 apiVersion: rbac.authorization.k8s.io/v1beta1 5 metadata: 6 name: admin 7 annotations: 8 rbac.authorization.kubernetes.io/autoupdate: "true" 9 roleRef: 10 kind: ClusterRole 11 name: cluster-admin 12 apiGroup: rbac.authorization.k8s.io 13 subjects: 14 - kind: ServiceAccount 15 name: admin 16 namespace: kube-system 17 --- 18 apiVersion: v1 19 kind: ServiceAccount 20 metadata: 21 name: admin 22 namespace: kube-system 23 labels: 24 kubernetes.io/cluster-service: "true" 25 addonmanager.kubernetes.io/mode: Reconcile 26 [root@master dashboard]# kubectl create -f admin-token.yml 27 [root@master dashboard]# kubectl get secret -n kube-system | grep admin 28 admin-token-6s8zx kubernetes.io/service-account-token 3 94s 29 [root@master dashboard]# kubectl describe secret/admin-token-6s8zx -n kube-system #查看所建立的token 30 [root@master dashboard]# kubectl -n kube-system get secret admin-token-6s8zx -o jsonpath={.data.token} | base64 -d #直接獲取
提示:Bearer Token認證方式本質上是經過ServiceAccount的身份認證加上Bearer token請求API server的方式實現。
默認狀況下禁用基自己份驗證,而建議使用受權模式RBAC和--basic-auth-file標誌配置Kubernetes API服務器。若未配置API服務器會自動回退到匿名用戶,也不會使用Username/password的方式,使用匿名用戶後沒法檢查提供的憑據是否有效。
可經過--authentication-mode=basic標誌開啓儀表板等等基自己份驗證功能。默認狀況下,它設置爲--authentication-mode=token。
1 [root@master ~]# echo "admin,admin,1" >> /etc/kubernetes/basic_auth_file.cvs #建立用戶和密碼 2 [root@master ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml 3 …… 4 - command: 5 - --authorization-mode=basic 6 - --basic-auth-file=/etc/kubernetes/basic_auth_file #追加 7 ……
提示:前面爲用戶,後面爲密碼,數字爲用戶ID,多個用戶不可重複。
如有多個master,以上操做在全部master上執行。
kubeconfig file只支持由--authentication-mode標誌指定的身份驗證,目前不支持外部身份提供程序或基於證書的身份驗證。
kubeconfig的認證可讓擁有該kubeconfig的用戶只擁有一個或幾個命名空間的操做權限,這相比與上面的token的方式更加的精確和安全。
1 [root@master ~]# kubectl -n kube-system get secret admin-token-6s8zx -o jsonpath={.data.token} | base64 -d 2 eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi02czh6eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImNkYzY0ZTQzLTkxY2ItMTFlOS04OTkzLTAwMGMyOWZhN2E3OSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.gEy5jU9Ur6xCnF1QYDTpk5zJ-Vkxh-R3TOj_Pn5B0BytSQYXjDRAgzG6BEPUYtz77Jh32fMoA8VVS1HiybhHWe9TYKgGqDhJQ-TBTlSkbWJsAsIkD3yvd2MS9W1kIWMRLowy0vtjgn4yqxVt0l_rZPM3UcuxL_aPZq3-1-kbMVO-Ysq6x2YoxL__ju6OcIeXD_56WdYbS9VsGQKg4aJHb2NMPaQw0A4S3CClqoESzUlVMS2lUms7xCOvOlZi0-r2cSlNbdetVjhfHBAFj8XAkDxAEpalc_eOk1aBxqbvUtapzBp7wBAEPTbhp5NmqMFKcUruo4Ab59TE0bPO836Hhg 3 [root@master ~]# vi admin_kubeconfig 4 …… 5 token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi02czh6eCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImNkYzY0ZTQzLTkxY2ItMTFlOS04OTkzLTAwMGMyOWZhN2E3OSIsInN1YiI6In-N5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.gEy5jU9Ur6xCnF1QYDTpk5zJ-Vkxh-R3TOj_Pn5B0BytSQYXjDRAgzG6BEPUYtz77Jh32fMoA8VVS1HiybhHWe9TYKgGqDhJQ-TBTlSkbWJsAsIkD3yvd2MS9W1kIWMRLowy0vtjgn4yqxVt0l_rZPM3UcuxL_aPZq3-1-kbMVO-Ysq6x2YoxL__ju6OcIeXD_56WdYbS9VsGQKg4aJHb2NMPaQw0A4S3CClqoESzUlVMS2lUms7xCOvOlZi0-r2cSlNbdetVjhfHBAFj8XAkDxAEpalc_eOk1aBxqbvUtapzBp7wBAEPTbhp5NmqMFKcUruo4Ab59TE0bPO836Hhg #追加3.3所建立的具備最高權限的token
將admin_kubeconfig導出,而後登陸界面的時候在Kubeconfig方式中能夠選擇admin_kubeconfig文件便可。
注意:部署生成的 kubeconfig 文件中沒有 token 字段,須要手動添加該字段。
本質上,dashboard只支持兩種方法,一種是token,一種是user/password。kubeconfig只是提供了一種便利,並非一個新的認證方式,若是要用kubeconfig,要麼使用username/password,要麼使用token。
提示:手動建立kubeconfig可參考:https://jimmysong.io/kubernetes-handbook/guide/kubectl-user-authentication-authorization.html
kubeconfig文件詳解參考:https://jimmysong.io/kubernetes-handbook/guide/authenticate-across-clusters-kubeconfig.html。
若是是在測試環境中,或不考慮安全性的狀況之下。能夠考慮讓外部用戶直接點擊skip進入到dashboard,而且擁有全部的權限。能夠經過將cluster-admin這個擁有全集羣最高權限的ClusterRole綁定到默認使用的ServiceAccount。
1 [root@master ~]# cd dashboard/ 2 [root@master dashboard]# vi kubernetes-dashboard.yaml 3 …… 4 args: 5 - --auto-generate-certificates 6 - --enable-skip-login 7 ……
1 [root@master ~]# cd dashboard/ 2 [root@master dashboard]# vi dashboard-admin.yaml 3 apiVersion: rbac.authorization.k8s.io/v1beta1 4 kind: ClusterRoleBinding 5 metadata: 6 name: kubernetes-dashboard 7 labels: 8 k8s-app: kubernetes-dashboard 9 roleRef: 10 apiGroup: rbac.authorization.k8s.io 11 kind: ClusterRole 12 name: cluster-admin 13 subjects: 14 - kind: ServiceAccount 15 name: kubernetes-dashboard 16 namespace: kube-system 17 [root@master dashboard]# kubectl create -f dashboard-admin.yaml
選擇跳過。
參考文檔:
https://jimmysong.io/posts/user-authentication-in-kubernetes/
https://zhangchenchen.github.io/2017/08/17/kubernetes-authentication-authorization-admission-control/