ConfigMap简介

ConfigMap是一种API对象,用来将非机密性的数据保存到键值对中。使用时Pods可以将其用作环境变量、命令行参数或者存储卷中的配置文件。服务需要连接mysql,redis等,代码中有一些配置需要经常改动。所以ConfigMap就是解决这些问题的。ConfigMap将环境配置信息和容器镜像解耦,便于应用配置的修改。不过需要注意的是

ConfigMap本身不提供加密功能。如果要存储的数据是机密的,使用Secret,或者使用其他第三方工具来保证你的数据的私密性,而不是用ConfigMap

ConfigMap在设计上不是用来保存大量数据的。在ConfigMap中保存的数据不可超过1MiB。如果你需要保存超出此尺寸限制的数据,可以考虑挂载存储卷或者使用独立的数据库或者文件服务

ConfigMap的创建

可以使用kubectl create configmap从文件、目录或者key-value字符串创建等创建ConfigMap,也可以通过kubectl create -f file创建

使用key-value字符串创建

[root@k8s01 ~]# kubectl create configmap config-test-1 --from-literal=name=allen  --from-literal=age=22        
configmap/config-test-1 created
[root@k8s01 ~]# kubectl get configmap config-test-1 -o go-template --template='{{.data}}'    
map[age:22 name:allen]

使用env文件创建

[root@k8s01 ~]# echo -e "name=allen\nage=25" | tee config.env
name=allen
age=25
[root@k8s01 ~]# kubectl create configmap config-test-2 --from-env-file=config.env 
configmap/config-test-2 created
[root@k8s01 ~]# kubectl get configmap config-test-2 -o go-template --template='{{.data}}'      
map[age:25 name:allen]

使用目录创建

[root@k8s01 ~]# mkdir config
[root@k8s01 ~]# echo 18 > config/age  
[root@k8s01 ~]# echo allen > config/name       
[root@k8s01 ~]# kubectl create configmap config-test-3 --from-file=config/
configmap/config-test-3 created
[root@k8s01 ~]# kubectl get configmap config-test-3 -o go-template --template='{{.data}}' 
map[age:18
 name:allen
]

使用Yaml/Json创建

[root@k8s01 ~]# cat tets.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-test-4
  namespace: default
data:
  name: allen
  age: 16
[root@k8s01 ~]# kubectl create  -f config-test-4.yaml
configmap/config-test-4 created  

ConfigMap使用

ConfigMap可以通过三种方式在Pod中使用,三种分别方式为:设置环境变量、设置容器命令行参数以及在Volume中直接挂载文件或目录

注意:

  • ConfigMap必须在Pod引用它之前创建

  • 使用envFrom时,将会自动忽略无效的键

  • Pod 只能使用同一个命名空间内的ConfigMap

创建ConfigMap

[root@k8s01 ~]# kubectl create configmap special-config --from-literal=name=all --from-literal=realname=allen
[root@k8s01 ~]# kubectl create configmap env-config --from-literal=log_level=INFO

用作环境变量

[root@k8s01 ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test
      image: busybox
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: SPECIAL_NAME_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: name
        - name: SPECIAL_REALNAME_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: realname
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never
  
[root@k8s01 ~]# kubectl logs -f test-pod
HOSTNAME=test-pod
SPECIAL_NAME_KEY=all
log_level=INFO
SPECIAL_REALNAME_KEY=allen

值已成功写入了

用作命令参数

将ConfigMap用作命令行参数时,需要先把ConfigMap的数据保存在环境变量中,然后通过$(VAR_NAME)的方式引用环境变量

[root@k8s01 ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test
      image: busybox
      command: ["/bin/sh", "-c", "echo $(SPECIAL_NAME_KEY) $(SPECIAL_REALNAME_KEY)" ]
      env:
        - name: SPECIAL_NAME_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: name
        - name: SPECIAL_REALNAME_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: realname
  restartPolicy: Never
  
[root@k8s01 ~]# kubectl logs -f test-pod
all allen

输出写入的配置

使用volume将ConfigMap作为文件或目录直接挂载

将创建的ConfigMap直接挂载至Pod 的/etc/config目录下,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容

[root@k8s01 ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test
      image: busybox
      command: ["/bin/sh", "-c", "cat /etc/config/name"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never
[root@k8s01 ~]# kubectl logs -f test-pod
all#     

使用subpath将ConfigMap作为单独的文件挂载到目录

一般情况下configmap挂载文件时,会先覆盖掉挂载目录,然后再将congfigmap中的内容作为文件挂载进行。如果想不对原来的文件夹下的文件造成覆盖,只是将configmap中的每个key按照文件的方式挂载到目录下,可以使用subpath参数

[root@k8s01 ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test
      image: nginx
      command: ["/bin/sh","-c","sleep 36000"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/nginx/name
        subPath: name
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: name
          path: name
  restartPolicy: Never
[root@k8s01 ~]# kubectl exec -it test-pod-7856cd8988-bxwwl bash

root@test-pod:/etc/nginx# ls
conf.d        mime.types  name    scgi_params
fastcgi_params    modules     nginx.conf    uwsgi_params  

被挂载的ConfigMap内容会被自动更新

当卷中使用的ConfigMap被更新时,所投射的键最终也会被更新。kubelet组件会在每次周期性同步时检查所挂载的ConfigMap是否为最新。 不过kubelet使用的是其本地的高速缓存来获得ConfigMap的当前值。

ConfigMap既可以通过watch操作实现内容传播(默认形式),也可实现基于TTL的缓存,还可以直接经过所有请求重定向到API服务器。 因此从ConfigMap被更新的那一刻算起,到新的主键被投射到Pod中去,这一 时间跨度可能与kubelet的同步周期加上高速缓存的传播延迟相等。 这里的传播延迟取决于所选的高速缓存类型 (分别对应watch操作的传播延迟、高速缓存的TTL时长或者 0)。

以环境变量方式使用的ConfigMap数据不会被自动更新,更新这些数据需要重新启动Pod

不可变更的ConfigMap

Kubernetes特性不可变更的Secret和ConfigMap提供了一种将各个Secret和ConfigMap设置为不可变更的选项。对于大量使用ConfigMap的集群(至少有数万个各不相同的ConfigMap给Pod 挂载)而言,禁止更改ConfigMap的数据有以下好处:

  • 保护应用,使之免受意外更新所带来的负面影响

  • 通过大幅降低对kube-apiserver的压力提升集群性能,这是因为系统会关闭对已标记为不可变更的ConfigMap的监视操作

可以通过将immutable字段设置为true创建不可变更的ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  ...
data:
  ...
immutable: true

一旦某ConfigMap被标记为不可变更,则无法逆转这一变化,,也无法更改data或binaryData字段的内容。你只能删除并重建ConfigMap。 因为现有的Pod会维护一个对已删除的ConfigMap的挂载点,建议重新创建这些Pods

文章作者: 鲜花的主人
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 爱吃可爱多
Kubernetes Kubernetes
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝