理解ConfigMap
什么是ConfigMap
首先來弄明白為什么需要ConfigMap
。對於應用開發來講,特別是后端開發。我們需要連接數據庫,mysql,redis..。這些連接,我們在測試環境,生成環境用的是多套。這就意味着,我們的代碼中有一些配置需要經常改動。所以ConfigMap
就是解決這些問題的。
ConfigMap
是一種API對象,用來將非機密性的數據保存到鍵值對中。使用時,Pods
可以將其用作環境變量、命令行參數或者存儲卷中的配置文件。
ConfigMap
將環境配置信息和容器鏡像解耦,便於應用配置的修改。
不過需要注意的是ConfigMap
本身不提供加密功能。如果要存儲的數據是機密的,使用Secret
,或者使用其他第三方工具來保證你的數據的私密性,而不是用ConfigMap
。
ConfigMap
在設計上不是用來保存大量數據的。在ConfigMap
中保存的數據不可超過1 MiB
。如果你需要保存超出此尺寸限制的數據,你可能希望考慮掛載存儲卷或者使用獨立的數據庫或者文件服務。
ConfigMap的創建
可以使用kubectl create configmap
從文件、目錄或者key-value
字符串創建等創建ConfigMap
。也可以通過kubectl create -f file
創建。
使用key-value 字符串創建
創建name和age
$ kubectl create configmap config-test-1 --from-literal=name=xiaoming --from-literal=age=22
查看結果
$ kubectl get configmap config-test-1 -o go-template='{{.data}}'
map[age:22 name:xiaoming]#
從env文件創建
創建env文件
$ echo -e "name=xiaobai\nage=25" | tee config.env
name=xiaobai
age=25
寫入config-test-1
內容
$ kkubectl create configmap config-test-2 --from-env-file=config.env
configmap/config-test-2 created
查看內容
$ kubectl get configmap config-test-2 -o go-template='{{.data}}'
map[age:25 name:xiaobai]#
從目錄創建
創建對應的目錄
$ mkdir config
$ echo 18>config/age
$ echo xiaohua>config/name
寫入config-test-3
內容
$ kubectl create configmap config-test-3 --from-file=config/
configmap/config-test-3 created
查看寫入的內容
$ kubectl get configmap config-test-3 -o go-template='{{.data}}'
map[age:18
name:xiaohua
]#
通過Yaml/Json創建
apiVersion: v1
kind: ConfigMap
metadata:
name: config-test-4
namespace: default
data:
name: xiaolong
age: 16year # 需要是string
創建
$ kubectl create -f config-test-4.yaml
configmap/config-test-4 created
ConfigMap使用
ConfigMap
可以通過三種方式在Pod中使用,三種分別方式為:設置環境變量、設置容器命令行參數以及在Volume
中直接掛載文件或目錄。
需要注意的點
ConfigMap 必須在 Pod 引用它之前創建
使用 envFrom 時,將會自動忽略無效的鍵
Pod 只能使用同一個命名空間內的 ConfigMap
首先創建 ConfigMap:
$ kubectl create configmap special-config --from-literal=name=long --from-literal=realname=xiaolong
$ kubectl create configmap env-config --from-literal=log_level=INFO
用作環境變量
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: SPECIAL_NAME_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: name
- name: SPECIAL_REALNAME_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: realname
envFrom:
- configMapRef:
name: env-config
restartPolicy: Never
運行之后查看日志
$ kubectl logs -f test-pod
HOSTNAME=test-pod
SPECIAL_NAME_KEY=long
log_level=INFO
SPECIAL_REALNAME_KEY=xiaolong
發現上面的值已成功寫入了
用作命令參數
將ConfigMap
用作命令行參數時,需要先把ConfigMap
的數據保存在環境變量中,然后通過$(VAR_NAME)
的方式引用環境變量。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: ["/bin/sh", "-c", "echo $(SPECIAL_NAME_KEY) $(SPECIAL_REALNAME_KEY)" ]
env:
- name: SPECIAL_NAME_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: name
- name: SPECIAL_REALNAME_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: realname
restartPolicy: Never
運行之后打印日志
$ kubectl logs -f dapi-test-pod
long xiaolong
輸出我們之前的寫入的配置信息
使用volume將ConfigMap作為文件或目錄直接掛載
將創建的ConfigMap
直接掛載至 Pod 的/etc/config
目錄下,其中每一個key-value
鍵值對都會生成一個文件,key
為文件名,value
為內容
apiVersion: v1
kind: Pod
metadata:
name: vol-test-pod
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/sh", "-c", "cat /etc/config/name"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
啟動之后打印輸出
$ kubectl logs -f vol-test-pod
long#
使用subpath將ConfigMap作為單獨的文件掛載到目錄
在一般情況下configmap
掛載文件時,會先覆蓋掉掛載目錄,然后再將congfigmap
中的內容作為文件掛載進行。如果想不對原來的文件夾下的文件造成覆蓋,只是將configmap
中的每個 key,按照文件的方式掛載到目錄下,可以使用subpath
參數。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: nginx
command: ["/bin/sh","-c","sleep 36000"]
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/name
subPath: name
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: name
path: name
restartPolicy: Never
進入到pod中查看
root@dapi-test-pod:/etc/nginx# ls
conf.d mime.types name scgi_params
fastcgi_params modules nginx.conf uwsgi_params
被掛載的ConfigMap內容會被自動更新
當卷中使用的ConfigMap
被更新時,所投射的鍵最終也會被更新。kubelet
組件會在每次周期性同步時檢查所掛載的ConfigMap
是否為最新。 不過,kubelet
使用的是其本地的高速緩存來獲得ConfigMap
的當前值。
ConfigMap
既可以通過watch
操作實現內容傳播(默認形式),也可實現基於TTL
的緩存,還可以直接經過所有請求重定向到API
服務器。 因此,從ConfigMap
被更新的那一刻算起,到新的主鍵被投射到Pod
中去,這一 時間跨度可能與 kubelet 的同步周期加上高速緩存的傳播延遲相等。 這里的傳播延遲取決於所選的高速緩存類型 (分別對應watch
操作的傳播延遲、高速緩存的TTL
時長或者 0)。
以環境變量方式使用的ConfigMap
數據不會被自動更新。 更新這些數據需要重新啟動Pod
。
不可變更的ConfigMap
Kubernetes
特性 不可變更的Secret
和ConfigMap
提供了一種將各個Secret
和ConfigMap
設置為不可變更的選項。對於大量使用 ConfigMap 的 集群(至少有數萬個各不相同的ConfigMap
給Pod
掛載)而言,禁止更改ConfigMap
的數據有以下好處:
-
保護應用,使之免受意外(不想要的)更新所帶來的負面影響。
-
通過大幅降低對
kube-apiserver
的壓力提升集群性能,這是因為系統會關閉 對已標記為不可變更的ConfigMap
的監視操作。
可以通過將immutable
字段設置為true
創建不可變更的ConfigMap
。 例如:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
一旦某ConfigMap
被標記為不可變更,則 無法 逆轉這一變化,,也無法更改data
或binaryData
字段的內容。你只能刪除並重建ConfigMap
。 因為現有的Pod
會維護一個對已刪除的ConfigMap
的掛載點,建議重新創建這些Pods
。
參考
【ConfigMap】https://kubernetes.io/zh/docs/concepts/configuration/configmap/
【ConfigMap】https://feisky.gitbooks.io/kubernetes/content/concepts/configmap.html