ConfigMap介绍

作者:苏晓林 [email protected]

ConfigMap的使命

在许多应用程序的实际配置中,常常需要通过命令行参数和环境变量进行混合的配置。复杂的配置会严重增加容器的部署和更新的难度、降低容器的可移植性。ConfigMap的出现就是为了解决该问题,通过ConfigMap将配置与镜像内容进行分离,镜像内容中不再包含需要动态变化的配置,全部放在ConfigMap中。从而使容器镜像具备了更好的可移植性,部署和更新也变得更容易。ConfigMap能够存储细粒度的信息(如单个属性)和粗粒度的信息(如整个配置文件或JSON对象),在容器运行时通过ConfigMap API资源将配置注入到容器中。

ConfigMap概述

ConfigMap API资源中能够保存Pod中能够使用的key-value配置,也能够存储系统组件(如Controller)的配置数据。ConfigMap在一定程度上与Secrets有些类似,但是ConfigMap在设计能够更方便的支持不包含敏感信息的字符串。

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字段包含了细粒度的配置信息example.property.1和example.property.2,也包括粗粒度的信息example.property.file。

ConfigMap在Pod中的使用支持多种方法,如下:

1.设置环境变量的值

2.设置容器中的命令行参数

3.设置volume中的配置文件

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

创建ConfigMap

创建ConfigMap的命令为kubectl create configmap,通过该命令可以直接通过目录、文件或key-value值的方式创建ConfigMap。

下面将对三种创建方式进行介绍:

目录创建

如下,在目录docs/user-guide/configmap/kubectl/中,存在配置game.properties和ui.properties:

$ 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

通过目录创建ConfigMap来保存该目录下每个文件的内容:

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

参数--from-file用来指向提供创建ConfigMap数据的目录,该目录中所有文件名称会作为ConfigMap中的key,文件中的内容作为value添加到新创建的ConfigMap中。

查看新创建的ConfigMap:

$ kubectl describe configmaps game-config
Name:           game-config
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data
====
game.properties:        121 bytes
ui.properties:          83 bytes

在该MapConfig的describe信息中,我们能够看到名称为上边命令指定的game-config,在Data字段能够看到两个新添加的key:game.properties和ui.properties。由于value的size较大,此处只显示了大小,要想查看value的完整内容,可以通过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

文件创建

通过文件创建ConfigMap的命令与通过目录创建的命令相同,但--from-file参数的值为指定的文件,并且可以通过添加多个--from-file参数,同时添加多个文件。下面的命令能够得到上面命令相同的结果。

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

查看ConfigMap:

$ 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

在上面的示例中ConfigMap的key名称默认都采用的文件的名称,也可以通过key=value的方式指定key的名称。

$ 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

key-value值创建

可以通过在命令行中直接指定ConfigMap中key、value的方式创建新的ConfigMap。参数为--from-literal,值为key=value格式的键值对,支持同时添加多个--from-literal参数。

$ 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

ConfigMap在Pod中的使用方式

通过ConfigMap设置环境变量

ConfigMap中的值可以通过环境变量的方式在容器中使用,参考如下示例:

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", "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
  restartPolicy: Never

当该容器运行时,输出环境变量的值为:

SPECIAL_LEVEL_KEY=very
SPECIAL_TYPE_KEY=charm

在Pod中使用envFrom引入环境变量(Kubernetes v1.6或更高版本)

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" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never

该方式中将会把ConfigMap中key的名称作为环境变量的名称,value作为环境变量的值引入。

通过ConfigMap设置命令行参数

ConfigMap也可以通过kubernetes替换语法$(VAR_NAME)来设置容器中的命令或参数的值。如下示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

首先需要在容器的环境变量中引入上边ConfigMap的值,然后通过$(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

当该容器运行时,命令行的输出结果为:

very charm

通过volume插件使用ConfigMap

可以通过volume的方式使用ConfigMap中的值,依然采用上面的ConfigMap示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

通过volume的方式引用ConfigMap的值有多种方式,最基本的方法为文件方式,volume中的文件名称为ConfigMap中的key,文件内容为ConfigMap中的value。引用示例如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "cat /etc/config/special.how" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

该容器运行时的输出结果为:

very

设置ConfigMap中key的映射路径:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "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

该容器运行时的输出结果为:

very

实战演练:配置Redis

下面通过Redis来展示ConfigMap在实际应用中的使用方法。假设我们需要将以下配置作为redis的运行参数:

maxmemory 2mb
maxmemory-policy allkeys-lru

该配置的文件目录为:docs/user-guide/configmap/redis/redis-config,创建ConfigMap:

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

查看该ConfigMap:

$ 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

Redis的配置文件:

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

该配置中通过volume的方式使用ConfigMap,将ConfigMap:example-redis-config中key:redis-config的值,写入到文件redis.conf中。然后将该文件挂载到目录/redis-master下,redis在启动时会加载该文件。

创建Redis容器:

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

使用kubectl exec命令进入该容器,并使用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中不存在的key的引用也会阻止该Pod启动。

当使用envFrom引入环境变量时,无效的key将会被跳过,容器能够启动,但无效的key将会记录在事件日志(InvalidVariableNames)中。

ConfigMap的作用范围被限制在namespace中,只有该namespace中的pod才能使用。

Kubelet不支持API Server中不存在的Pod使用ConfigMap。

原文连接:

https://kubernetes-v1-4.github.io/docs/user-guide/configmap/

https://kubernetes.io/docs/tasks/configure-pod-container/configmap/

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap/

results matching ""

    No results matching ""