ConfigMap概述


ConfigMap API资源保存配置数据的键值对,可以在pods中使用或者可以用于存储系统组件的配置数据。ConfigMap类似于Secrets,但是旨在更方便的使用不包含敏感信息的字符串。


注意:ConfigMap不打算充当属性文件的替换者。你可以认为类似于/etc目录,以及Linux计算机上的文件。一个例子是从ConfigMap创建一个Kubernetes卷,其中ConfigMap的数据项变成一个新的文件。


例如下面的例子:


kind: ConfigMap

apiVersion: v1

metadata:

  creationTimestamp: 2016-02-18T19:14:38Z

  name: example-config

  namespace: default

data:

  example.property.1: hello

  example.property.2: world

  example.property.file: |-

    property.1=value-1

    property.2=value-2

    property.3=value-3


data字段包含配置信息。可以看到ConfigMap可以用于细粒度的单个属性,或者是配置文件的内容。


配置数据在pods中有多种使用方式。ConfigMap有以下几种使用方式:


  • 填充环境变量的值

  • 设置容器内的命令行参数

  • 填充卷的配置文件


用户和系统组建都可以在ConfigMap中存储配置数据。


新建ConfigMap


可以使用kubectl create configmap 命令行非常容易的从字面值,文件或目录中创建configmaps。


让我们尝试用不同的方式创建一个ConfigMap:



1

从目录创建


比如说我们有一个目录其中包含一些已经已经包含要填充ConfigMap数据的文件:


$ ls docs/user-guide/configmap/kubectl/

game.properties

ui.properties

$ cat docs/user-guide/configmap/kubectl/game.properties

enemies=aliens

lives=3

enemies.cheat=true

enemies.cheat.level=noGoodRotten

secret.code.passphrase=UUDDLRLRBABAS

secret.code.allowed=true

secret.code.lives=30

$ cat docs/user-guide/configmap/kubectl/ui.properties

color.good=purple

color.bad=yellow

allow.textmode=true

how.nice.to.look=fairlyNice


kubectl create configmap 可用于创建一个保存此目录中每个文件内容的ConfigMap:


$ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl


当 --from-file指向一个目录,每个目录中的文件直接用于填充ConfigMap中的key,key的名称是文件名称,key的值是这个文件的内容。让我们看看上面命令创建的ConfigMap:


$ kubectl describe configmaps game-config

Name:           game-config

Namespace:      default

Labels:         <none>

Annotations:    <none>


Data

game.properties:        158 bytes

ui.properties:          83 bytes


可以看到map中的两个key是从我们指向的kubectl的目录中的文件名创建的。因为这些建的内容可能很大,kubectl describe你只能看到他们key的名称和大小。如果想看这些key的值,可以通过kubectl get获取:


$ kubectl get configmaps game-config -o yaml

apiVersion: v1

data:

  game.properties: |

    enemies=aliens

    lives=3

    enemies.cheat=true

    enemies.cheat.level=noGoodRotten

    secret.code.passphrase=UUDDLRLRBABAS

    secret.code.allowed=true

    secret.code.lives=30

  ui.properties: |

    color.good=purple

    color.bad=yellow

    allow.textmode=true

    how.nice.to.look=fairlyNice

kind: ConfigMap

metadata:

  creationTimestamp: 2016-02-18T18:34:05Z

  name: game-config

  namespace: default

  resourceVersion: "407"

  selfLink: /api/v1/namespaces/default/configmaps/game-config

  uid: 30944725-d66e-11e5-8cd0-68f728db1985



2

从文件创建


也可以通过--from-file指定文件,并将他多次传递给kubectc。下面的命令和上面的示例产生相同的结果:


$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties


$ kubectl get configmaps game-config-2 -o yaml

apiVersion: v1

data:

  game.properties: |

    enemies=aliens

    lives=3

    enemies.cheat=true

    enemies.cheat.level=noGoodRotten

    secret.code.passphrase=UUDDLRLRBABAS

    secret.code.allowed=true

    secret.code.lives=30

  ui.properties: |

    color.good=purple

    color.bad=yellow

    allow.textmode=true

    how.nice.to.look=fairlyNice

kind: ConfigMap

metadata:

  creationTimestamp: 2016-02-18T18:52:05Z

  name: game-config-2

  namespace: default

  resourceVersion: "516"

  selfLink: /api/v1/namespaces/default/configmaps/game-config-2

  uid: b4952dc3-d670-11e5-8cd0-68f728db1985


我们可以通过key=value表达式为每个文件设置key:


--from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties:

$ kubectl create configmap game-config-3 --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties


$ kubectl get configmaps game-config-3 -o yaml

apiVersion: v1

data:

  game-special-key: |

    enemies=aliens

    lives=3

    enemies.cheat=true

    enemies.cheat.level=noGoodRotten

    secret.code.passphrase=UUDDLRLRBABAS

    secret.code.allowed=true

    secret.code.lives=30

kind: ConfigMap

metadata:

  creationTimestamp: 2016-02-18T18:54:22Z

  name: game-config-3

  namespace: default

  resourceVersion: "530"

  selfLink: /api/v1/namespaces/default/configmaps/game-config-3

  uid: 05f8da22-d671-11e5-8cd0-68f728db1985


3

字面值创建


也可以通过kubectl create configmap创建ConfigMap使用字面值。--from-literal选项使用一个key=value语法,允许直接在命令行中直接提供字面值:


$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm


$ kubectl get configmaps special-config -o yaml

apiVersion: v1

data:

  special.how: very

  special.type: charm

kind: ConfigMap

metadata:

  creationTimestamp: 2016-02-18T19:14:38Z

  name: special-config

  namespace: default

  resourceVersion: "651"

  selfLink: /api/v1/namespaces/default/configmaps/special-config

  uid: dadce046-d673-11e5-8cd0-68f728db1985


Pods使用ConfigMap


用例:在环境变量中使用ConfigMap


ConfigMap可用于填充各个环境变量或者整个使用。举例如下:


apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  special.how: very

  special.type: charm

apiVersion: v1

kind: ConfigMap

metadata:

  name: env-config

  namespace: default

data:

  log_level: INFO


可以在pod中这样使用ConfigMap的键:


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh", "-c", "env" ]

      env:

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: special.how

        - name: SPECIAL_TYPE_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: special.type

      envFrom:

        - configMapRef:

            name: env-config

  restartPolicy: Never


当这个pod运行起来的时候,它输出包含下面的行:


SPECIAL_LEVEL_KEY=very

SPECIAL_TYPE_KEY=charm

log_level=INFO


可选ConfigMap在环境变量中


有些情况环境变量不是总是需要。这些环境变量可以标记为可选的在pods:


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh", "-c", "env" ]

      env:

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              name: a-config

              key: akey

              optional: true

  restartPolicy: Never


当这个pod运行,输出是空的。


设置命令行参数用ConfigMap


ConfigMaps可以用于设置容器里面的命令行参数的值。这是使用Kubernetes替换$(value)语法完成的。考虑ConfigMap:


apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  special.how: very

  special.type: charm


为了把值注入到命令行,我们必须使用我们作为环境变量的键,例如上一个例子。我们可以参考在容器内命令行使用$(VAR_NAME)语法:


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]

      env:

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: special.how

        - name: SPECIAL_TYPE_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: special.type

  restartPolicy: Never


当pod运行起来的时候,从test-container容器的输出会是:


very charm


用例:使用ConfigMap通过卷插件

ConfigMaps也可以在卷内使用。再次返回我们的示例:


apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  special.how: very

  special.type: charm


在卷中使用ConfigMap我们有几个不同的选项。最基础的方式是填充卷文件,键值是文件名内容是键对应的值:


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]

      volumeMounts:

      - name: config-volume

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        name: special-config

  restartPolicy: Never


当这个pod运行起来,会输出下面的内容:


very


我们还可以控制卷中的路径通过ConfigMap键映射:


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ]

      volumeMounts:

      - name: config-volume

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        name: special-config

        items:

        - key: special.how

          path: path/to/special-key

  restartPolicy: Never


当这个pod运行起来,会输出下面:


very


映射key指定的路径和权限


你可以在每个文件基础上指定key映射的特定路径和权限。Secrets用户指南介绍语法。


可选ConfigMap通过卷插件


卷和文件也可以标记为可选。ConfigMap或指定的键不一定存在。将始终创建这些项目的挂载路径。


apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: gcr.io/google_containers/busybox

      command: [ "/bin/sh", "-c", "ls /etc/config" ]

      volumeMounts:

      - name: config-volume

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        name: no-config

        optional: true

  restartPolicy: Never


当pod运行起来,输出将是空。


真实的示例:配置Redis


让我们看一个真实示例,使用ConfigMap配置redis。加入我们想用推荐的配置注入redis作为缓存。redis的配置文件应该包含:


maxmemory 2mb

maxmemory-policy allkeys-lru


这个文件在docs/user-guide/configmap/redis,我们可以用下面的命令新建一个ConfigMap:


$ kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config


$ kubectl get configmap example-redis-config -o yaml

apiVersion: v1

data:

  redis-config: |

    maxmemory 2mb

    maxmemory-policy allkeys-lru

kind: ConfigMap

metadata:

  creationTimestamp: 2016-03-30T18:14:41Z

  name: example-redis-config

  namespace: default

  resourceVersion: "24686"

  selfLink: /api/v1/namespaces/default/configmaps/example-redis-config

  uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002


现在我们新建一个pod使用这个配置:


apiVersion: v1

kind: Pod

metadata:

  name: redis

spec:

  containers:

  - name: redis

    image: kubernetes/redis:v1

    env:

    - name: MASTER

      value: "true"

    ports:

    - containerPort: 6379

    resources:

      limits:

        cpu: "0.1"

    volumeMounts:

    - mountPath: /redis-master-data

      name: data

    - mountPath: /redis-master

      name: config

  volumes:

    - name: data

      emptyDir: {}

    - name: config

      configMap:

        name: example-redis-config

        items:

        - key: redis-config

          path: redis.conf


注意,这个pod有一个ConfigMap卷,它将example-redis-config ConfigMap的redis-config键的值放入一个名为redis.conf的文件中。这个卷是挂载到redis容器里面的/redis-master目录里面,我们的配置文件在/redis-master/redis.conf,这个redis注解点在镜像里面的配置文件。


$ kubectl create -f docs/user-guide/configmap/redis/redis-pod.yaml


运行kubectl exec进入到这个pod里面并运行redis-cli工具,可以检查我们的配置是否正确应用:


$ kubectl exec -it redis redis-cli

127.0.0.1:6379> CONFIG GET maxmemory

1) "maxmemory"

2) "2097152"

127.0.0.1:6379> CONFIG GET maxmemory-policy

1) "maxmemory-policy"

2) "allkeys-lru"


限制


ConfigMap必须在pod消耗他之前创建,除非被标记为可选。对于不存在的ConfigMap将阻止它启动。控制器可能被写入以容忍丢失数据,可以个根据具体情况查看通过ConfigMap配置的各个组件。


通过configMapKeyRef引用命名ConfigMap中不存在的键将阻止他的启动。


ConfigMaps用于填充环境变量通过envFrom,它们被认为具有无效的环境变量名称的键将跳过这些键。该pod被允许启动。将会有一个事件,原因是InvalidVariabelNames,该消息包含被跳过的无效的键的列表。该示例显示一个pod它指的是 default/myconfig ConfigMap包含两个无效的键,1badkey和2alsobad。


$ kubectl.sh get events

LASTSEEN   FIRSTSEEN   COUNT     NAME            KIND      SUBOBJECT                         TYPE      REASON

0s         0s          1         dapi-test-pod   Pod                                         Warning   InvalidEnvironmentVariableNames   kubelet, 127.0.0.1      Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.


ConfigMap驻留到namespace里面。他们可以被引用和pod相同的namespace。ConfigMap配额大小是一个计划功能。


kubelet仅支持pod使用ConfigMap获取从API server。这包括使用kubectl创建每个pod,或者间接通过副本控制器。