Kubernetes之ServiceAccount


ServiceAccount 是什么

Service Account為Pod中的進程和外部用戶提供身份信息。所有的kubernetes集群中賬戶分為兩類,Kubernetes管理的serviceaccount(服務賬戶)和useraccount(用戶賬戶)。

大家都知道api server的集群的入口,對於kunbernetes的api server 是肯定不能隨便訪問。所以我們必須需要一些認證信息。例如:

當用戶訪問集群(例如使用kubectl命令)時,apiserver 會將您認證為一個特定的 User Account(目前通常是admin,除非您的系統管理員自定義了集群配置)。Pod 容器中的進程也可以與 apiserver 聯系。 當它們在聯系 apiserver 的時候,它們會被認證為一個特定的 Service Account。

因為kubernetes是高度模塊化,所有認證方式和授權方式都可以通過插件的方式讓客戶自定義的,可以支持很多種。客戶端請求的時候首先需要進行認證,認證通過后再進行授權檢查,因有些操作需要級聯到其他資源或者環境,但是級聯環境是否有授權權限,這時候需要准入控制。

認證插件

  • bearer token  當使用來自 http 客戶端的 bearer token 時,API server 期望 Authorization header 中包含 Bearer token 的值。Bearer token 必須是一個字符串序列,只需使用 HTTP 的編碼和引用功能就可以將其放入到 HTTP header 中。
  • 客戶端證書  客戶端請求前需要,需要發送api server的辦法的證書,由api server來確認是否他來簽署的,引用的文件必須包含一個或多個證書頒發機構,用於驗證提交給 API server 的客戶端證書。如果客戶端證書已提交並驗證,則使用 subject 的 Common Name(CN)作為請求的用戶名。反過來,api server也要驗證客戶端的證書,所有對於客戶端也應該有一個證書,提供api server 驗證,此過程是雙向驗證。
  • HTTP BASE 認證: 通過用戶名+密碼方式認證。

當啟用了多個認證模塊時,第一個認證模塊成功認證后將短路請求,不會進行第二個模塊的認證。API server 不會保證認證的順序。

用戶賬戶需要哪些信息:

  • user 保護UserName和UID,UserName是標識最終用戶的字符串,UID是標識最終用戶的字符串,比用戶名更加一致切唯一。
  • group 一組將用戶和常規用戶組相關聯的字符串
  • extra  包含其他有用認證信息的字符串列表

上述是來自集群外部的訪問,我們可以理解成是User Account,是給kubernetes集群外部用戶,例如(系統管理員、用戶/租戶等)。Service Account而是給運行在Pod的容器、或者Pod使用的身份認證。

正常情況下,為了確保kubernetes集群的安全性,Api Server 都會給客戶端進行身份認證,但是Pod訪問Kubernetes Api Server服務時,也是需要身份認證的。如下圖:

 

 我們在每一個namespace下看到都有一個secret,而我們看svc的時候,api server通過svc的訪問訪問的,他們的Endpoints是api server。

$ kubectl  get svc 
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   52d
$ kubectl describe svc kubernetes 
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         172.16.138.40:6443,172.16.138.41:6443
Session Affinity:  None
Events:            <none>
$ kubectl get secret  -n default
NAME                  TYPE                                  DATA      AGE
default-token-lplp6   kubernetes.io/service-account-token   3         52d
$ kubectl get secret  -n ingress-nginx
NAME                                       TYPE                                  DATA      AGE
default-token-v58zx                        kubernetes.io/service-account-token   3         52d

每個Namespace下都有一個名為default的默認的 Service Account對象,這個Service Account里面有一個名為Tokens的可以當作Volume一樣被Mount到Pod里的secret,當Pod啟動時候,這個Secret會自動Mount到Pod的指定目錄下,用來完成Pod中的進程訪問API server時的身份認證過程。下面可以看到

$  kubectl describe pod my-demo
.....
Volumes:
  appindex:
    Type:          HostPath (bare host directory volume)
    Path:          /data/pod/myapp
    HostPathType:  DirectoryOrCreate
  default-token-lplp6:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-lplp6
    Optional:    false
.....

創建一個serviceaccount

$ kubectl create serviceaccount jaxzhai
$ kubectl get sa 
NAME      SECRETS   AGE
default   1         52d
jaxzhai   1         8s
$ kubectl describe sa jaxzhai
Name:                jaxzhai
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   jaxzhai-token-9n5th
Tokens:              jaxzhai-token-9n5th
Events:              <none>
$ kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-lplp6   kubernetes.io/service-account-token   3         52d
jaxzhai-token-9n5th   kubernetes.io/service-account-token   3         4m

這里我們看到Kubernetes集群會自動創建一個token的secert,並被jaxzhai這個serviceaccount引用。

設置非默認的 service account,只需要在 pod 的spec.serviceAccountName 字段中將name設置為您想要用的 service account 名字即可。

在 pod 創建之初 service account 就必須已經存在,否則創建將被拒絕。

您不能更新已創建的 pod 的 service account。

在pod中使用service account

apiVersion: v1
kind: Pod
metadata:
  name: my-sa-demo
  namespace: default
  labels:
    name: myapp
    tier: appfront
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: jaxzhai

$ kubectl apply -f myapp-serviceaccount.yaml 
pod/my-sa-demo created
$ kubectl describe pod my-sa-demo 
......
Volumes:
  jaxzhai-token-9n5th:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  jaxzhai-token-9n5th
    Optional:    false
QoS Class:       BestEffort
......

 


免責聲明!

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



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