https://blog.csdn.net/BigData_Mining/article/details/88529157
API Server作為Kubernetes網關,是訪問和管理資源對象的唯一入口,其各種集群組件訪問資源都需要經過網關才能進行正常訪問和管理。每一次的訪問請求都需要進行合法性的檢驗,其中包括身份驗證、操作權限驗證以及操作規范驗證等,需要通過一系列驗證通過之后才能訪問或者存儲數據到etcd當中。如下圖:
每一個用戶對API資源進行操作都需要通經過以下三個步驟:
第一步:對客戶端訪問進行認證操作,確認是否具有訪問k8s權限
token(共享秘鑰)
SSL(雙向SSL認證)
....通過任何一個認證即表示認證通過,進入下一步
第二步:授權檢查,確認是否對資源具有相關的權限
ABAC(基於屬性的訪問控制)
RBAC(基於角色的訪問控制)
NODE(基於節點的訪問控制)
WEB HOOK(自定義HTTP回調方法的訪問控制)
第三步:准入控制(對操作資源相關聯的其他資源是否有權限操作)
Kubernetes只對以下的API請求屬性進行檢查
user - username,uid group - user group "extra"- 額外信息 API - API資源的對象 Request path - 請求資源的路徑(k8s使用resultful風格接口的API) http://Node_IPaddr:6443/apis/apps/v1/namespaces/namespaces_name/resource_name/ HTTP 請求動作 - HTTP verbs get,post,put,和delete用於非資源請求 HTTP 請求動作映射到 API資源操作- get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用於請求resource Resource -被訪問(僅用於resource 請求)的resource 的ID或名字- *對於使用resource 的請求get,update,patch,和delete,必須提供resource 名稱。 Subresource - 正在訪問的subresource (僅用於請求resource ) Namespace - 正在訪問對象的命名空間(僅針對命名空間的請求資源) API group - 正在訪問的API組(僅用於請求資源)。空字符串指定核心API組。
Secret解決了密碼、token、密鑰等敏感數據的配置問題,而不需要把這些敏感數據暴露到鏡像或者Pod Spec中。Secret可以以Volume或者環境變量的方式使用。
一、Secret
1、Secret類型
Secret有三種類型: Opaque:base64編碼格式的Secret,用來存儲密碼、密鑰等;但數據也通過base64 –decode解碼得到原始數據,所以加密性很弱。 kubernetes.io/dockerconfigjson:用來存儲私有docker registry的認證信息。 kubernetes.io/service-account-token: 用於被serviceaccount引用。serviceaccout創建時Kubernetes會默認創建對應的secret。Pod如果使用了serviceaccount,對應的secret會自動掛載到Pod目錄/run/secrets/ kubernetes.io/serviceaccount中。
2、Opaque Secret
Opaque類型的數據是一個map類型,要求value是base64編碼格式
$ echo -n "admin" | base64 YWRtaW4= $ echo -n "1f2d1e2e67df" | base64 MWYyZDFlMmU2N2Rm
secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
創建secret:kubectl create -f secrets.yml。
# kubectl get secret NAME TYPE DATA AGE default-token-cty7p kubernetes.io/service-account-token 3 45d mysecret Opaque
注意:其中default-token-cty7p為創建集群時默認創建的secret,被serviceacount/default引用。
如果是從文件創建secret,則可以用更簡單的kubectl命令,比如創建tls的secret
kubectl create secret generic helloworld-tls \ --from-file=key.pem \ --from-file=cert.pem
kubernetes.io/service-account-token: 用於被serviceaccount引用。serviceaccout創建時Kubernetes會默認創建對應的secret。Pod如果使用了serviceaccount,對應的secret會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中。
二、ServiceAccount
User Accounts 與 Service Accounts
Kubernetes區分普通帳戶(user accounts)和服務帳戶(service accounts)的原因
-普通帳戶是針對(人)用戶的,服務賬戶針對Pod進程。 -普通帳戶是全局性。在集群所有namespaces中,名稱具有惟一性。 -通常,群集的普通帳戶可以與企業數據庫同步,新的普通帳戶創建需要特殊權限。服務賬戶創建目的是更輕量化,允許集群用戶為特定任務創建服務賬戶。 -普通帳戶和服務賬戶的審核注意事項不同。 -對於復雜系統的配置包,可以包括對該系統的各種組件的服務賬戶的定義。
Token controller
TokenController作為controller-manager的一部分運行。異步行為
-觀察serviceAccount的創建,並創建一個相應的Secret 來允許API訪問。 -觀察serviceAccount的刪除,並刪除所有相應的ServiceAccountToken Secret -觀察secret 添加,並確保關聯的ServiceAccount存在,並在需要時向secret 中添加一個Token。 -觀察secret 刪除,並在需要時對應 ServiceAccount 的關聯
需要使用–service-account-private-key-file 參數選項將Service Account 密匙(key)文件傳遞給controller-manager中的Token controller。key用於 Service Account Token簽名。同樣,也需要使用–service-account-key-file 參數選項將相應的(public key)公匙傳遞給kube-apiserver ,公鑰用於在認證期間驗證Token。
Service Account Controller
Service Account Controller在namespaces里管理ServiceAccount,並確保每個有效的namespaces中都存在一個名為“default”的ServiceAccount。
什么是serviceaccount
Service Account 用來訪問 kubernetes API,通過 kubernetes API 創建和管理,每個 account 只能在一個 namespace 上生效,存儲在 kubernetes API 中的 Secrets 資源。kubernetes 會默認創建,並且會自動掛載到 Pod 中的 /run/secrets/kubernetes.io/serviceaccount 目錄下。
Service account是為了方便Pod里面的進程調用Kubernetes API或其他外部服務而設計的。它與User account不同
1.User account是為人設計的,而service account則是為Pod中的進程調用Kubernetes API而設計; 2.User account是跨namespace的,而service account則是僅局限它所在的namespace; 3.每個namespace都會自動創建一個default service account 4.Token controller檢測service account的創建,並為它們創建secret 5.開啟ServiceAccount Admission Controller后 1.每個Pod在創建后都會自動設置spec.serviceAccount為default(除非指定了其他ServiceAccout) 2.驗證Pod引用的service account已經存在,否則拒絕創建 3.如果Pod沒有指定ImagePullSecrets,則把service account的ImagePullSecrets加到Pod中 4.每個container啟動后都會掛載該service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/
當創建 pod 的時候,如果沒有指定一個 service account,系統會自動在與該pod 相同的 namespace 下為其指派一個default service account。而pod和apiserver之間進行通信的賬號,稱為serviceAccountName。如下:
[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之間的通信。
驗證