Kubernetes常用资源对象-ConfigMap

我们来学习另外⼀个非常重要的资源对象: ConfigMap ,我们知道许多应用经常会有从配置⽂件、命令⾏参数或者环境变量中读取⼀些配置信息,这些配置信息我们肯定不会直接写死到应用程序中去的,比如有⼀个应⽤连接⼀个 redis 服务,下⼀次想更换⼀个了,还得重新去修改代码,重新制作⼀个镜像,这肯定是不可取的,而 ConfigMap 就给我们提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,也可以用来保存整个配置文件,比如我们可以用来配置⼀个 redis 服务的访问地址,也可以用来保存整个 redis 的配置文件。

1、创建ConfigMap

ConfigMap 资源对象使用 key-value 形式的键值对来配置数据,这些数据可以在 Pod 里面使用, ConfigMap 和我们后面要讲到的 Secrets 比较类似,⼀个比较大的区别是 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 configmap-demo.yaml 来创建上面的 ConfigMap 对象:

img

注:如果不知道怎么创建 ConfigMap 的话,不要忘记 kubectl 是我们最好的老师,我们可以使用 kubectl createconfigmap -h 来查看关于创建 ConfigMap 的帮助信息:

img

从上面的帮助文档我们看清楚的看到、ConfigMap的创建有多种方式:通过 Yaml 文件创建、通过命令行的方式创建、通过文件夹创建、通过文件创建、通过制定字符串来创建、通过env文件创建。

例如:我们有⼀个 testcm 的目录,该目录下⾯包含⼀些配置文件, redis 和 mysql 的连接信息如下:

[root@Node01 testcm]# ls
mysql.conf  redis.conf
[root@Node01 testcm]# cat redis.conf 
host=127.0.0.1
port=6379
[root@Node01 testcm]# cat mysql.conf 
host=127.0.0.1
port=3306
[root@Node01 testcm]#

通过文件目录方式创建ConfigMap

然后我们可以使用 from-file 关键字来创建包含这个⽬录下面所以配置文件的 ConfigMap;其中 from-file 参数指定在该目录下⾯的所有文件都会被用在 ConfigMap 里面创建⼀个键值对,键的名字就是⽂件名,值就是文件的内容;创建完成后,同样我们可以使用如下命令来查看 ConfigMap 列表;可以看到已经创建了⼀个 cm-demo1 的 ConfigMap 对象,然后可以使用 describe 命令查看详细信息:

kubectl create configmap cm-demo1 --from-file=testcm

img

注:我们可以看到两个 key 是 testcm 目录下⾯的文件名称,对应的 value 值的话就是⽂件内容。这里需要注意的是如果ConfigMap的资源文件够大、够多;通过kubectl describe 命令不会把所有的信息都展示出来;我们可以通过下面的 kubectl get configmap cm-demo1 -o yaml 命令把ConfigMap生成一个Yaml资源文件进行查看:

img

通过指定文件方式创建ConfigMap

除了通过文件目录进⾏创建,我们也可以使用指定的文件进行创建 ConfigMap 。同样的,以上⾯的配
置文件为例,我们创建⼀个 redis 配置的⼀个单独 ConfigMap 对象:

kubectl create configmap cm-demo2 --from-file=testcm/redis.conf

img

我们可以看到⼀个关联 redis.conf 文件配置信息的 ConfigMap 对象创建成功了,另外值得注意的是 –
-from-file 这个参数可以多次使用,比如我们这里使用两次分别指定 redis.conf 和 mysql.conf 文件,就和直接指定整个⽬录是⼀样的效果了。

通过字符串方式创建ConfigMap

另外,通过帮助文档我们可以看到我们还可以直接使用字符串进行创建,通过 –from-literal 参数传递配置信息,同样的,这个参数可以使用多次,格式如下:

kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=3306

img

2、使用ConfigMap

ConfigMap 虽然创建成功了,但是我们应该怎么在 Pod 中来使用呢?我们说 ConfigMap 这些配置数据可以通过很多种方式在 Pod 里使用⽤,主要有以下⼏种方式:

  • 设置环境变量的值;
  • 在容器里设置命令行参数;
  • 在数据卷里⾯创建config⽂件。

通过环境变量使用ConfigMap信息

⾸先,我们使用 ConfigMap 来填充我们的环境变量:

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

img

通过 kubectl logs testcm1-pod 命令我们我们可以看到 DB_HOST 和 DB_PORT 都已经正常输出了,另外的环境变量是因为我们这⾥直接把 cmdemo1给注入进来了,所以把他们的整个键值给输出出来了,这也是符合预期的:

img

通过设置命令行参数使用ConfigMap信息

我们也可以使用 ConfigMap 来设置命令行参数, ConfigMap 也可以被用来设置容器中的命令或者参
数值,例如下面这个 Pod :

apiVersion: v1
kind: Pod
metadata:
  name: testcm2-pod
spec:
  containers:
    - name: testcm2
      image: busybox
      command: [ "/bin/sh", "-c", "echo (DB_HOST)(DBHOST)(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

img

通过数据卷config文件使用ConfigMap信息

另外⼀种是非常常见的使用 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

img

当然我们也可以在 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

img

另外需要注意的是,当 ConfigMap 以数据卷的形式挂载进 Pod 时,这时更新 ConfigMap (或删掉重建 ConfigMap ), Pod 内挂载的配置信息会热更新。也可以增加⼀些监测配置⽂件变更的脚本,然后 reload 对应服务。

推荐文章