Kubernetes之ServiceAccount+Secret相關概念


     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之間的通信。
驗證

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM