Kubernetes ConfigMap詳解,多種方式創建、多種方式使用

我最新最全的文章都在 南瓜慢說 www.pkslow.com ,歡迎大家來喝茶!

1 簡介

配置是程序繞不開的話題,在Kubernetes中使用ConfigMap來配置,它本質其實就是鍵值對。本文講解如何通過5種方式創建ConfigMap,通過4種方式使用ConfigMap

2 創建ConfigMap

按大類可分爲兩種方式,細分共有五種方式:

(一)kubectl create configmap創建

  • (1)通過命令行參數字面直接創建

  • (2)通過指定文件創建

  • (3)通過指定目錄創建

  • (4)通過指定環境變量配置文件創建

(二)yaml文件創建

2.1 通過命令kubectl create configmap創建

2.1.1 從字面創建

命令如下:

$ kubectl create configmap pkslow-literal \
--from-literal=pkslow.name=Larry \
--from-literal=pkslow.age=18 \
--from-literal=pkslow.webSite=www.pkslow.com 

通過參數--from-literal直接指定鍵值對。這種方式比較適用於臨時測試使用,而且不適合配置很多的情況。

查看內容如下:

$ kubectl get configmaps pkslow-literal -o yaml

apiVersion: v1
data:
  pkslow.age: "18"
  pkslow.name: Larry
  pkslow.webSite: www.pkslow.com
kind: ConfigMap
metadata:
  name: pkslow-literal
  namespace: default

2.1.2 從文件創建

application.yaml文件內容如下:

server:
  port: 8080
pkslow:
  name: Larry
  age: 18
  webSite: www.pkslow.com

application-uat.yaml文件內容如下:

server:
  port: 8080
pkslow:
  name: LarryDpk
  age: 20
  webSite: https://www.pkslow.com

命令如下:

$ kubectl create configmap pkslow-file \
--from-file=application.yaml \
--from-file=application-uat.yaml

通過參數--from-file來指定文件。查看內容如下:

$ kubectl get configmaps pkslow-file -o yaml

apiVersion: v1
data:
  application-uat.yaml: |-
    server:
      port: 8080
    pkslow:
      name: LarryDpk
      age: 20
      webSite: https://www.pkslow.com
  application.yaml: |-
    server:
      port: 8080
    pkslow:
      name: Larry
      age: 18
      webSite: www.pkslow.com
kind: ConfigMap
metadata:
  name: pkslow-file
  namespace: default

可以看到它的key爲文件名,因爲我們沒有指定,所以默認爲文件名。需要指定則如下:

$ kubectl create configmap pkslow-file \
--from-file=app=application.yaml \
--from-file=uat=application-uat.yaml

2.1.3 從目錄創建

命令如下:

$ kubectl create configmap pkslow-directory --from-file=./

如上一種方式沒有太大差別,只是--from-file後面的參數是目錄,而不是文件。

2.1.4 從環境變量配置文件創建

配置文件pkslow.env內容如下:

PKSLOW_NAME=Larry
PKSLOW_AGE=18
PKSLOW_WEBSITE=www.pkslow.com

創建命令如下:

$ kubectl create configmap pkslow-env --from-env-file=pkslow.env

查看內容如下:

kubectl get configmaps pkslow-env -o yaml

apiVersion: v1
data:
  PKSLOW_AGE: "18"
  PKSLOW_NAME: Larry
  PKSLOW_WEBSITE: www.pkslow.com
kind: ConfigMap
metadata:
  name: pkslow-env
  namespace: default

細心的朋友應該能發現,這種方式如之前的從文件創建很不一樣。它的(key, value)不是(文件名,文件內容),而是文件中一個個的配置。

2.2 通過yaml文件創建

通過yaml文件創建就很常規了,跟普通的kubernetes資源創建沒有什麼區別。先準備yaml文件如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: pkslow-yaml
data:
  PKSLOW_AGE: "18"
  PKSLOW_NAME: Larry
  PKSLOW_WEBSITE: www.pkslow.com
  application-uat.yaml: |-
    server:
      port: 8080
    pkslow:
      name: LarryDpk
      age: 20
      webSite: https://www.pkslow.com
  application.yaml: |-
    server:
      port: 8080
    pkslow:
      name: Larry
      age: 18
      webSite: www.pkslow.com

再通過以下文件創建:

$ kubectl apply -f configmap.yaml

3 Pod使用ConfigMap

Pod中使用ConfigMap有以下四種方式:

  1. 在容器命令和參數內
  2. 容器的環境變量
  3. 在只讀卷裏面添加一個文件,讓應用來讀取
  4. 編寫代碼在 Pod 中運行,使用 Kubernetes API 來讀取 ConfigMap

其中第1種和第2種方式類似,只是啓動命令添加環境變量,所以還是要把ConfigMap映射爲容器的環境變量。

第4種方式要訪問API,可以使用相關的庫,如Spring Cloud Kubernetes,這裏不再介紹。

所以我們主要講解第2、3種方式。

3.1 Pod的環境變量映射

ConfigMap的值映射到環境變量,主要有兩種方式,valueFromenvFrom

3.1.1 valueFrom一一映射

通過valueFrom來配置環境變量,Pod的環境變量名與ConfigMap不必相同。

apiVersion: v1
kind: Pod
metadata:
  name: pkslow-env-value-from
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: PKSLOW_NAME
          valueFrom:
            configMapKeyRef:
              name: pkslow-yaml
              key: PKSLOW_NAME
        - name: PKSLOW_WEBSITE
          valueFrom:
            configMapKeyRef:
              name: pkslow-yaml
              key: PKSLOW_WEBSITE
  restartPolicy: Never

查看結果如下:

$ kubectl logs -f pkslow-env-value-from | grep PKSLOW
PKSLOW_WEBSITE=www.pkslow.com
PKSLOW_NAME=Larry

NOTE:當然也可以把application-uat.yaml這種文件映射成環境變量,但因爲文件內容可能是多行的,我們一般不會這樣做。

3.1.2 envFrom全部映射

通過envFrom會把ConfigMap的所有鍵值對都映射到Pod的環境變量中去。使用如下:

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

查看環境變量如下:

$ kubectl logs -f pkslow-env-env-from 
PKSLOW_WEBSITE=www.pkslow.com
PKSLOW_AGE=18
PKSLOW_NAME=Larry
application.yaml=server:
  port: 8080
pkslow:
  name: Larry
  age: 18
  webSite: www.pkslow.com
application-uat.yaml=server:
  port: 8080
pkslow:
  name: LarryDpk
  age: 20
  webSite: https://www.pkslow.com

顯然看起來這種方式更簡便,不用每個環境變量都配一遍,但它可能會帶來髒數據,就看怎麼使用了。

3.2 加載文件

3.2.1 通過volume加載

可以通過volume的方式把ConfigMap加載進Pod,如下:

apiVersion: v1
kind: Pod
metadata:
  name: pkslow-mount-volume
spec:
  volumes:
    - name: config-volume
      configMap:
        name: pkslow-yaml
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "sleep 1000000" ]
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: config-volume
          mountPath: /data/config
  restartPolicy: Never

進入Pod,查看內容如下:

$ kubectl exec -it pkslow-mount-volume -- /bin/sh
/ # cd /data/config/

/data/config # ls -lrt
total 0
lrwxrwxrwx    1 root     root            23 Feb 21 17:10 application.yaml -> ..data/application.yaml
lrwxrwxrwx    1 root     root            27 Feb 21 17:10 application-uat.yaml -> ..data/application-uat.yaml
lrwxrwxrwx    1 root     root            21 Feb 21 17:10 PKSLOW_WEBSITE -> ..data/PKSLOW_WEBSITE
lrwxrwxrwx    1 root     root            18 Feb 21 17:10 PKSLOW_NAME -> ..data/PKSLOW_NAME
lrwxrwxrwx    1 root     root            17 Feb 21 17:10 PKSLOW_AGE -> ..data/PKSLOW_AGE

/data/config # cat PKSLOW_WEBSITE
www.pkslow.com

/data/config # cat application.yaml
server:
  port: 8080
pkslow:
  name: Larry
  age: 18
  webSite: www.pkslow.com

如果只想要ConfigMap的部分內容,並自定義文件名,可通過items來配置,如下:

apiVersion: v1
kind: Pod
metadata:
  name: pkslow-mount-volume
spec:
  volumes:
    - name: config-volume
      configMap:
        name: pkslow-yaml
        items:
          - key: application.yaml
            path: app.yaml
          - key: application-uat.yaml
            path: uat.yaml
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "sleep 1000000" ]
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: config-volume
          mountPath: /data/config
  restartPolicy: Never

3.2.2 通過subPath加載

通過配置subPath字段,把文件一個一個加載到Pod中去。

apiVersion: v1
kind: Pod
metadata:
  name: pkslow-mount-subpath
spec:
  volumes:
    - name: config-volume
      configMap:
        name: pkslow-yaml
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "sleep 1000000" ]
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: config-volume
          mountPath: /data/config/dev.yaml
          subPath: application.yaml
        - name: config-volume
          mountPath: /data/config/uat.yaml
          subPath: application-uat.yaml
  restartPolicy: Never

查看內容如下:

$ kubectl exec -it pkslow-mount-subpath -- /bin/sh
/ # cd /data/config/

/data/config # ls -lrt
total 8
-rw-r--r--    1 root     root            89 Feb 21 17:31 uat.yaml
-rw-r--r--    1 root     root            78 Feb 21 17:31 dev.yaml

/data/config # cat dev.yaml 
server:
  port: 8080
pkslow:
  name: Larry
  age: 18
  webSite: www.pkslow.com
  
/data/config # cat uat.yaml 
server:
  port: 8080
pkslow:
  name: LarryDpk
  age: 20
  webSite: https://www.pkslow.com

4 不可變的ConfigMap

可以禁止修改ConfigMap,好處有:

  • 保護應用,使之免受意外(不想要的)更新所帶來的負面影響。
  • 通過大幅降低對 kube-apiserver 的壓力提升集羣性能,這是因爲系統會關閉 對已標記爲不可變更的 ConfigMap 的監視操作。

此功能特性由 ImmutableEphemeralVolumes 特性門控 來控制。你可以通過將 immutable 字段設置爲 true 創建不可變更的 ConfigMap。 例如:

apiVersion: v1
kind: ConfigMap
metadata:
  ...
data:
  ...
immutable: true

一旦某 ConfigMap 被標記爲不可變更,則 無法 逆轉這一變化,也無法更改 databinaryData 字段的內容。你只能刪除並重建 ConfigMap。 因爲現有的 Pod 會維護一個對已刪除的 ConfigMap 的掛載點,建議重新創建 這些 Pods。

5 總結

SecretConfigMap的創建與使用也是類似的,不再詳細介紹了。

代碼請查看:https://github.com/LarryDpk/pkslow-samples


歡迎關注微信公衆號<南瓜慢說>,將持續爲你更新...

多讀書,多分享;多寫作,多整理。

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