最好的K8S 安全機制介紹 4 service account secret

service account secret

service account 是一種提供給pod 用的賬號。

pod 與 api server 之間的認證

pod訪問api server時,是以service 的方式進行訪問的,訪問的服務名為kubernetes。kubernetes 服務只在443端口提供。pod 與kubernetes 之間的認證方式通過特殊的認證方式 service account auth 進行認證。

service account auth(SAA)

SAA 與http token 認證的方式類似,但存在以下區別

  • token 來自pod里指定路徑下的一個文件(/run/secrets/kubernetes.io/serviceaccount/token), 這種token是動態生成的,確切的說,是由kubernetes controller 進程用 api server的私鑰(-- service-account-private-key-file 指定的私鑰) 簽名生成的一個JWT secret
  • 在官方提供的客戶端REST 框架代碼里,通過HTTPS 方式 與API SERVER 建立連接后, 會用POD里指定路徑下的一個CA證書(/run/secrets/kubernetes.io/serviceaccount/ca.crt)驗證api server 發來的證書, 驗證是否為CA證書簽名的合法證書。
  • API SERVER 在收到這個token后,采用自己的私鑰(實際上是使用service-account-key-file參數指定的私鑰,如果沒有設置此參數,則默認采用tls-private-key-file指定的參數,即自己的私鑰) 對token 進行合法性驗證。

涉及到的文件總共有三個,起到了類似于secret的作用

  • /run/secrets/kubernetes.io/serviceaccount/token
  • /run/secrets/kubernetes.io/serviceaccount/ca.crt
  • /run/secrets/kubernetes.io/serviceaccount/namespace (pod 客戶端使用這里的指定的namespace 作為參數調用 api server)

我們來看下serviceaccount 與secret的關系

roger@microk8s:~$ kubectl get sa
NAME                                    SECRETS   AGE
default                                 1         75d
nginx-ingress-microk8s-serviceaccount   1         6d3h


roger@microk8s:~$ kubectl describe sa nginx-ingress-microk8s-serviceaccount
Name:                nginx-ingress-microk8s-serviceaccount
Namespace:           default
Labels:              <none>
Annotations:         kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"nginx-ingress-microk8s-serviceaccount","namespace":"defaul...
Image pull secrets:  <none>
Mountable secrets:   nginx-ingress-microk8s-serviceaccount-token-djzgv
Tokens:              nginx-ingress-microk8s-serviceaccount-token-djzgv
Events:              <none>


roger@microk8s:~$ kubectl describe sa default
Name:                default
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-6fh79
Tokens:              default-token-6fh79
Events:              <none>

看看secret里的內容

roger@microk8s:~$ kubectl describe secret default-token-6fh79
Name:         default-token-6fh79
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: f4e65628-6270-11e9-879c-000c29f4dd4d

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tNmZoNzkiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImY0ZTY1NjI4LTYyNzAtMTFlOS04NzljLTAwMGMyOWY0ZGQ0ZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.NjcX2r-WREHIFLkMJEacULVv45yCKshVRXe4VCyqY1xBhpIsZTlDKFL1NsIvYyiBrHXX1CUjTRuWxErMQK1HJN_8KCypWrrGbl2AAkijQ9maDoNlPV0swseS84LZ3I0BCWImuFyfe1E-A1laMpg-vbd2QK32Cz-ESNa8PWdsyjL4xotcyxX7E_8Dc2QhRmxIKUpyrjjnUdKNfxu1jk_ylciwY58Nz1H96fMDRmsJXKmXKf4qRmjpcGOh8vPLby7DJk1OLd7EEvY__mXV4yNFGMqSGP6cniZOFuokBFNFOND2dsXd0wAwqZpTulmnRav4p1yeyb1V1o1PUpotsKS7NQ

每個NAMESPACE下都有一個名為default的默認serviceaccount對象,在這個service account中有一個名為tokens secret,被當做volume掛在到pod的指定目錄里.

  • 名為imagePullSecrets 的secret 用于下載容器鏡像的認證.
  • 名為Tokens的secret 用于訪問 api server的認證

service account 相關的幾個控制器

  • adminssion controller (AC)
  • token controller (TC)
  • serviceaccount controller (SAC)

controller manager 創建了serviceaccount controller 與 token controller , SAC 一直堅挺serviceaccount 和namespace的實踐,如果 namespace 中沒有default service account, SAC 會為該namesapce 創建一個 default' service account

如果controller manager 啟動是指定了API SERVER的私鑰.(service-account-private-key 參數), 那么controller manager 會創建 token controller, token controller也堅挺service acount的實踐,如果發現新的service account 中沒有對應的service account secret,會用API SERVER的私鑰創建一個TOKEN(JWT TOKEN)并用該token, CA證書,以及namespace 名稱三個信息產生一個新的secret對象,放入到新創建的service account中. 如果監聽到 service account的刪除事件,則會自動刪除相關的secret

service account secret 的掛在目錄為 /var/run/secrets/kubernetes.io/serviceaccount

如果文章對您有幫助,請點一下下面的 "喜歡"

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。