我最新最全的文章都在南瓜慢說 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


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

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