ConfigMap詳解

應(yīng)用部署的一個最佳實踐是將應(yīng)用所需的配置信息與程序進行分離,這樣可以使得應(yīng)用程序被更好地復(fù)用,通過不同的配置也能實現(xiàn)更靈活的功能。
將應(yīng)用打包為容器鏡像后,可以通過環(huán)境變量或者外掛文件的方式在創(chuàng)建容器時進行配置注入,但在大規(guī)模容器集群的環(huán)境中,對多個容器進行不同的配置將變得非常復(fù)雜。
從Kubernetes v1.2開始提供了一種統(tǒng)一的應(yīng)用配置管理方案——ConfigMap。本節(jié)對ConfigMap的概念和用法進行詳細描述。

1. ConfigMap概述

ConfigMap供容器使用的典型用法如下:

  1. 生成為容器內(nèi)的環(huán)境變量;
  2. 設(shè)置容器啟動命令的啟動參數(shù)(需設(shè)置為環(huán)境變量);
  3. 以Volume的形式掛載為容器內(nèi)部的文件或目錄。

2. 創(chuàng)建ConfigMap資源對象

2.1 通過yaml配置文件方式創(chuàng)建

下面的例子cm-appvars.yaml描述了將幾個應(yīng)用所需的變量定義為ConfigMap的用法:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  apploglevel: info
  appdatadir: /var/data

執(zhí)行kubectl create命令創(chuàng)建該ConfigMap:

kubectl create -f cm-appvars.yaml

查看創(chuàng)建好的ConfigMap:

# 查看ConfigMap列表
kubectl get configmap
# 查看ConfigMap cm-appvars
kubectl describe configmap cm-appvars
# 以yaml的形式輸出cm-appvars
kubectl get configmap cm-appvars -o yaml

2.2 通過kubectl命令行方式創(chuàng)建

不使用yaml文件,直接通過kubectl create configmap也可以創(chuàng)建ConfigMap,可以使用參數(shù)--from-file--from-literal指定內(nèi)容,并且可以在一行命令中指定多個參數(shù)。
(1)通過--from-file參數(shù)從文件中進行創(chuàng)建,可以指定key的名稱,也可以在一個命令行中創(chuàng)建包含多個key的ConfigMap,語法為:

kubectl create configmap NAME --from-file=[key=]source --from-file=[key=]source

(2)通過--from-file參數(shù)從目錄中進行創(chuàng)建,該目錄下的每個配置文件名稱都被設(shè)置為key,文件的內(nèi)容被設(shè)置為value,語法為:

kubectl create configmap NAME  --from-file=config-files-dir

(3)--from-literal從文本中進行創(chuàng)建,直接將指定的key-value對創(chuàng)建為ConfigMap的內(nèi)容,語法為:

kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2

3. 使用ConfigMap

容器應(yīng)用對ConfigMap的使用有以下兩種方法:

  • 通過環(huán)境變量獲取ConfigMap
  • 通過Volume掛載的方式將ConfigMap中的內(nèi)容掛載為容器內(nèi)部的文件或目錄

3.1 在Pod中使用ConfigMap

(1)通過環(huán)境變量方式使用ConfigMap
以前面創(chuàng)建的ConfigMap “cm-appvars” 為例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  apploglevel: info
  appdatadir: /var/data

在Pod “cm-test-pod” 的定義中,將ConfigMap “cm-appvars” 中的內(nèi)容以環(huán)境變量(APPLOGLEVEL和APPDATADIR)設(shè)置為容器內(nèi)部的環(huán)境變量,容器的啟動命令將顯示這兩個環(huán)境變量的值("env | grep APP"):

apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  containers:
  - name: cm-test
    image: busybox
    command: ["/bin/sh", "-c", "env | grep APP"]
    env:
    - name: APPLOGLEVEL
      valueFrom:
        configMapKeyRef:
          name: cm-appvars
          key: apploglevel
    - name: APPDATADIR
      valueFrom:
        configMapKeyRef:
          name: cm-appvars
          key: appdatadir
    restartPolicy: Never

使用kubectl create -f命令創(chuàng)建該Pod,由于是測試Pod,所以該Pod在執(zhí)行完啟動命令后將會退出,并且不會被系統(tǒng)自動重啟(restartPolicy: Never):

kubectl create -f cm-test-pod.yaml

使用kubectl get pods --show-all 查看已經(jīng)停止的Pod
查看該Pod的日志,可以看到啟動命令“env | grep APP”的執(zhí)行結(jié)果如下:

$ kubectl logs cm-test-pod
APPDATADIR=/var/data
APPLOGLEVEL=info

從Kubernetes v1.6開始,引入了一個新的字段 envFrom ,實現(xiàn)在Pod環(huán)境內(nèi)將ConfigMap(也可用于Secret資源對象)中所定義的key=value自動生成為環(huán)境變量:

apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: cm-appvars
  restartPolicy: Never

通過這個定義,在容器內(nèi)部將生成如下環(huán)境變量:

apploglevel=info
appdatadir=/var/data

需要說明的是,環(huán)境變量的名稱受POSIX命名規(guī)范([a-zA-Z_][a-zA-Z0-9_]*)約束,不能以數(shù)字開頭。
如果包含非法字符,則系統(tǒng)將跳過該條環(huán)境變量的創(chuàng)建,并記錄一個Event來描述環(huán)境變量無法生成,但不會阻止Pod的啟動。

3.2 在 Pod 命令里使用 ConfigMap 定義的環(huán)境變量

我們可以利用$(VAR_NAME)這個 Kubernetes 替換變量,在 Pod 的配置文件的command段使用 ConfigMap 定義的環(huán)境變量。

例子如下:

下面的 Pod 配置

apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(APPLOGLEVEL) $(APPDATADIR)" ]
      env:
        - name: APPLOGLEVEL
          valueFrom:
            configMapKeyRef:
              name: cm-appvars
              key: apploglevel
        - name: APPDATADIR
          valueFrom:
            configMapKeyRef:
              name: cm-appvars
              key: appdatadir
  restartPolicy: Never

3.3 通過volumeMount使用ConfigMap

當(dāng)您使用 --from-file 創(chuàng)建 ConfigMap 時, 文件名將作為鍵名保存在 ConfigMap 的 data 段,文件的內(nèi)容變成鍵值。

從 ConfigMap 里的數(shù)據(jù)生成一個卷

下面的例子展示了一個名為 special-config 的 ConfigMap 的配置:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.level: very
  special.type: charm

在 Pod 的配置文件里的 volumes 段添加 ConfigMap 的名字。 這會將 ConfigMap 數(shù)據(jù)添加到 volumeMounts.mountPath 指定的目錄里面(在這個例子里是 /etc/config)。 command 段引用了 ConfigMap 里的 special.level.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: special-config
  restartPolicy: Never

Pod 運行起來后, 執(zhí)行這個命令 ("ls /etc/config/") 將產(chǎn)生如下的輸出:

special.level
special.type

添加 ConfigMap 數(shù)據(jù)到卷里指定路徑

使用 path 變量定義 ConfigMap 數(shù)據(jù)的文件路徑。 在我們這個例子里,special.level 將會被掛載在 config-volume 的文件 /etc/config/keys 下.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.level
          path: keys
  restartPolicy: Never

Pod 運行起來后,執(zhí)行命令("cat /etc/config/keys")將產(chǎn)生下面的結(jié)果:

very

3.4 使用ConfigMap的限制條件

使用ConfigMap的限制條件如下:

  • ConfigMap必須在Pod之前創(chuàng)建(除非您把 ConfigMap 標(biāo)志成”optional”)。如果您引用了一個不存在的 ConfigMap, 那這個Pod是無法啟動的。就像引用了不存在的 Key 會導(dǎo)致 Pod 無法啟動一樣。
  • ConfigMap受Namespace限制,只有處于相同的Namespace中的Pod可以引用它;
  • ConfigMap中的配額管理還未能實現(xiàn);
  • kubelet值支持可以被API Server管理的Pod使用ConfigMap。kubelet在當(dāng)前Node上通過 --manifest-url--config 自動創(chuàng)建的靜態(tài)Pod將無法引用ConfigMap;
  • 在Pod對ConfigMap進行掛載(volumeMount)操作是,容器內(nèi)部只能掛載為目錄,無法掛載為文件。
  • 在掛載到容器內(nèi)部后,目錄中將包含ConfigMap定義的每個item,如果該目錄下原理還有其他文件,則容器內(nèi)的該目錄會被掛載的ConfigMap覆蓋
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容