应用的配置在Kubernetes中可通过ConfigMap资源对象来实现,避免被直接写死到应用程序中,比如应用连接一个redis服务,下一次想更换另一个,如果写死的话,就得重新修改代码,重新制作新镜像。而利用ConfigMap就可以很方便地向容器中注入配置信息。类似于Windows/Linux中的环境变量的配置。
不过需要注意的是,ConfigMap一般是保存非安全的配置信息,比如服务连接地址,环境变量参数,服务端口等等,如果是涉及到密钥等敏感信息,则不适合用ConfigMap,因为ConfigMap是明文保存的,如果保存密钥等信息就会引起安全问题了。
1. 实践1:通过ConfigMap向容器中注入数据库端口值
最直观的方式是在命令行中直接注入参数值,通过--from-literal
参数传递配置信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| $ kubectl create configmap cm-demo1 --from-literal=db.host=localhost --from-literal=db.port=3306 configmap/cm-demo1 created
$ kubectl get cm/cm-demo1 -o yaml apiVersion: v1 data: db.host: localhost db.port: "3306" kind: ConfigMap metadata: creationTimestamp: "2022-03-28T07:36:40Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:db.host: {} f:db.port: {} manager: kubectl-create operation: Update time: "2022-03-28T07:36:40Z" name: cm-demo1 namespace: default resourceVersion: "37278796" selfLink: /api/v1/namespaces/default/configmaps/cm-demo1 uid: 53212514-4737-4bc1-b841-48deb80c9597
|
通过kubectl create configmap
创建configmap
配置信息,指定了key
与value
值,如果需要指定多个参数,则指定多个--from-litera
.通过上面的命令,创建了一个名为cm-demo1的configmap
,对应有两个变量。
- db.host: localhost
- db.port: 3306
上面创建好的configmap如何被其他API对象引用呢?可通过env
-> name
valueFrom
-> configMapKeyRef
-> name
key
引用。如:
testcm1_pod.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| apiVersion: v1 kind: Pod metadata: name: testcm1-pod spec: containers: - name: testcm1 image: busybox command: [ "/bin/sh", "-c", "echo DB_HOST: $DB_HOST, DB_PORT: $DB_PORT" ] env: - name: DB_HOST valueFrom: configMapKeyRef: name: cm-demo1 key: db.host - name: DB_PORT valueFrom: configMapKeyRef: name: cm-demo1 key: db.port
|
这里定义一个POD,使用busybox镜像,启动容器后只需命令echo DB_HOST: $DB_HOST, DB_PORT: $DB_PORT
,显然,busybox镜像默认并没有DB_HOST与DB_PORT的变量,而是通过在POD下文中通过env
定义的。
在env
中定义了两个变量:
name
为DB_HOST的变量:通过valueFrom-configMapKeyRef
定位到configmap,分别设置name
与key
,则引用名为cm-demo1
的configmap对象例的db.host
变量。
name
为DB_PORT的变量:通过valueFrom-configMapKeyRef
定位到configmap,分别设置name
与key
,则引用名为cm-demo1
的configmap对象例的db.port
变量。
测试查看结果:
1 2 3 4 5
| $ kubectl apply -f pod_cm.yaml pod/testcm1-pod created
$ kubectl logs testcm1-pod DB_HOST: localhost, DB_PORT: 3306
|
在创建pod对象后,testcm1-pod能够识别打印出提前定义的变量DB_HOST与DB_PORT。
2. 实践2:通过在数据卷中使用configmap向容器中注入多个变量
上面通过命令行,写了两个变量,已经有点麻烦了,如果涉及到多个变量的话,写命令行就不合适了,最好需要将配置写入文件,应用来读取该文件。一般采取步骤如下:
- 创建好配置文件,如Mysql的配置文件
mysql.cnf
。
1 2 3 4 5 6 7 8
| [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid !includedir /etc/my.cnf.d
|
- 根据该配置文件,创建成configmap配置,以供Kubernetes对象使用。
1 2
| $ kubectl create cm mysql-cm --from-file=mysql.cnf configmap/mysql-cm created
|
创建完成后,可查看创建好的cm。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| $ kubectl get cm/mysql-cm -o yaml apiVersion: v1 data: mysql.cnf: | [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid !includedir /etc/my.cnf.d kind: ConfigMap metadata: creationTimestamp: "2022-03-28T08:20:12Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:mysql.cnf: {} manager: kubectl-create operation: Update time: "2022-03-28T08:20:12Z" name: mysql-cm namespace: default resourceVersion: "37289515" selfLink: /api/v1/namespaces/default/configmaps/mysql-cm uid: 8f220505-0a44-4363-8bfc-9067e86dd034
|
- Kubernetes资源对象引用configmap
定义POD,pod_vol_cm.yaml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: v1 kind: Pod metadata: name: testcm2-pod spec: volumes: - name: config-volume configMap: name: mysql-cm containers: - name: testcm2 image: busybox command: [ "/bin/sh","-c","sleep 3000" ] volumeMounts: - name: config-volume mountPath: /etc/config
|
POD中定义了volumes,引用configmap,即:名为mysql-cm
的configMap也是一个volumes数据卷,最终在container中被挂载到/etc/config
目录下。在容器中执行cat命令,最终打印出的将是mysql.cnf
文件内容。
生成POD并查看注入的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $ kubectl apply -f pod_vol_cm.yaml pod/testcm2-pod created
$ kubectl exec -it testcm2-pod sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. / [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid !includedir /etc/my.cnf.d /
|
在POD中可查看到configmap注入的配置信息。
简单理解下:有一个数据卷名为mysql-cm,这个名字其实也就是configmap的名字,这个数据卷被挂载到容器里的某个路径/etc/config
,这个路径下的文件也即是configmap的配置文件。
3. 总结ConfigMap的使用
configmap可以用来存储Kubernetes资源对象所需的配置文件,其内容将写入到ETCD存储中。
3.1 创建ConfigMap
通用创建ConfigMap的方式有以下几种:
- 通过直接在命令行中指定configmap参数创建,即
--from-literal
;
- 通过指定文件创建,即将一个配置文件创建为一个ConfigMap,
--from-file=<文件>
;
- 事先写好标准的configmap的yaml文件,然后
kubectl create -f
创建。
3.1.1 通过–from-literal创建
1
| $ kubectl create configmap test-config1 --from-literal=db.host=localhost --from-literal=db.port='3306'
|
直接在命令行中写好所有的变量,通过configmap注入到容器中。
3.1.2 通过–from-file
1 2 3
| $ echo -n 172.18.8.200 > ./db.host $ echo -n 3306 > ./db.port $ kubectl create cm test-config2 --from-file=./db.host --from-file=./db.port
|
将环境变量写入文件,通过from-file导入。
3.1.1.3 通过YAML配置
1 2 3 4 5 6 7
| apiVersion: v1 kind: ConfigMap metadata: name: test-config4 data: db.host: 172.18.8.200 db.port: "3306"
|
直接写好configmap的配置,通过yaml文件创建API资源对象。
3.2 使用ConfigMap
使用ConfigMap的方式主要有两种:
- 第一种是通过环境变量的方式,直接传递给pod;
- 第二种是作为volume的方式挂载到pod内。
3.2.1 通过环境变量使用
使用valueFrom
、configMapKeyRef
、name
、key
指定要用的key,如上面的实践1。当然也可以通过envFrom
、configMapRef
、name
使得configmap中的所有key/value对都自动变成环境变量。如:
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: busybox args: [ "/bin/sh", "-c", "sleep 3000" ] envFrom: - configMapRef: name: test-config4
|
3.2.2 作为volume数据卷被挂载使用
通过将ConfigMap定义为数据卷,挂载到容器的某路径中。如上面的实践2。当然我们也可以在 ConfigMap
值被映射的数据卷里去控制路径,如下 Pod 定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| apiVersion: v1 kind: Pod metadata: name: testcm2-pod spec: volumes: - name: config-volume configMap: name: mysql-cm items: - key: mysql.conf path: path/to/msyql.conf containers: - name: testcm2 image: busybox command: [ "/bin/sh","-c","cat /etc/config/path/to/msyql.cnf" ] volumeMounts: - name: config-volume mountPath: /etc/config
|
参考链接:https://blog.51cto.com/wzlinux/2331050

欢迎关注公众号-梅旭红,记录技术之旅,不定期更新.