k8s实践(八):ConfigMap and Secret
- 2019 年 10 月 5 日
- 筆記
环境说明:
主机名 |
操作系统版本 |
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*')

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