Kubernetes筆記(8) - ConfigMap和Secret

<!-- /code_chunk_output -->

ConfigMap和Secret是Kubernetes系統上兩種特殊類型的存儲卷,ConfigMap對象用於爲容器中的應用提供配置數據,Secret對象則用於提供密鑰、證書等敏感的配置信息。它們將相應的配置信息保存於對象中,而後在Pod資源上以存儲卷的形式將其掛載並獲取相關的配置,以實現配置與鏡像文件的解耦。

ConfigMap

配置本身源於代碼,是爲了提高代碼的靈活性而提取出來的一些經常變化的或需要定製的內容。已有一些開源的分佈式系統配置管理系統如Apollo、Diamond、Disconf等。ConfigMap則是Kubernetes提供的統一配置管理方案,一個ConfigMap對象就是一系列配置數據的集合,這些數據可“注入”到Pod對象中,併爲容器應用所使用,注入方式有兩種

  • 掛載爲存儲卷
  • 傳遞爲環境變量

創建ConfigMap對象

ConfigMap對象將配置數據以鍵值對的形式進行存儲,可以使用kubectl create命令創建

kubectl create configmap <map-name> <data-source>

map-name爲ConfigMap對象的名稱,而data-source是數據源,它可以通過這幾種方式來獲取

  • 字面值
  • 文件
  • 目錄
  • 配置清單

無論採用哪一種方式,都要被轉換爲ConfigMap對象中的Key-Value數據。

基於字面值創建

使用--from-literal選項可在命令行直接提供鍵值對:

kubectl create configmap literal-config --from-literal=key1=value1

創建後可以使用kubectl get configmaps dir-config -o yaml命令查看。

基於文件創建

基於文件創建時要使用--from-file選項:

kubectl create configmap file-config --from-file=8_config_file.txt

這種方式創建的ConfigMap對象,其數據存儲的鍵爲文件名,值爲文件內容

apiVersion: v1
data:
  8_config_file.txt: |-
    test
    config
    from
    file
kind: ConfigMap

自定義鍵名的方式:

kubectl create configmap file-config --from-file=file-key1=8_config_file.txt

基於目錄創建

使用--from-file選項時,如果指定的是文件目錄,kubectl會將目錄下的文件分別創建爲鍵值數據。

kubectl create configmap dir-config --from-file=.

使用配置清單創建

配置清單需要指定apiVersion、kind、metadata、data字段,data字段用於存儲鍵值數據:

apiVersion: v1
kind: ConfigMap
metadata:
  name: yaml-config
data:
  key1: value1
  key2: value2

通過環境變量傳遞ConfigMap數據

ConfigMap是名稱空間級別的資源,它必須與引用它的Pod資源在同一空間中; 通過環境變量傳遞ConfigMap的格式爲:

env:
- name: <env-name>
  valueFrom:
    configMapKeyRef: 
      name: <configmap-name>
      key: <key-name>
      optional: <bool>

如果optional指定爲false,則創建引用了ConfigMap資源的Pod對象時,被引用的資源必須事先存在,否則將無法啓動容器,直到被依賴的資源創建完成爲止。 示例:

apiVersion: v1
kind: Pod
metadata:
  name: env-test-pod
  labels:
    app: label-env-test-pod
spec:
  containers:
  - name: env-test-container
    image: busybox
    command: ["/bin/sh", "-c", "env"]
    env:
    - name: MY_KEY1
      valueFrom:
        configMapKeyRef: 
          name: yaml-config
          key: key3
          optional: true
    - name: MY_KEY2
      valueFrom:
        configMapKeyRef: 
          name: yaml-config
          key: key4
          optional: true

envFrom

有時容器需要引用很多ConfigMap資源中的鍵值數據,這種情況下如果爲容器逐一配置環境變量會非常繁瑣,而且不好維護。使用envFrom字段可以直接將ConfigMap資源中的所有鍵值一次性導入。格式爲:

envFrom:
- prefix: <prefix>
  configMapRef:
    name: <configmap-name>
    optional: <bool>

通過ConfigMap存儲卷傳遞數據

如果在ConfigMap中的值體積較大,比如存放的是給容器應用提供的配置文件,那麼使用環境變量將其導入會使得變量值佔據過多的內存空間而且不易處理。這時建議通過ConfigMap存儲卷的方式可以將內容直接作爲文件進行引用。

掛載整個存儲卷

關聯爲Pod資源的存儲卷時,ConfigMap對象中的每個鍵都對應地表現爲一個文件,鍵名爲文件名

apiVersion: v1
kind: Pod
metadata:
  name: configmap-vol
  labels:
    app: configmap-vol
spec:
  containers:
  - name: configmap-vol
    image: busybox
    command: ["/bin/sh", "-c", "sleep 3600"]
    volumeMounts:
    - name: config-vol
      mountPath: /etc/test
      readOnly: true
  volumes:
  - name: config-vol
    configMap:
      name: file-config

掛載後可以將鍵名作爲文件名來查看內容:

kubectl exec configmap-vol -- cat /etc/test/file-key1

掛載存儲卷中的部分鍵值

有時並不希望掛載ConfigMap中的所有內容,可以只掛載存儲卷中的部分鍵值。 格式爲:

volumes:
- name: config-vol
  configMap:
    name: file-config
    items:
    - key: file-key1
      path: file-key1

Secret

Secret資源的功能類似於ConfigMap,但它專用於存放敏感數據,例如密碼、數字證書、私鑰、令牌和SSH key等。 與ConfigMap類似,Secret以鍵值方式存儲數據,在Pod資源中通過環境變量或存儲捲進行數據訪問。 Secret對象的數據的存儲及打印格式爲Base64編碼的字符串,在容器中以環境變量或存儲卷的方式訪問時,它們會被自動解碼爲明文格式。 Secret對象主要有兩種用途:

  • 作爲存儲卷注入到Pod上由容器應用程序所使用
  • 用於kubelet爲Pod裏的容器拉取鏡像時向私有倉庫提供認證信息

Secret資源分爲四種類型:

  • Opaque:自定義數據內容;base64編碼,用來存儲密碼、密鑰、信息、證書等數據,類型標識符爲generic。‰
  • kubernetes.io/service-account-token:Service Account的認證信息,可在創建Service Accout時由Kubernetes自動創建。‰
  • kubernetes.io/dockerconfigjson:用來存儲Docker鏡像倉庫的認證信息,類型標識爲docker-registry。‰
  • kubernetes.io/tls:用於爲SSL通信模式存儲證書和私鑰文件,命令式創建時類型標識爲tls。

創建Secret資源

命令式創建

直接使用字面值創建:

kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=password1

查看base64編碼後的內容:

✗ kubectl get secret mysql-auth -o yaml
apiVersion: v1
data:
  password: cGFzc3dvcmQx
  username: cm9vdA==

使用generic標識創建的Secret爲Opaque類型。下面的示例使用了tls標識來創建tls類型的Secret:

kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt

創建成功後名稱固定爲tls.key和tls.crt,不受證書和私鑰文件的名稱的影響。

基於配置清單創建

基於配置清單創建的示例:

apiVersion: v1
kind: Secret
metadata:
  name: yaml-secret
stringData:
  username: redis
  password: password1
type: Opaqu

這裏使用了stringData,可以用明文的形式設置secret數據,然後在創建爲Secret對象時會自動進行Base64編碼並保存於data字段中;stringData字段中的明文不會被API Server輸出,但如果使用“kubectl apply”命令進行的創建,那麼註解信息中還是可以看到明文信息的。如果用data字段,則必須直接提供Base64編碼後的數據。

Secret存儲卷

雖然Secret數據也可以痛毆環境變量注入,但並不推薦這樣做,因爲容器應用通常會在發生錯誤時將所有環境變量保存於日誌信息中,甚至有些應用在啓動時即會將運行環境打印到日誌中;另外,容器應用調用第三方程序爲子進程時,這些子進程能夠繼承並使用父進程的所有環境變量。 所以建議使用Secret存儲捲來傳遞數據,使用方式與configMap基本相同,但字段爲secret和secretName:

volumes:
- name: secret-vol
  secret:
    secretName: yaml-secret
    items:
    - key: username
      path: username
    - key: password
      path: password

imagePullSecret資源對象

imagePullSecret資源可用於將Secret提供的密碼傳遞給kubelet從而在拉取鏡像前完成認證。 創建imagePullSecret的標識爲docker-registry,有兩種使用方式:

  • 在定義Pod資源時通過“imagePullSecrets”字段指定
  • 將其添加到某特定的ServiceAccount對象中

採用第一張方式,創建docker-registry:

kubectl create secret docker-registry local-registry --docker-username=user1 --docker-password=password1

然後在創建Pod的配置清單中,通過spec.imagePullSecrets字段爲kubelet提供Secret信息:

spec:
  imagePullSecrets:
  - name: local-registry

但這種方式需要爲每個Pod資源顯式定義imagePullSecrets,基於ServiceAccount的的方式可以避免這個問題,後續再做詳細瞭解。

學習資料

《Kubernetes實戰進階》 馬永亮著

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章