1. 程式人生 > 其它 >Kubernetes配置管理

Kubernetes配置管理

Kubernetes配置管理

ConfigMap

對於應用的可變配置在 Kubernetes 中是通過一個 ConfigMap 資源物件來實現的,許多應用經常會有從配置檔案、命令列引數或者環境變數中讀取一些配置資訊的需求,這些配置資訊我們肯定不會直接寫死到應用程式中,比如一個應用連線一個 redis 服務,下一次想更換一個,還得重新去修改程式碼,重新制作一個映象,這肯定是不可取的,而ConfigMap 就給我們提供了向容器中注入配置資訊的能力,不僅可以用來儲存單個屬性,還可以用來儲存整個配置檔案,比如我們可以用來配置一個 redis 服務的訪問地址,也可以用來儲存整個 redis 的配置檔案。

建立

ConfigMap資源物件使用key-value形式的鍵值對來配置資料,這些資料可以在Pod裡面使用,如下所示的資源清單:

apiVersion: v1
kind: ConfigMap
metadata:
  name: configMap
data: # <map[string]string>
  xxx

詳細的資源清單:

kind: ConfigMap
apiVersion: v1
metadata:
  name: cm-demo
  namespace: default
data:
  data.1: hello
  data.2: world
  config: |
    property.1=value-1
    property.2=value-2
    property.3=value-3

其中配置資料在 data 屬性下面進行配置,前兩個被用來儲存單個屬性,後面一個被用來儲存一個配置檔案。

當然同樣的我們可以使用kubectl create -f xx.yaml來建立上面的 ConfigMap 物件,但是如果我們不知道怎麼建立 ConfigMap 的話,可以使用kubectl create configmap -h來檢視關於建立 ConfigMap 的幫助資訊:

Examples:
# Create a new configmap named my-config based on folder bar
kubectl create configmap my-config --from-file=path/to/bar

# Create a new configmap named my-config with specified keys instead of file basenames on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

# Create a new configmap named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

可以看到可以從一個給定的目錄來建立一個 ConfigMap 物件,比如我們有一個 testcm 的目錄,該目錄下面包含一些配置檔案,redis 和 mysql 的連線資訊,如下:

$ ls testcm/
mysql.conf  redis.conf

$ cat testcm/mysql.conf 
host=127.0.0.1
port=3306

$ cat testcm/redis.conf 
host=127.0.0.1
port=6379

接著我們就可以使用 from-file 關鍵字來建立包含這個目錄下面所以配置檔案的 ConfigMap

$ kubectl create configmap cm-demo1 --from-file=testcm/
configmap/cm-demo1 created

其中 from-file 引數指定在該目錄下面的所有檔案都會被用在 ConfigMap 裡面建立一個鍵值對,鍵的名字就是檔名,值就是檔案的內容。建立完成後,同樣可以使用如下命令來檢視 ConfigMap 列表:

$ kubectl get config
NAME       DATA   AGE
cm-demo1   2      10m

可以看到已經建立了一個cm-demo1的ConfigMap物件,接著可以使用describe命令檢視詳細資訊:

$ kubectl describe configmap cm-demo1
Name:         cm-demo1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
mysql.conf:
----
host=127.0.0.1
port=3306

redis.conf:
----
host=127.0.0.1
port=6379

Events:  <none>

可以看到兩個 key 是 testcm 目錄下面的檔名稱,對應的 value 值就是檔案內容,這裡值得注意的是如果檔案裡面的配置資訊很大的話,describe 的時候可能不會顯示對應的值,要檢視完整的鍵值,可以使用如下命令:

$ kubectl get cm cm-demo1 -o yaml
apiVersion: v1
data:
  mysql.conf: |
    host=127.0.0.1
    port=3306
  redis.conf: |
    host=127.0.0.1
    port=6379
kind: ConfigMap
metadata:
  creationTimestamp: "2022-01-02T02:58:51Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:mysql.conf: {}
        f:redis.conf: {}
    manager: kubectl
    operation: Update
    time: "2022-01-02T02:58:51Z"
  name: cm-demo1
  namespace: default
  resourceVersion: "4885"
  selfLink: /api/v1/namespaces/default/configmaps/cm-demo1
  uid: 1d4353cc-2bbb-44a0-9b25-b4ac4ca2cafe

除了通過檔案目錄進行建立,我們也可以使用指定的檔案進行建立 ConfigMap,同樣的,以上面的配置檔案為例,我們建立一個 redis 的配置的一個單獨 ConfigMap 物件:

$ kubectl create configmap cm-demo2 --from-file=testcm/mysql.conf 
configmap/cm-demo2 created

可以看到一個關聯mysql.conf 檔案配置資訊的 ConfigMap 物件建立成功了,另外值得注意的是 --from-file 這個引數可以使用多次,比如我們這裡使用兩次分別指定 redis.conf 和 mysql.conf 檔案,就和直接指定整個目錄是一樣的效果了。

另外,通過幫助文件我們可以看到我們還可以直接使用字串進行建立,通過 --from-literal 引數傳遞配置資訊,同樣的,這個引數可以使用多次,格式如下:

$ kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=6379
configmap/cm-demo3 created

$ kubectl get cm cm-demo3 -o yaml
apiVersion: v1
data:
  db.host: localhost
  db.port: "6379"
kind: ConfigMap
metadata:
  creationTimestamp: "2022-01-02T03:19:39Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:db.host: {}
        f:db.port: {}
    manager: kubectl
    operation: Update
    time: "2022-01-02T03:19:39Z"
  name: cm-demo3
  namespace: default
  resourceVersion: "7882"
  selfLink: /api/v1/namespaces/default/configmaps/cm-demo3
  uid: ac114686-f7cd-4da9-86a9-1c6fff3ad8ee

使用

ConfigMap建立成功了,我們應該怎麼在Pod中使用呢?ConfigMap這些配置資料可以通過以下方式在Pod的使用:

  • 設定環境變數的值
  • 在容器中設定命令列引數
  • 在資料卷裡掛載配置檔案

首先使用ConfigMap來填充我們的環境變數,如下所示Pod資源物件:

apiVersion: v1
kind: Pod
metadata:
  name: testcm1-pod
spec:
  containers:
    - name: testcm1
      image: busybox
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.port
      envFrom:
        - configMapRef:
            name: cm-demo1

檢視Pod輸出日誌:

$ kubectl logs testcm1-pod
......
DB_PORT=6379
mysql.conf=host=127.0.0.1
port=3306
redis.conf=host=127.0.0.1
port=6379
DB_HOST=localhost
......

發現與我們的預期一致,DB_HOST和DB_PORT都已經正常輸出了,另外的環境變數是因為我們直接把cm-demo1給注入進來了。

另外我們也可以使用ConfigMap來設定命令列引數:

apiVersion: v1
kind: Pod
metadata:
  name: testcm2-pod
spec:
  containers:
    - name: testcm1
      image: busybox:1.30
      command: ["/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)"]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.port

同樣我們檢視Pod的輸出:

$ kubectl logs testcm2-pod
localhost 6379

另外也可以在資料卷中使用ConfigMap,如下資源物件所示:

apiVersion: v1
kind: Pod
metadata:
  name: testcm3-pod
spec:
  volumes:
    - name: config-volume
      configMap:
        name: cm-demo2
  containers:
    - name: testcm3
      image: busybox:1.30
      command: ["/bin/sh", "-c", "cat /etc/config/mysql.conf"]
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config

執行這個Pod,檢視日誌:

$ kubectl logs testcm3-pod
host=127.0.0.1
port=3306

當然,我們也可以在ConfigMap值被對映的資料卷裡去控制路徑,如下Pod所示:

apiVersion: v1
kind: Pod
metadata:
  name: testcm4-pod
spec:
  volumes:
    - name: config-volume
      configMap:
        name: cm-demo1
        items:
          - key: redis.conf
            path: path/redis.conf   # 定義容器裡的掛載路徑
  containers:
    - name: testcm3
      image: busybox:1.30
      command: ["/bin/sh", "-c", "cat /etc/config/path/redis.conf"]
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config

執行這個Pod,檢視輸出日誌:

$ kubectl logs testcm4-pod
host=127.0.0.1
port=6379

另外需要注意的是,當 ConfigMap 以資料卷的形式掛載進 Pod 的時,這時更新 ConfigMap(或刪掉重建ConfigMap),Pod 內掛載的配置資訊會熱更新。這時可以增加一些監測配置檔案變更的指令碼,然後重載入對應服務就可以實現應用的熱更新。

下面我們建立一個ConfigMap,以資料卷的形式掛載進Pod,動態更新配置資訊。

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm1
data:
  info:
    username:admin
    password:123456

將上面的ConfigMap掛載進Pod

apiVersion: v1
kind: Pod
metadata:
  name: cm-pod
spec:
  containers:
    - name: nginx
      image: nginx:1.17.1
      volumeMounts:
        - name: config
          mountPath: /configMap/config
  volumes:
    - name: config
      configMap:
        name: cm1

進入容器檢視配置:

$ kubectl exec -it cm-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.

root@cm-pod:~# cat /configMap/config/info 
username:admin password:123456

接下來我們進行動態修改ConfigMap:

$ kubectl edit cm cm1
# 這裡我將原來的password:123456改成了admin

修改完成後,再次進入容器檢視配置:

$ kubectl exec -it cm-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
root@cm-pod:/# cat /configMap/config/info 
username:admin password:admin

另外,只有通過 Kubernetes API 建立的 Pod 才能使用 ConfigMap,其他方式建立的(比如靜態 Pod)不能使用;ConfigMap 檔案大小限制為 1MB(ETCD 的要求)。

Secret

一般情況下 ConfigMap 是用來儲存一些非安全的配置資訊,如果涉及到一些安全相關的資料的話用 ConfigMap 就非常不妥了,因為ConfigMap 是明文儲存的,這個時候我們就需要用到另外一個和ConfigMap非常相似的資源物件了:SecretSecret用來儲存敏感資訊,例如密碼、OAuth 令牌和 ssh key 等等,將這些資訊放在 Secret 中比放在 Pod 的定義中或者 Docker 映象中要更加安全和靈活。

Secret主要使用有以下三種類型:

  • Opaque:base64 編碼格式的 Secret,用來儲存密碼、金鑰等;但資料也可以通過base64 –decode解碼得到原始資料,所有加密性很弱。
  • kubernetes.io/dockerconfigjson:用來儲存私有docker registry的認證資訊。
  • kubernetes.io/service-account-token:用於被 ServiceAccount ServiceAccount 建立時 Kubernetes 會預設建立一個對應的 Secret 物件。Pod 如果使用了 ServiceAccount,對應的 Secret 會自動掛載到 Pod 目錄 /run/secrets/kubernetes.io/serviceaccount 中。

Opaque Secret

Opaque 型別的資料是一個 map 型別,要求 value 必須是 base64 編碼格式,比如我們來建立一個使用者名稱為 admin,密碼為 admin321 的 Secret 物件,首先我們需要先把使用者名稱和密碼做 base64 編碼:

$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "admin123" | base64
YWRtaW4xMjM=

接著們使用以上編碼後的資料編寫一個YAML檔案:

apiVersion: v1
kind: Secret
metadata:
  name: s1
type:
  Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4xMjM=

建立後使用kubectl get secret命令進行檢視:

$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-lqrpd   kubernetes.io/service-account-token   3      171m
s1                    Opaque                                2      8s

其中 default-token-lqrpd 為建立叢集時預設建立的 Secret,被 serviceacount/default 引用。

我們可以使用 describe 命令檢視s1的詳情:

kubectl describe secret s1
Name:         s1
Namespace:    default
Labels:       <none>
Annotations:  
Type:         Opaque

Data
====
password:  8 bytes
username:  5 bytes

我們發現Data的資料沒有直接顯示出來,那麼我們可以輸出成yaml檔案檢視:

$ kubectl get secret s1 -o yaml
apiVersion: v1
data:
  password: YWRtaW4xMjM=
  username: YWRtaW4=
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"YWRtaW4xMjM=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"s1","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2022-01-02T05:20:21Z"
  ...... 省略部分內容
  name: s1
  namespace: default
  resourceVersion: "25976"
  selfLink: /api/v1/namespaces/default/secrets/s1
  uid: 1ca8d5b8-27c5-4044-8c02-e5ac8331584b
type: Opaque

建立好Secret物件後,有兩種方式使用:以環境變數的形式和以Volume掛載形式

環境變數

環境變數和上面ConfigMap中的configMapKeyRef類似,在Secret中使用secertKeyRef

apiVersion: v1
kind: Pod
metadata:
  name: s1-pod
spec:
  containers:
    - name: secret1
      image: busybox:1.30
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: USERNAME
          valueFrom:
            secretKeyRef:
              name: s1
              key: username
        - name: PASSWORD
          valueFrom:
            secretKeyRef:
              name: s1
              key: password

同樣檢視Pod輸出日誌:

$ kubectl logs s1-pod
......
USERNAME=admin
PASSWORD=admin123
......

Volume掛載

同樣使用一個Pod驗證Volume掛載:

apiVersion: v1
kind: Pod
metadata:
  name: s1-pod1
spec:
  containers:
    - name: secret1
      image: busybox:1.30
      command: ["/bin/sh", "-c", "ls /etc/secrets"]
      volumeMounts:
        - name: secrets
          mountPath: /etc/secrets
  volumes:
    - name: secrets
      secret:
        secretName: s1

檢視Pod的輸出日誌:

$ kubectl logs s1-pod1
password
username

可以看到 Secret 把兩個 key 掛載成了兩個對應的檔案。當然如果想要掛載到指定的檔案上面,是不是也可以使用上一節的方法:在 secretName 下面新增 items 指定 keypath

apiVersion: v1
kind: Pod
metadata:
  name: s1-pod2
spec:
  volumes:
    - name: secrets
      secret:
        secretName: s1
        items:
          - key: password
            path: secrets/password
  containers:
    - name: s1
      image: busybox:1.30
      command: ["/bin/sh", "-c", "cat /etc/config/secrets/password"]
      volumeMounts:
        - name: secrets
          mountPath: /etc/config

同樣檢視pod的輸出日誌:

$ kubectl logs s1-pod2
admin123

kubernetes.io/dockerconfigjson

除了上面Opaque這種型別外,還可以建立使用者docker registry認證的Secret,直接使用kubectl create命令建立即可:

$ kubectl create secret docker-registry myregistry \
	--docker-server=DOCKER_SERVER \
	--docker-username=DOCKER_USER\
 	--docker-password=DOCKER_PASSWORD\
 	--docker-email=DOCKER_EMAIL

我們可以通過指定檔案的方式來建立映象倉庫認證任資訊,需要主要對應的KEYTYPE

首先我們登入docker:

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: huiyichanmian
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

登入成功後,docker會把登入資訊存放在``~/.docker/config.json`這個檔案裡。

接下來我們建立映象倉庫認證資訊:

$ kubectl create secret generic myregistry \
	--from-file=.dockerconfigjson=/root/.docker/config.json \
	--type=kubernetes.io/dockerconfigjson

檢視Secret列表:

$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-lqrpd   kubernetes.io/service-account-token   3      6h9m
myregistry            kubernetes.io/dockerconfigjson        1      22s
myregistry1           kubernetes.io/dockerconfigjson        1      42s

myregistry對應的TYPEkubernetes.io/dockerconfigjson,同樣可以使用describe命令來檢視詳細資訊:

$ kubectl describe secret myregistry
Name:         myregistry
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  152 bytes

Data區域的資料沒有直接展示,我們使用-o yaml來輸出:

$ kubectl get secret myregistry -o yaml
apiVersion: v1
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOiB7CgkJCSJhdXRoIjogImFIVnBlV2xqYUdGdWJXbGhianBqYUhKcGMzUnBZVzQ0TWpVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDYuMy1jZSAobGludXgpIgoJfQp9
kind: Secret
metadata:
  creationTimestamp: "2022-01-02T08:38:01Z"
  .....
  uid: 37b13407-b5d2-4513-a8cf-6dee65acc2bf
type: kubernetes.io/dockerconfigjson

我們把上面data.dockerconfigjson的資料做一個base64解碼:

$ echo eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= | base64 -d
{"auths":{"DOCKER_SERVER":{"username":"DOCKER_USER","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRVI6RE9DS0VSX1BBU1NXT1JE"}}}

如果我們需要拉去私有倉庫中的Docker映象,就需要使用上面的myregistry這個Secret:

apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: foo
    image: 192.168.1.100:5000/test:v1
  imagePullSecrets:
  - name: myregistry
  • ImagePullSecrets

    ImagePullSecretsSecrets 不同,因為 Secrets 可以掛載到 Pod 中,但是 ImagePullSecrets 只能由 Kubelet 訪問。

我們需要拉取私有倉庫映象 192.168.1.100:5000/test:v1,我們就需要針對該私有倉庫來建立一個如上的 Secret,然後在 Pod 中指定 imagePullSecrets

kubernetes.io/service-account-token

kubernetes.io/service-account-token用於被 ServiceAccount 引用。ServiceAccout 建立時 Kubernetes 會預設建立對應的 Secret。Pod 如果使用了 ServiceAccount,對應的 Secret 會自動掛載到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目錄中。如下所示我們隨意建立一個 Pod:

$ kubectl run secret-pod --image nginx:1.17.1

檢視這個pod的詳細資訊:

......
spec:
  containers:
  - image: nginx:1.17.1
    imagePullPolicy: IfNotPresent
    name: secret-pod
   ......
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-lqrpd
      readOnly: true
......
  serviceAccount: default
  serviceAccountName: default
  volumes:
  - name: default-token-lqrpd
    secret:
      defaultMode: 420
      secretName: default-token-lqrpd

可以看到預設把名為 default(自動建立的)的 ServiceAccount 對應的 Secret 物件通過 Volume 掛載到了容器的 /var/run/secrets/kubernetes.io/serviceaccount 的目錄中。

同樣 Secret 檔案大小限制為 1MB(ETCD 的要求);Secret 雖然採用 Base64 編碼,但是我們還是可以很方便解碼獲取到原始資訊,所以對於非常重要的資料還是需要慎重考慮。

ServiceAccount

ServiceAccount 主要是用於解決 Pod 在叢集中的身份認證問題的。認證使用的授權資訊其實就是利用前面所說的 kubernetes.io/service-account-token 進行管理的。

介紹

ServiceAccount 是名稱空間級別的,每一個名稱空間建立的時候就會自動建立一個名為 defaultServiceAccount 物件:

$ kubectl create namespace dev
namespace/dev created

$ kubectl get serviceaccount -n dev
NAME      SECRETS   AGE
default   1         22s

$  kubectl get secret -n dev
NAME                  TYPE                                  DATA   AGE
default-token-qxvm4   kubernetes.io/service-account-token   3      70s

這個ServiceAccount會自動關聯到一個Secret物件上:

$ kubectl get sa default -n dev -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2022-01-02T09:21:03Z"
  name: default
  namespace: dev
  resourceVersion: "61354"
  selfLink: /api/v1/namespaces/dev/serviceaccounts/default
  uid: 0cfe3ea8-0255-434a-84ec-82f9c9e60fee
secrets:
- name: default-token-qxvm4

這個 Secret 物件是 ServiceAccount 控制器自動建立的,我們可以檢視這個關聯的 Secret 物件資訊:

# kubectl get secret default-token-qxvm4 -n dev -o yaml
apiVersion: v1
data:
  ca.crt: LS0...
  namespace: ZGV2
  token: ZXlKaGJ...
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: 0cfe3ea8-0255-434a-84ec-82f9c9e60fee
  creationTimestamp: "2022-01-02T09:21:03Z"
  ......
  name: default-token-qxvm4
  namespace: dev
  resourceVersion: "61353"
  selfLink: /api/v1/namespaces/dev/secrets/default-token-qxvm4
  uid: 0277b6f3-5e22-405d-a4fa-e64b7bbd4bc5
type: kubernetes.io/service-account-token

data區域,我們可以看到三個資訊:

  • ca.crt:用於校驗服務端的證書資訊
  • namespace:表示當前管理的名稱空間
  • token:用於 Pod 身份認證的 Token

預設情況下當前 namespace 下面的 Pod 會預設使用 default 這個 ServiceAccount,對應的 Secret 會自動掛載到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目錄中,這樣我們就可以在 Pod 裡面獲取到用於身份認證的資訊了。

實現原理

實際上這個自動掛載過程是在 Pod 建立的時候通過 Admisson Controller(准入控制器) 來實現的。

  • Admisson Controller

    Admission Controller(准入控制)是 Kubernetes API Server 用於攔截請求的一種手段。Admission 可以做到對請求的資源物件進行校驗,修改,Pod 建立時 Admission Controller 會根據指定的的 ServiceAccount(預設的 default)把對應的 Secret 掛載到容器中的固定目錄下 /var/run/secrets/kubernetes.io/serviceaccount/

當我們在 Pod 裡面訪問叢集的時候,就可以預設利用掛載到 Pod 內部的 token 檔案來認證 Pod 的身份,ca.crt 則用來校驗服務端。在 Pod 中訪問 Kubernetes 叢集的一個典型的方式如下圖所示:

程式碼中我們指定了 ServiceAccount 背後的 Secret 掛載到 Pod 裡面的兩個檔案:tokenca.crt,然後通過環境變數獲取到 APIServer 的訪問地址(前面我們提到過會把 Service 資訊通過環境變數的方式注入到 Pod 中),然後通過 ca.cart 校驗服務端是否可信,最後服務端會根據我們提供的 token 檔案對 Pod 進行認證。

Pod 身份被認證合法過後,具體具有哪些資源的訪問許可權,就需要通過後面的 RBAC 來進行聲明瞭。