環境說明:
主機名 | 操作系統版本 | ip | docker version | kubelet version | 配置 | 備註 |
---|---|---|---|---|---|---|
master | Centos 7.6.1810 | 172.27.9.131 | Docker 18.09.6 | V1.14.2 | 2C2G | master主機 |
node01 | Centos 7.6.1810 | 172.27.9.135 | Docker 18.09.6 | V1.14.2 | 2C2G | node節點 |
node02 | Centos 7.6.1810 | 172.27.9.136 | Docker 18.09.6 | V1.14.2 | 2C2G | node節點 |
k8s集羣部署詳見:Centos7.6部署k8s(v1.14.2)集羣
k8s學習資料詳見:基本概念、kubectl命令和資料分享
一、概述
1. ConfigMap
在實際的應用部署中, 經常需要爲各種應用/中間件配置各種參數, 如數據庫地址、 用戶名、 密碼等, 而且大多數生產環境中的應用程序配置較爲複雜, 可能是多個 Config 文件、 命令行參數和環境變量的組合。 要完成這樣的任務有很多種方案, 比如:
- 1.可以直接在打包鏡像的時候寫在應用配置文件裏面,但這種方式的壞處顯而易見,因爲在應用部署中往往需要修改這些配置參數,或者說製作鏡像時並不知道具體的參數配置,一旦打包到鏡像中將無法更改配置。另外,部分配置信息涉及安全信息(如用戶名、 密碼等),打包人鏡像容易導致安全隱患;
- 2.可以在配置文件裏面通過ENV環境變量傳入,但是如若修改ENV就意味着要修改yaml文件,而且需要重啓所有的容器才行;
- 3.可以在應用啓動時在數據庫或者某個特定的地方取配置文件。
顯然,前兩種方案不是最佳方案,而第三種方案實現起來又比較麻煩。爲了解決這個難題,kubernetes引入ConfigMap這個API資源來滿足這一需求。
2. 爲什麼需要ConfigMap和Secret
ConfigMap和Secret是Kubernetes系統上兩種特殊類型的存儲卷,ConfigMap象用於爲容器中的應用提供配置數據以定製程序的行爲,不過敏感的配置信息,例如密鑰、證書等通常由Secret對象來進行配置。它們將相應的配置信息保存於對象中,而後在Pod資源上以存儲卷的形式將其掛載並獲取相關的配置,以實現配置與鏡像文件的解耦。
3. ConfigMap作用
- 向容器傳遞命令行參數
- 爲每個容器設置自定義環境變量
- 通過特殊類型的卷將配置文件掛載到容器中
二、準備工作
製作基礎鏡像loong576/date-random,創建pod date-random-configmap,pod中包含容器centos-date和nginx-server,其中容器centos-date由鏡像loong576/date-random創建,通過訪問容器nginx-server驗證參數是否生效。
1. 製作鏡像
製作鏡像loong576/date-random並上傳dockerhub
[root@master loong576]# more Dockerfile
FROM centos:centos7.6.1810
ADD date-random.sh /usr/bin/date-random
ENTRYPOINT /usr/bin/date-random
[root@master loong576]# more date-random.sh
#!/bin/bash
mkdir /var/htdocs
while :
do
/usr/bin/echo "date is : " `date` >> /var/htdocs/index.html
/usr/bin/echo "RANDOM is : " `echo $RANDOM` >> /var/htdocs/index.html
sleep 5
done
[root@master loong576]# docker build -t loong576/date-random .
Sending build context to Docker daemon 4.096kB
Step 1/3 : FROM centos:centos7.6.1810
---> f1cb7c7d58b7
Step 2/3 : ADD date-random.sh /usr/bin/date-random
---> 58296331ae70
Step 3/3 : ENTRYPOINT /usr/bin/date-random
---> Running in e9a3184518e7
Removing intermediate container e9a3184518e7
---> 07db2452d706
Successfully built 07db2452d706
Successfully tagged loong576/date-random:latest
[root@master loong576]# docker images |grep loong576/date-random
loong576/date-random latest 07db2452d706 24 seconds ago 202MB
基礎鏡像爲centos:centos7.6.1810,向其中寫入腳本date-random.sh並執行,該腳本運行date和echo $RANDOM命令,前者輸出當前時間,後者輸出0~32767之間的隨機數,腳本循環時間爲5秒。
2. 上傳dockerhub
[root@master loong576]# docker push loong576/date-random
The push refers to repository [docker.io/loong576/date-random]
ec4ecb05d6b3: Pushed
89169d87dbe2: Layer already exists
latest: digest: sha256:a680438f09b92f40b38f3da5f9ea34e4b3561c540f1093d9cbcc2385c0184551 size: 736
上傳至dockerhub前需執行登錄操作docker login
3. 驗證鏡像
[root@master loong576]# more date-random-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
name: date-random-configmap
spec:
containers:
- image: loong576/date-random
name: centos-date
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: nginx
name: nginx-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: html
emptyDir: {}
[root@master loong576]# kubectl apply -f date-random-configmap.yaml
pod/date-random-configmap created
[root@master loong576]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
date-random-configmap 2/2 Running 0 14s 10.244.1.203 node01 <none> <none>
[root@master loong576]# curl 10.244.1.203
date is : Mon Sep 16 02:51:21 UTC 2019
RANDOM is : 17563
date is : Mon Sep 16 02:51:26 UTC 2019
RANDOM is : 434
date is : Mon Sep 16 02:51:31 UTC 2019
RANDOM is : 18246
date is : Mon Sep 16 02:51:36 UTC 2019
RANDOM is : 2225
運行date-random-configmap.yaml並訪問容器nginx-server(nginx默認端口爲80),發現每5秒輸出date和隨機數,符合預期。
三、容器中的配置數據傳遞
1. 容器的ENTRYPOINT和CMD
Dockerfile中的兩種指令分別定義命令與參數這兩個部分:
- ENTRYPOINT定義容器啓動時運行的命令。
- CMD指定傳遞給ENTRYPOINT的參數。
CMD也可以執行命令,一般爲默認的啓動命令。
k8s中與ENTRYPOINT和CMD對應的如下:
Docker | Kubernetes | 說明 |
---|---|---|
ENTRYPOINT | command | 在容器中執行可執行程序 |
CMD | args | 傳遞給可執行程序的參數 |
pod中指定自定義命令和參數
[root@master loong576]# more nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
command: ["/bin/echo"]
args: ["hello","world"]
[root@master loong576]# kubectl apply -f nginx.yaml
pod/nginx created
[root@master loong576]# kubectl logs nginx
hello world
可以查看日誌可以看到pod nginx的輸出爲'hello world',與pod裏面command和args中的定義一致。
2. 向容器傳遞命令行參數
2.1 循環間隔參數化
[root@master loong576]# more date-random.sh
#!/bin/bash
mkdir /var/htdocs
INTERVAL=$1
while :
do
/usr/bin/echo "date is : " `date` >> /var/htdocs/index.html
/usr/bin/echo "RANDOM is : " `echo $RANDOM` >> /var/htdocs/index.html
sleep $INTERVAL
done
[root@master loong576]# more Dockerfile
FROM centos:centos7.6.1810
ADD date-random.sh /usr/bin/date-random
ENTRYPOINT ["/usr/bin/date-random"]
CMD ["10"]
[root@master loong576]# docker build -t loong576/date-random:args .
Sending build context to Docker daemon 5.12kB
Step 1/4 : FROM centos:centos7.6.1810
---> f1cb7c7d58b7
Step 2/4 : ADD date-random.sh /usr/bin/date-random
---> 307e2f66dfa4
Step 3/4 : ENTRYPOINT ["/usr/bin/date-random"]
---> Running in ab41b93f6b28
Removing intermediate container ab41b93f6b28
---> 5f536f70da1f
Step 4/4 : CMD ["10"]
---> Running in 90f5d58c68fb
Removing intermediate container 90f5d58c68fb
---> 8bf9ce828481
Successfully built 8bf9ce828481
Successfully tagged loong576/date-random:args
[root@master loong576]# docker push loong576/date-random:args
The push refers to repository [docker.io/loong576/date-random]
200d475bbffa: Pushed
89169d87dbe2: Layer already exists
args: digest: sha256:08e4c791dc9d6b71ce45b13768ab09194cc11ecd4856b52f2719372d912ee9c1 size: 736
將之前的循環間隔5秒修改爲參數INTERVAL,在Dockerfile中傳遞該參數值爲10秒,上傳dockerhub。Dockerfile中ENTRYPOINT和CMD後面的[]表明執行格式爲Exec,區別於之前的Shell格式。
2.2 Docker運行帶參數鏡像
[root@master loong576]# docker run -itd --name centos-args loong576/date-random:args
159e3204dad64516adc4681e9d7b1fe9f4d11a178e3cca7e9a9f13fd10252a43
[root@master loong576]# docker run -d --name centos-args loong576/date-random:args
ee938a39167afb52fe72f9367ad23d9e8b2985037320ad1ccc6ec7e3f9bc9255
[root@master loong576]# docker exec -it centos-args sh
sh-4.2# [root@master loong576]#
[root@master loong576]#
[root@master loong576]#
[root@master loong576]# docker run -it --name centos-args loong576/date-random:args
[root@master loong576]# docker run -itd --name centos-args loong576/date-random:args
2a25e91a0f5b54c1c568ce089d879d50cd9a12513be5d365dc5743d74f2ac737
[root@master loong576]# docker ps |grep centos
2a25e91a0f5b loong576/date-random:args "/usr/bin/date-rando…" 18 seconds ago Up 16 seconds centos-args
[root@master loong576]# docker exec -it centos-args sh
sh-4.2# cd /var/htdocs/
sh-4.2# ls -alrt
total 4
drwxr-xr-x 1 root root 20 Sep 16 07:24 ..
drwxr-xr-x 2 root root 24 Sep 16 07:24 .
-rw-r--r-- 1 root root 234 Sep 16 07:25 index.html
sh-4.2# tail -f index.html
date is : Mon Sep 16 07:24:31 UTC 2019
RANDOM is : 26700
date is : Mon Sep 16 07:24:41 UTC 2019
RANDOM is : 13556
date is : Mon Sep 16 07:24:51 UTC 2019
RANDOM is : 7320
date is : Mon Sep 16 07:25:01 UTC 2019
RANDOM is : 6041
date is : Mon Sep 16 07:25:11 UTC 2019
RANDOM is : 23591
^C
sh-4.2#
index.html輸出的巡檢間隔爲10秒,證明Dockerfile設置生效。
2.3 Docker直接指定參數運行鏡像
指定循環間隔爲3秒
[root@master loong576]# docker run -itd --name centos-args2 loong576/date-random:args 3
498e48dabb0b2eb15366286d7cfd317774cf993a98c19310e3b3fe2aad9d8d6a
[root@master loong576]# docker ps |grep centos
498e48dabb0b loong576/date-random:args "/usr/bin/date-rando…" 7 seconds ago Up 5 seconds centos-args2
2a25e91a0f5b loong576/date-random:args "/usr/bin/date-rando…" 6 minutes ago Up 6 minutes centos-args
[root@master loong576]# docker exec -it centos-args2 sh
sh-4.2# tail -f /var/htdocs/index.html
date is : Mon Sep 16 07:31:24 UTC 2019
RANDOM is : 17156
date is : Mon Sep 16 07:31:27 UTC 2019
RANDOM is : 30995
date is : Mon Sep 16 07:31:30 UTC 2019
RANDOM is : 24714
date is : Mon Sep 16 07:31:33 UTC 2019
RANDOM is : 11670
date is : Mon Sep 16 07:31:36 UTC 2019
RANDOM is : 32253
date is : Mon Sep 16 07:31:39 UTC 2019
RANDOM is : 18917
^C
sh-4.2#
可以看到index.html的輸出間隔時間爲3秒
2.4 pod中定義傳遞的參數值
定義pod date-random-configmap-args,設置傳遞容器的參數值爲4.
[root@master loong576]# more date-random-configmap-args.yaml
apiVersion: v1
kind: Pod
metadata:
name: date-random-configmap-args
spec:
containers:
- image: loong576/date-random:args
args: ["4"]
name: centos-date
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: nginx
name: nginx-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: html
emptyDir: {}
[root@master loong576]# kubectl apply -f date-random-configmap-args.yaml
pod/date-random-configmap-args created
[root@master loong576]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
date-random-configmap 2/2 Running 0 5h2m 10.244.1.203 node01 <none> <none>
date-random-configmap-args 2/2 Running 0 100s 10.244.2.209 node02 <none> <none>
nginx 0/1 CrashLoopBackOff 20 81m 10.244.1.205 node01 <none> <none>
[root@master loong576]# curl 10.244.2.209
date is : Mon Sep 16 07:52:37 UTC 2019
RANDOM is : 5067
date is : Mon Sep 16 07:52:41 UTC 2019
RANDOM is : 1512
date is : Mon Sep 16 07:52:45 UTC 2019
RANDOM is : 30707
date is : Mon Sep 16 07:52:49 UTC 2019
RANDOM is : 9853
date is : Mon Sep 16 07:52:53 UTC 2019
RANDOM is : 4578
date is : Mon Sep 16 07:52:57 UTC 2019
RANDOM is : 22461
date is : Mon Sep 16 07:53:01 UTC 2019
RANDOM is : 23571
date is : Mon Sep 16 07:53:05 UTC 2019
RANDOM is : 27206
date is : Mon Sep 16 07:53:09 UTC 2019
RANDOM is : 5840
date is : Mon Sep 16 07:53:13 UTC 2019
RANDOM is : 16860
date is : Mon Sep 16 07:53:17 UTC 2019
RANDOM is : 3697
date is : Mon Sep 16 07:53:21 UTC 2019
RANDOM is : 24393
date is : Mon Sep 16 07:53:25 UTC 2019
RANDOM is : 6753
index.html的輸出時間間隔爲4秒,與pod的args設置的值一致。
3. 爲容器設置環境變量
3.1 生成鏡像loong576/date-random:env
[root@master loong576]# more date-random.sh
#!/bin/bash
mkdir /var/htdocs
#INTERVAL=$1
while :
do
/usr/bin/echo "date is : " `date` >> /var/htdocs/index.html
/usr/bin/echo "RANDOM is : " `echo $RANDOM` >> /var/htdocs/index.html
sleep $INTERVAL
done
[root@master loong576]# more Dockerfile
FROM centos:centos7.6.1810
ADD date-random.sh /usr/bin/date-random
ENTRYPOINT ["/usr/bin/date-random"]
#CMD ["10"]
[root@master loong576]# docker build -t loong576/date-random:env .
Sending build context to Docker daemon 6.144kB
Step 1/3 : FROM centos:centos7.6.1810
---> f1cb7c7d58b7
Step 2/3 : ADD date-random.sh /usr/bin/date-random
---> 1ddb8d15b11d
Step 3/3 : ENTRYPOINT ["/usr/bin/date-random"]
---> Running in e34374da108a
Removing intermediate container e34374da108a
---> b5daa0cf4479
Successfully built b5daa0cf4479
Successfully tagged loong576/date-random:env
[root@master loong576]# docker push loong576/date-random:env
The push refers to repository [docker.io/loong576/date-random]
5a389d8a01f4: Pushed
89169d87dbe2: Layer already exists
env: digest: sha256:f51c0831235a559e589ede54226d9f387966bea45435026acafad5416eba5e69 size: 736
生成鏡像loong576/date-random:env,該鏡像相比loong576/date-random:args主要是註釋腳本中的參數傳遞'INTERVAL=$1'和Dockerfile中指定的參數值'CMD ["10"]'
3.2 pod中指定環境變量
新建pod date-random-configmap-env並指定環境變量INTERVAL,賦值爲6
[root@master loong576]# more date-random-configmap-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: date-random-configmap-env
spec:
containers:
- image: loong576/date-random:env
env:
- name: INTERVAL
value: "6"
name: centos-date
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: nginx
name: nginx-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: html
emptyDir: {}
[root@master loong576]# kubectl apply -f date-random-configmap-env.yaml
pod/date-random-configmap-env created
[root@master loong576]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
date-random-configmap 2/2 Running 0 5h29m 10.244.1.203 node01 <none> <none>
date-random-configmap-args 2/2 Running 0 29m 10.244.2.209 node02 <none> <none>
date-random-configmap-env 2/2 Running 0 4m20s 10.244.1.208 node01 <none> <none>
nginx 0/1 CrashLoopBackOff 8 18m 10.244.1.206 node01 <none> <none>
[root@master loong576]# curl 10.244.1.208
date is : Mon Sep 16 08:16:50 UTC 2019
RANDOM is : 30120
date is : Mon Sep 16 08:16:56 UTC 2019
RANDOM is : 8149
date is : Mon Sep 16 08:17:02 UTC 2019
RANDOM is : 2752
date is : Mon Sep 16 08:17:08 UTC 2019
RANDOM is : 20276
date is : Mon Sep 16 08:17:14 UTC 2019
RANDOM is : 19299
date is : Mon Sep 16 08:17:21 UTC 2019
RANDOM is : 20116
date is : Mon Sep 16 08:17:27 UTC 2019
RANDOM is : 22331
date is : Mon Sep 16 08:17:33 UTC 2019
RANDOM is : 3626
date is : Mon Sep 16 08:17:39 UTC 2019
RANDOM is : 28190
date is : Mon Sep 16 08:17:45 UTC 2019
RANDOM is : 3241
date is : Mon Sep 16 08:17:51 UTC 2019
RANDOM is : 27762
date is : Mon Sep 16 08:17:57 UTC 2019
RANDOM is : 26519
date is : Mon Sep 16 08:18:03 UTC 2019
RANDOM is : 28403
date is : Mon Sep 16 08:18:09 UTC 2019
RANDOM is : 27219
index.html的輸出時間間隔爲6秒,與pod的env設置的值一致。
四、ConfigMap
通過'三、容器中的配置數據傳遞',可以將要傳遞給容器的參數直接定義在鏡像中或者pod中通過定義參數值和環境變量方式傳遞參數給容器,這些方式有如下弊端:
- 1.pod配置不能複用,生產和開發環境需定義兩套;
- 2.參數變更時需重啓容器;
- 3.鏡像中的參數變更需新建鏡像;
- 4.不適合分佈式環境;
這時就需要ConfigMap,通過Volume的形式被mount到Pod或者環境變量的方式傳遞參數給容器。
1. 創建configmap
1.1 --from-file指定文件方式
[root@master loong576]# more file1.txt
file1:abc
file1:123
[root@master loong576]# more file2.txt
file2:abcd
file2:1234
[root@master loong576]# kubectl create cm my-config-file --from-file=file1.txt --from-file=test2=file2.txt
configmap/my-config-file created
[root@master loong576]# kubectl get cm
NAME DATA AGE
my-config-file 2 5s
[root@master loong576]# kubectl describe cm my-config-file
Name: my-config-file
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
file1.txt:
----
file1:abc
file1:123
test2:
----
file2:abcd
file2:1234
Events: <none>
創建configmap my-config-file,指定文件爲file1.txt和file2.txt,key值分別爲默認的file1.txt和指定的test2。
1.2 --from-file指定目錄方式
[root@master configmap]# kubectl create configmap my-config-dir --from-file=/root/loong576/configmap/
configmap/my-config-dir created
[root@master configmap]# kubectl get cm
NAME DATA AGE
my-config-dir 2 6s
my-config-file 2 16h
創建configmap my-config-dir,指定目錄爲/root/loong576/configmap/,該目錄下有文件my-nginx-config.conf和sleep-interval,一個爲nginx配置,一個爲腳本循環時間設置,後面的configmap會用到。
1.3 --from-literal字面量方式
[root@master loong576]# kubectl create cm my-config-literal --from-literal=username=admin --from-literal=password=123456
configmap/my-config-literal created
[root@master loong576]# kubectl get cm
NAME DATA AGE
my-config-dir 2 18m
my-config-file 2 16h
my-config-literal 2 4s
創建configmap my-config-literal,key分別爲admin和password
1.4 --from-env-file鍵值對方式
[root@master loong576]# more bar.env
a=1
b=2
c=3
d=4
e
f=
gggg
h='8'
#i = '9'
j="10"
[root@master loong576]# kubectl create configmap my-config-env --from-env-file=./bar.env
configmap/my-config-env created
[root@master loong576]# kubectl get cm
NAME DATA AGE
my-config-dir 2 23m
my-config-env 9 3s
my-config-file 2 16h
my-config-literal 2 5m35s
鍵值對方式對格式有一定要求:有效的環境變量名必須由字母字符、數字、''-'或'.'組成,並且不能以數字開頭(例如,'.my.env name',或'.my'.env.name',或'.myenvname1',用於驗證的regex是'[-.'-z a-z][-.'-u a-za-z0-9]*')
1.5 yaml文件方式
[root@master loong576]# more configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config-yaml
data:
sleep-interval: "15"
[root@master loong576]# kubectl apply -f configmap.yaml
configmap/my-config-yaml created
[root@master loong576]# kubectl get cm
NAME DATA AGE
my-config-dir 2 34m
my-config-env 9 11m
my-config-file 2 16h
my-config-literal 2 16m
my-config-yaml 1 3s
[root@master loong576]# kubectl describe cm my-config-yaml
Name: my-config-yaml
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":{"sleep-interval":"15"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"my-config-yaml","namespace":"def...
Data
====
sleep-interval:
----
15
Events: <none>
創建configmap my-config-yaml,指定key值sleep-interval爲15
2. 使用configmap
2.1 新建pod date-random-configmap-volume
創建pod date-random-configmap-volume,給容器centos-date傳遞ConfigMap條目sleep-interval作爲環境變量;將ConfigMap作爲卷掛載至容器nginx-server作爲nginx配置文件
[root@master loong576]# more date-random-configmap-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: date-random-configmap-volume
spec:
containers:
- image: loong576/date-random:env #容器centos-date使用的鏡像,tag爲env
env:
- name: INTERVAL #環境變量名爲INTERVAL,與腳本date-random.sh中定義的保持一致
valueFrom:
configMapKeyRef: #使用ConfigMap初始化
name: my-config-dir #ConfigMap名稱
key: sleep-interval #環境變量的值被設置爲ConfigMap下sleep-interval對應的值
name: centos-date
volumeMounts:
- name: html
mountPath: /var/htdocs #掛載emptyDir卷的位置
- image: nginx
name: nginx-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html #掛載emptyDir卷的位置
readOnly: true
- name: config
mountPath: /etc/nginx/conf.d #掛載ConfigMap卷的位置
readOnly: true
volumes:
- name: html
emptyDir: {}
- name: config
configMap:
name: my-config-dir #定義卷類型爲ConfigMap,名字爲my-config-dir
items: #選擇包含在卷中的條目
- key: my-nginx-config.conf #被掛載的條目爲my-nginx-config.conf
path: nginx-port.conf #掛載至容器的文件名
[root@master loong576]# kubectl apply -f date-random-configmap-volume.yaml
pod/date-random-configmap-volume created
[root@master loong576]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
date-random-configmap 2/2 Running 2 29h 10.244.1.211 node01 <none> <none>
date-random-configmap-args 2/2 Running 2 24h 10.244.2.210 node02 <none> <none>
date-random-configmap-env 2/2 Running 2 24h 10.244.1.209 node01 <none> <none>
date-random-configmap-volume 2/2 Running 0 20s 10.244.1.216 node01 <none> <none>
nginx 0/1 CrashLoopBackOff 113 24h 10.244.1.212 node01 <none> <none>
通過掛載ConfigMap更新nginx配置原理:Nginx需讀取配置文件/etc/nginx/nginx.conf, 默認配置文件會自動嵌入子文件夾/etc/nginx/conf.d/下的所有conf文件, 因此只需要將你的配置文件置於該子文件夾中即可
2.2 訪問測試
[root@master loong576]# curl 10.244.1.216:81
date is : Tue Sep 17 08:27:34 UTC 2019
RANDOM is : 9389
date is : Tue Sep 17 08:27:42 UTC 2019
RANDOM is : 22109
date is : Tue Sep 17 08:27:50 UTC 2019
RANDOM is : 13043
訪問pod,nginx端口爲81,date輸出的間隔爲8秒
[root@master loong576]# kubectl exec -it date-random-configmap-volume -c nginx-server sh
# cd /etc/nginx/conf.d
# ls
nginx-port.conf
# more nginx-port.conf
server {
listen 81;
server_name localhost;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
進入容器nginx-server,/etc/nginx/conf.d下發現作爲卷掛載的ConfigMap條目nginx-port.conf
3. 更新應用配置
3.1 更新ConfigMap
[root@master loong576]# kubectl edit cm my-config-dir
更新my-config-dir,將條目my-nginx-config.conf的nginx監聽端口由81更改爲82
3.2 nginx加載配置
# nginx -s reload
由於nginx不會自動加載配置,故需重新加載
3.3 再次訪問nginx
[root@master loong576]# curl 10.244.1.216:82
date is : Tue Sep 17 08:27:34 UTC 2019
RANDOM is : 9389
date is : Tue Sep 17 08:27:42 UTC 2019
RANDOM is : 22109
date is : Tue Sep 17 08:27:50 UTC 2019
RANDOM is : 13043
再次訪問nginx,端口變爲82.
使用ConfigMap更新配置文件可避免pod重啓或容器重建。
五、Secret
爲了存儲與分發此類信息,Kubemetes提供了一種稱爲Secret的單獨資源對象。Secret結構與ConfigMap類似,均是鍵/值對的映射。
Secret作用:
- 將 Secret 條目作爲環境變量傳遞給容器
- 將 Secret 條目暴露爲卷中的文件
1. 創建Secret
和ConfigMap類似,Secret也有5中創建方式
使用文件、目錄和字面量方式:
[root@master loong576]# kubectl create secret generic mysecret --from-file=./username.txt --from-file=mypassword=./password.txt --from-literal=loong=576 --from-file=./secret-dir/
secret/mysecret created
[root@master loong576]# kubectl get secrets mysecret
NAME TYPE DATA AGE
mysecret Opaque 5 15s
secret有三種類型:
- docker-registry 創建一個給Docker registry使用的secret
- generic 從本地file, directory或者literal value創建一個secret
- tls 創建一個TLS secret
這裏使用的是generic方式,後面還會用到docker-registry方式。
鍵值對方式:
[root@master loong576]# kubectl create secret generic mysecret-env --from-env-file=secret-env.txt
secret/mysecret-env created
[root@master loong576]# kubectl get secrets
NAME TYPE DATA AGE
default-token-gwhj2 kubernetes.io/service-account-token 3 2m29s
mysecret Opaque 5 103s
mysecret-env Opaque 3 7s
yaml方式:
[root@master loong576]# echo loong|base64
bG9vbmcK
[root@master loong576]# echo 576|base64
NTc2Cg==
[root@master loong576]# more secret-yaml.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret-yaml
data:
username: bG9vbmcK
password: NTc2Cg==
[root@master loong576]# kubectl apply -f secret-yaml.yaml
secret/mysecret-yaml created
[root@master loong576]# kubectl get secrets
NAME TYPE DATA AGE
default-token-gwhj2 kubernetes.io/service-account-token 3 31m
mysecret Opaque 5 30m
mysecret-env Opaque 3 29m
mysecret-yaml Opaque 2 5s
注意,yaml方式中條目對應的key值對應的value需base64編碼,直接寫明文會報錯。
2. 查看Secret
[root@master loong576]# kubectl get secrets
NAME TYPE DATA AGE
default-token-gwhj2 kubernetes.io/service-account-token 3 36m
mysecret Opaque 5 35m
mysecret-env Opaque 3 33m
mysecret-yaml Opaque 2 4m53s
[root@master loong576]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
dir1.txt: 8 bytes
dir2.txt: 8 bytes
loong: 3 bytes
mypassword: 7 bytes
username.txt: 6 bytes
[root@master loong576]# kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
dir1.txt: dGVzdDAwMQo=
dir2.txt: dGVzdDAwMgo=
loong: NTc2
mypassword: YWJjMTIzCg==
username.txt: YWRtaW4K
kind: Secret
metadata:
creationTimestamp: "2019-09-18T01:55:47Z"
name: mysecret
namespace: default
resourceVersion: "2643256"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: 6ebdc96c-d9b7-11e9-863b-000c29d99ba3
type: Opaque
[root@master loong576]# echo dGVzdDAwMQo=|base64 --decode
test001
通過'kubectl get secrets'查看所有secret,通過'kubectl describe secrets mysecret'查看條目key值,通過'kubectl get secrets mysecret -o yaml'可查看條目的value值,不過需要base64解碼。
3. 使用Secret
本文以使用Secret拉取私有鏡像爲例介紹Secret的用法。
3.1 創建secret docker-registry
[root@master loong576]# kubectl create secret docker-registry loong576-secret --docker-username=loong576 --docker-password=xxxxxxxxxx [email protected]
secret/loong576-secret created
[root@master loong576]# kubectl get secrets loong576-secret
NAME TYPE DATA AGE
loong576-secret kubernetes.io/dockerconfigjson 1 16s
[root@master loong576]#
創建secret docker-registry:loong576-secret,dockerhub的用戶名密碼和郵箱根據個人的實際情況填寫。
3.2 創建私有鏡像loong576/test
在dockerhub上創建私有鏡像loong576/test
3.3 創建pod private-pod-secret
[root@master loong576]# more private-image-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: private-pod-secret
spec:
imagePullSecrets:
- name: loong576-secret #引用創建的docker-registry secret:loong576-secret
containers:
- image: loong576/test #拉取私有鏡像
name: busybox576
args: ["/bin/sh","-c","sleep 600000"]
volumeMounts:
- name: vol-secret
mountPath: /etc/loong576 #將卷掛載至容器的路徑
readOnly: true
volumes:
- name: vol-secret #將secret作爲卷掛載,卷名爲vol-secret
secret:
secretName: mysecret-yaml #引用之前創建的secret mysecret-yaml
[root@master loong576]# kubectl apply -f private-image-secret-volume.yaml
pod/private-pod-secret created
[root@master loong576]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
date-random-configmap 2/2 Running 4 2d 10.244.1.217 node01 <none> <none>
date-random-configmap-args 2/2 Running 4 43h 10.244.2.213 node02 <none> <none>
date-random-configmap-env 2/2 Running 4 42h 10.244.1.220 node01 <none> <none>
date-random-configmap-volume 2/2 Running 2 18h 10.244.1.221 node01 <none> <none>
nginx 0/1 CrashLoopBackOff 156 43h 10.244.1.218 node01 <none> <none>
private-pod-secret 1/1 Running 0 45s 10.244.2.218 node02 <none> <none>
創建pod private-pod-secret,使用secret loong576-secret拉取私有鏡像,將secret mysecret-yaml作爲卷掛載至容器。
3.4 pod中查看secret
[root@master loong576]# kubectl exec -it private-pod-secret sh
/ # df -h
Filesystem Size Used Available Use% Mounted on
overlay 5.0G 3.5G 1.5G 70% /
tmpfs 64.0M 0 64.0M 0% /dev
tmpfs 909.8M 0 909.8M 0% /sys/fs/cgroup
tmpfs 909.8M 8.0K 909.8M 0% /etc/loong576
/dev/mapper/root--vg-var
5.0G 3.5G 1.5G 70% /dev/termination-log
/dev/mapper/root--vg-var
5.0G 3.5G 1.5G 70% /etc/resolv.conf
/dev/mapper/root--vg-var
5.0G 3.5G 1.5G 70% /etc/hostname
/dev/mapper/root--vg-var
5.0G 3.5G 1.5G 70% /etc/hosts
shm 64.0M 0 64.0M 0% /dev/shm
tmpfs 909.8M 12.0K 909.8M 0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs 909.8M 0 909.8M 0% /proc/acpi
tmpfs 64.0M 0 64.0M 0% /proc/kcore
tmpfs 64.0M 0 64.0M 0% /proc/keys
tmpfs 64.0M 0 64.0M 0% /proc/timer_list
tmpfs 64.0M 0 64.0M 0% /proc/timer_stats
tmpfs 64.0M 0 64.0M 0% /proc/sched_debug
tmpfs 909.8M 0 909.8M 0% /proc/scsi
tmpfs 909.8M 0 909.8M 0% /sys/firmware
/ # cd /etc/loong576/
/etc/loong576 # ls -l
total 0
lrwxrwxrwx 1 root root 15 Sep 18 03:15 password -> ..data/password
lrwxrwxrwx 1 root root 15 Sep 18 03:15 username -> ..data/username
/etc/loong576 # more username
loong
/etc/loong576 # more password
576
進入容器查看secret,發現/etc/loong576下作爲卷掛載的secret;/etc/loong576文件系統類型爲tmpfs,說明secret卷採用內存文件系統掛載,secret數據不會寫入磁盤,保證數據安全。
4. 更新Secret
[root@master loong576]# echo loong-update|base64
bG9vbmctdXBkYXRlCg==
[root@master loong576]# echo 576-update|base64
NTc2LXVwZGF0ZQo=
[root@master loong576]# kubectl edit secret mysecret-yaml
secret/mysecret-yaml edited
更新mysecret-yaml,發現容器中掛載的內容同時被更新。
本文所有腳本和配置文件已上傳:k8s實踐(八):ConfigMap and Secret