configmap 是 kubernetes 中與 pod、service 同一級別的組件,它裏面以鍵值對的形式存放着創建pod 所需的變量。configmap 存在的意義就是當pod創建時將其所需要的變量都”注入“ pod 中,這裏的”注入“剛開始聽到的時候着實有點困惑,現在覺得這個”注入“也是蠻有道理的。所謂”注入“,就是:當 pod 創建時,需要什麼變量,就從存放這個變量的 configmap 中拿。對比想想 Spring Boot 中的 application.properties 文件,它裏面存放着各種配置,甚至是各種環境下的配置。等代碼中實際使用某個變量時,只需要通過 @Value
這個註解,就可以將配置文件中的變量值注入到代碼的實際變量中。kubernetes 集羣中所有的 configmap 發揮着與 Spring Boot 中的 application.properties 文件相同的作用。
本文參考官方資料:
Configure a Pod to Use a ConfigMap
創建comfigMap
在注入之前必須先創建configmap,並且將相關變量存入其中。創建configmap有三種方式:從目錄創建、從文件創建、從字面量創建。
從字面量創建(literal values)
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
查看結果:kl describe configmaps special-config
Name: special-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
special.how:
----
very
special.type:
----
charm
Events: <none>
special-config 中有兩個 item(條目),key 分別爲:special.how
和 special.type
,他們各自各自的 value 分別爲:very
和 charm
。
從目錄創建
創建目錄並下載兩個文件
# Create the local directory
mkdir -p configure-pod-container/configmap/
# Download the sample files into `configure-pod-container/configmap/` directory
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
從目錄創建 configmap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
查看結果:kubectl describe configmaps game-config
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
configure-pod-container/configmap/
路徑下的文件名爲key
,文件中的內容爲value
從文件創建
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
查看結果:kubectl describe configmaps game-config-2
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
從文件創建並自定義key
在用文件創建configmap時,默認文件名做爲key,文件內容作爲value。但我們可以選擇不用文件名做爲key,而是自己指定,這樣做的目的就是爲了“注入”時用起來方便。
創建configmap:
kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties
查看結果:kubectl get configmaps game-config-3 -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:54:22Z
name: game-config-3
namespace: default
resourceVersion: "530"
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
data:
game-special-key: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
這塊留心看下:data
中的 key 變成了 game-special-key
而不是之前的文件名。
這就是三種創建 configmap 的方式,這是命令行的方式演示的。
注入
創建 configmap 的目的是要將它裏面的值注入到 pod 中去,最後再將這些值“弄到” container ,應爲應用程序是跑在容器中的。將configmap 中的鍵值對“弄到” container 中有兩種方式:
作爲 container 的環境變量
先創建configmap:
kubectl create configmap special-config --from-literal=special.how=very
在上面我們創建了 special-config
這個 configmap。這塊我們將special-config
中的變量作爲container 的環境變量,從而使得 container 中的應用程序就可以使用這些配置變量了。
創建pod:dapi-test-pod
:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
restartPolicy: Never
稍微解釋下: 在上面的 yaml 中 創建了pod:dapi-test-pod
,pod 中用鏡像 :busybox
創建了 容器:test-container
。在test-container
中定義了一個環境變量:SPECIAL_LEVEL_KEY
,這個環境變量的值是從名字叫:special-config
的configmap 中的 key:special.how 的值獲取到的。這塊可能有點繞口,理解萬歲!!!
那怎麼確認有沒有注入成功呢?其實很簡單,我們只需要看下container中是不是有環境變量:SPECIAL_LEVEL_KEY
,並且它的值是不是跟 special-config
中的一樣就可以了。
pod:dapi-test-pod
中執行命令:command: [ "/bin/sh", "-c", "env" ]
這樣會把環境變量打到標準輸出中,我們只需要查看容器的日誌就可以了。
查看日誌:kubectl logs dapi-test-pod
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
SPECIAL_LEVEL_KEY=very
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
至於configmap中的配置變量作爲container的命令行參數,這個用法大家自己查吧,很簡單的。
作爲 container 中路徑下的文件
這種用法是 configmap 中的配置作爲 container 中指定路徑下的文件,configmap 中鍵值對的 key 作爲文件名,value 作爲文件的內容。
這裏我們看個栗子:
先創建configmap,這次用yaml文件的方式,內容如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
special-config 中有兩個鍵值對 SPECIAL_LEVEL: very
和 SPECIAL_TYPE: charm
創建configmap:
kubectl create -f configmap-multikeys.yaml
創建 pod:
kubectl create -f pod-configmap-volume.yaml
pod-configmap-volume.yaml:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
解釋一下:在上面的yaml中,pod:dapi-test-pod
掛載了一個名字叫 special-config
的 configMap
類型的卷 (volume)
,並且給 special-config
取了一個別名叫 config-volume
,這個別名只能被容器 test-container
使用。test-container
將卷:config-volume
掛載到了 /etc/config
路徑下。因爲 special-config
中的配置變量是兩個鍵值對,所以在容器的 /etc/config
路徑下會出來呢兩個文件。
查看日誌:kubectl logs dapi-test-pod
SPECIAL_LEVEL
SPECIAL_TYPE
可以看到日誌中有兩個文件名,但這樣看不是很明顯,爲了看得更清楚些,我們可以選擇進入容器的方式進行查看。
這裏我們得首先修改下yaml文件,因爲上面的 command: [ "/bin/sh", "-c", "ls /etc/config/" ]
命令執行一下就完事了,pod會處於 completed
狀態。只有 running
狀態的 pod 才能進入它裏面的容器。所以,將上面yaml中的command 改爲:
command: ["/bin/sh","-c","while true; do echo 'hello diego'; sleep 3; done "]
進入容器:
kubectl exec -it dapi-test-pod /bin/sh
查看掛載的目錄:
/ # ls /etc/config/
SPECIAL_LEVEL SPECIAL_TYPE
查看文件內容:
cat /etc/config/SPECIAL_TYPE
charm
很明顯,將configmap中的鍵值對掛載了容器的 /etc/config/
路徑下,key是文件名,value是文件內容。
關於 Secret
secret 和 configmap 的存在的意義是一樣的,不同點是 secret 中存放的都是些安全敏感的配置信息,具體內容,後續再整理吧。