ConfigMap线罕,我們知道許多應用經常會有從配置文件、命令行參數或者環(huán)境變量中讀取一些配置信息柒莉,這些配置信息我們肯定不會直接寫死到應用程序中去的闻坚,比如你一個應用連接一個redis服務,下一次想更換一個了的兢孝,還得重新去修改代碼窿凤,重新制作一個鏡像,這肯定是不可取的跨蟹,而ConfigMap就給我們提供了向容器中注入配置信息的能力雳殊,不僅可以用來保存單個屬性,也可以用來保存整個配置文件窗轩,比如我們可以用來配置一個redis服務的訪問地址夯秃,也可以用來保存整個redis的配置文件。
創(chuàng)建
ConfigMap 資源對象使用key-value形式的鍵值對來配置數據痢艺,這些數據可以在Pod里面使用仓洼,ConfigMap和我們后面要講到的Secrets比較類似,一個比較大的區(qū)別是ConfigMap可以比較方便的處理一些非敏感的數據堤舒,比如密碼之類的還是需要使用Secrets來進行管理色建。我們來舉個例子說明下ConfigMap的使用方法:
kind: ConfigMap
apiVersion: v1
metadata:
name: cm-demo
namespace: default
data:
data.1: hello
data.2: world
config: |
property.1=value-1
property.2=value-2
property.3=value-3
其中配置數據在data屬性下面進行配置,前兩個被用來保存單個屬性舌缤,后面一個被用來保存一個配置文件箕戳。
當然同樣的我們可以使用kubectl create -f xx.yaml來創(chuàng)建上面的ConfigMap對象,但是如果我們不知道怎么創(chuàng)建ConfigMap的話国撵,不要忘記kubectl是我們最好的老師陵吸,可以使用kubectl create configmap -h來查看關于創(chuàng)建ConfigMap的幫助信息,
Examples:
# Create a new configmap named my-config based on folder bar
kubectl create configmap my-config --from-file=path/to/bar
# Create a new configmap named my-config with specified keys instead of file basenames on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
# Create a new configmap named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
我們可以看到可以從一個給定的目錄來創(chuàng)建一個ConfigMap對象介牙,比如我們有一個testcm的目錄壮虫,該目錄下面包含一些配置文件,redis和mysql的連接信息环础,如下:
$ ls testcm
redis.conf
mysql.conf
$ cat testcm/redis.conf
host=127.0.0.1
port=6379
$ cat testcm/mysql.conf
host=127.0.0.1
port=3306
然后我們可以使用from-file關鍵字來創(chuàng)建包含這個目錄下面所以配置文件的ConfigMap:
$ kubectl create configmap cm-demo1 --from-file=testcm
configmap "cm-demo1" created
其中from-file參數指定在該目錄下面的所有文件都會被用在ConfigMap里面創(chuàng)建一個鍵值對囚似,鍵的名字就是文件名,值就是文件的內容喳整。
創(chuàng)建完成后谆构,同樣我們可以使用如下命令來查看ConfigMap列表:
$ kubectl get configmap
NAME DATA AGE
cm-demo1 2 17s
可以看到已經創(chuàng)建了一個cm-demo1的ConfigMap對象裸扶,然后可以使用describe命令查看詳細信息:
kubectl describe configmap cm-demo1
Name: cm-demo1
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
mysql.conf:
----
host=127.0.0.1
port=3306
redis.conf:
----
host=127.0.0.1
port=6379
Events: <none>
我們可以看到兩個key是testcm目錄下面的文件名稱框都,對應的value值的話就是文件內容,這里值得注意的是如果文件里面的配置信息很大的話,describe的時候可能不會顯示對應的值魏保,要查看鍵值的話熬尺,可以使用如下命令:
$ kubectl get configmap cm-demo1 -o yaml
apiVersion: v1
data:
mysql.conf: |
host=127.0.0.1
port=3306
redis.conf: |
host=127.0.0.1
port=6379
kind: ConfigMap
metadata:
creationTimestamp: 2018-06-14T16:24:36Z
name: cm-demo1
namespace: default
resourceVersion: "3109975"
selfLink: /api/v1/namespaces/default/configmaps/cm-demo1
uid: 6e0f4d82-6fef-11e8-a101-525400db4df7
除了通過文件目錄進行創(chuàng)建,我們也可以使用指定的文件進行創(chuàng)建ConfigMap谓罗,同樣的粱哼,以上面的配置文件為例,我們創(chuàng)建一個redis的配置的一個單獨ConfigMap對象:
$ kubectl create configmap cm-demo2 --from-file=testcm/redis.conf
configmap "cm-demo2" created
$ kubectl get configmap cm-demo2 -o yaml
apiVersion: v1
data:
redis.conf: |
host=127.0.0.1
port=6379
kind: ConfigMap
metadata:
creationTimestamp: 2018-06-14T16:34:29Z
name: cm-demo2
namespace: default
resourceVersion: "3110758"
selfLink: /api/v1/namespaces/default/configmaps/cm-demo2
uid: cf59675d-6ff0-11e8-a101-525400db4df7
我們可以看到一個關聯(lián)redis.conf文件配置信息的ConfigMap對象創(chuàng)建成功了檩咱,另外值得注意的是--from-file這個參數可以使用多次揭措,比如我們這里使用兩次分別指定redis.conf和mysql.conf文件,就和直接指定整個目錄是一樣的效果了刻蚯。
另外绊含,通過幫助文檔我們可以看到我們還可以直接使用字符串進行創(chuàng)建,通過--from-literal參數傳遞配置信息炊汹,同樣的躬充,這個參數可以使用多次,格式如下:
$ kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=3306
configmap "cm-demo3" created
$ kubectl get configmap cm-demo3 -o yaml
apiVersion: v1
data:
db.host: localhost
db.port: "3306"
kind: ConfigMap
metadata:
creationTimestamp: 2018-06-14T16:43:12Z
name: cm-demo3
namespace: default
resourceVersion: "3111447"
selfLink: /api/v1/namespaces/default/configmaps/cm-demo3
uid: 06eeec7e-6ff2-11e8-a101-525400db4df7
使用
ConfigMap創(chuàng)建成功了讨便,那么我們應該怎么在Pod中來使用呢充甚?我們說ConfigMap這些配置數據可以通過很多種方式在Pod里使用,主要有以下幾種方式:
設置環(huán)境變量的值
在容器里設置命令行參數
在數據卷里面創(chuàng)建config文件
首先霸褒,我們使用ConfigMap來填充我們的環(huán)境變量:
apiVersion: v1
kind: Pod
metadata:
name: testcm1-pod
spec:
containers:
- name: testcm1
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.port
envFrom:
- configMapRef:
name: cm-demo1
這個Pod運行后會輸出如下幾行:
$ kubectl logs testcm1-pod
......
DB_HOST=localhost
DB_PORT=3306
mysql.conf=host=127.0.0.1
port=3306
redis.conf=host=127.0.0.1
port=6379
......
我們可以看到DB_HOST和DB_PORT都已經正常輸出了伴找,另外的環(huán)境變量是因為我們這里直接把cm-demo1給注入進來了,所以把他們的整個鍵值給輸出出來了,這也是符合預期的夹孔。
另外我們可以使用ConfigMap來設置命令行參數汁展,ConfigMap也可以被用來設置容器中的命令或者參數值,如下Pod:
apiVersion: v1
kind: Pod
metadata:
name: testcm2-pod
spec:
containers:
- name: testcm2
image: busybox
command: [ "/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)" ]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.port
運行這個Pod后會輸出如下信息:
$ kubectl logs testcm2-pod
localhost 3306
另外一種是非常常見的使用ConfigMap的方式:通過數據卷使用穆役,在數據卷里面使用ConfigMap,就是將文件填入數據卷梳凛,在這個文件中耿币,鍵就是文件名,鍵值就是文件內容:
apiVersion: v1
kind: Pod
metadata:
name: testcm3-pod
spec:
containers:
- name: testcm3
image: busybox
command: [ "/bin/sh", "-c", "cat /etc/config/redis.conf" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: cm-demo2
運行這個Pod的韧拒,查看日志:
$ kubectl logs testcm3-pod
host=127.0.0.1
port=6379
當然我們也可以在ConfigMap值被映射的數據卷里去控制路徑淹接,如下Pod定義:
apiVersion: v1
kind: Pod
metadata:
name: testcm4-pod
spec:
containers:
- name: testcm4
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/path/to/msyql.conf" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: cm-demo1
items:
- key: mysql.conf
path: path/to/msyql.conf
運行這個Pod的,查看日志:
$ kubectl logs testcm4-pod
host=127.0.0.1
port=3306
另外需要注意的是叛溢,當ConfigMap以數據卷的形式掛載進Pod的時塑悼,這時更新ConfigMap(或刪掉重建ConfigMap),Pod內掛載的配置信息會熱更新楷掉。這時可以增加一些監(jiān)測配置文件變更的腳本厢蒜,然后reload對應服務。