×

理解 ConfigMap

许多应用程序需要使用配置文件、命令行参数和环境变量的某种组合进行配置。在 OpenShift Container Platform 中,这些配置工件与镜像内容分离,以保持容器化应用程序的可移植性。

ConfigMap 对象提供了一种机制,可以在容器中注入配置数据,同时保持容器与 OpenShift Container Platform 的无关性。ConfigMap 可用于存储细粒度信息(如单个属性)或粗粒度信息(如整个配置文件或 JSON 块)。

ConfigMap 对象保存配置数据的键值对,这些数据可以在 Pod 中使用,或用于存储系统组件(如控制器)的配置数据。例如:

ConfigMap 对象定义
kind: ConfigMap
apiVersion: v1
metadata:
  creationTimestamp: 2016-02-18T19:14:38Z
  name: example-config
  namespace: my-namespace
data: (1)
  example.property.1: hello
  example.property.2: world
  example.property.file: |-
    property.1=value-1
    property.2=value-2
    property.3=value-3
binaryData:
  bar: L3Jvb3QvMTAw (2)
1 包含配置数据。
2 指向包含非 UTF-8 数据的文件,例如二进制 Java 密钥库文件。输入 Base 64 中的文件数据。

从二进制文件(例如图像)创建 ConfigMap 时,可以使用binaryData 字段。

配置数据可以通过多种方式在 Pod 中使用。ConfigMap 可用于:

  • 填充容器中的环境变量值

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

  • 填充卷中的配置文件

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

ConfigMap 类似于 Secret,但设计得更方便地支持处理不包含敏感信息的字符串。

ConfigMap 限制

必须先创建 ConfigMap,然后才能在 Pod 中使用其内容。

控制器可以编写为容忍缺少配置数据。针对个案,咨询使用 ConfigMap 配置的各个组件。

ConfigMap 对象驻留在项目中。

它们只能被同一项目中的 Pod 引用。

Kubelet 只支持将 ConfigMap 用于从 API 服务器获取的 Pod。

这包括使用 CLI 创建的任何 Pod,或间接来自复制控制器的 Pod。它不包括使用 OpenShift Container Platform 节点的--manifest-url 标志、其--config 标志或其 REST API 创建的 Pod,因为这些不是创建 Pod 的常用方法。

在 OpenShift Container Platform Web 控制台中创建 ConfigMap

您可以在 OpenShift Container Platform Web 控制台中创建 ConfigMap。

步骤
  • 要以集群管理员身份创建 ConfigMap:

    1. 在管理员视角中,选择工作负载ConfigMap

    2. 在页面右上角,选择创建 Config Map

    3. 输入您的 config map 内容。

    4. 选择创建

  • 作为开发者创建 config map

    1. 在开发者视角中,选择Config Maps

    2. 在页面右上角,选择创建 Config Map

    3. 输入您的 config map 内容。

    4. 选择创建

使用 CLI 创建 config map

您可以使用以下命令从目录、特定文件或字面值创建 config map。

步骤
  • 创建 config map

    $ oc create configmap <configmap_name> [options]

从目录创建 config map

您可以使用--from-file标志从目录创建 config map。此方法允许您使用目录中的多个文件来创建 config map。

目录中的每个文件都用于填充 config map 中的一个键,其中键的名称是文件名,键的值是文件的内容。

例如,以下命令创建了一个包含example-files目录内容的 config map

$ oc create configmap game-config --from-file=example-files/

查看 config map 中的键

$ oc describe configmaps game-config
示例输出
Name:           game-config
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data

game.properties:        158 bytes
ui.properties:          83 bytes

您可以看到,映射中的两个键是由命令中指定的目录中的文件名创建的。这些键的内容可能很大,因此oc describe的输出只显示键的名称及其大小。

前提条件
  • 您必须拥有一个包含要用于填充 config map 的数据的文件的目录。

    以下过程使用这些示例文件:game.propertiesui.properties

    $ cat example-files/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 example-files/ui.properties
    示例输出
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
步骤
  • 输入以下命令,创建一个包含此目录中每个文件内容的 config map

    $ oc create configmap game-config \
        --from-file=example-files/
验证
  • 使用-o选项输入对象的oc get命令以查看键的值

    $ oc 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

从文件创建 config map

您可以使用--from-file标志从文件创建 config map。您可以将--from-file选项多次传递给 CLI。

您还可以通过将key=value表达式传递给--from-file选项,指定要为从文件导入的内容设置的 config map 中的键。例如

$ oc create configmap game-config-3 --from-file=game-special-key=example-files/game.properties

如果您从文件创建 config map,您可以包含包含非 UTF8 数据的文件,这些文件放置在此字段中不会损坏非 UTF8 数据。OpenShift Container Platform 会检测二进制文件并将其透明地编码为MIME。在服务器上,MIME有效负载被解码并存储,不会损坏数据。

前提条件
  • 您必须拥有一个包含要用于填充 config map 的数据的文件的目录。

    以下过程使用这些示例文件:game.propertiesui.properties

    $ cat example-files/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 example-files/ui.properties
    示例输出
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
步骤
  • 通过指定特定文件创建 config map

    $ oc create configmap game-config-2 \
        --from-file=example-files/game.properties \
        --from-file=example-files/ui.properties
  • 通过指定键值对创建 config map

    $ oc create configmap game-config-3 \
        --from-file=game-special-key=example-files/game.properties
验证
  • 使用-o选项输入对象的oc get命令以查看文件中的键的值

    $ oc 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
  • 使用-o选项输入对象的oc get命令以查看键值对中的键的值

    $ oc get configmaps game-config-3 -o yaml
    示例输出
    apiVersion: v1
    data:
      game-special-key: |- (1)
        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
    1 这是您在上一步中设置的键。

从字面值创建 config map

您可以为 config map 提供字面值。

--from-literal选项采用key=value语法,允许直接在命令行上提供字面值。

步骤
  • 通过指定字面值创建 config map

    $ oc create configmap special-config \
        --from-literal=special.how=very \
        --from-literal=special.type=charm
验证
  • 使用-o选项输入对象的oc get命令以查看键的值

    $ oc 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

用例:在 Pod 中使用 config map

以下部分描述了在 Pod 中使用ConfigMap对象的某些用例。

使用 config map 填充容器中的环境变量

您可以使用 config map 填充容器中的单个环境变量,或填充形成有效环境变量名称的所有键的容器中的环境变量。

例如,考虑以下 config map

包含两个环境变量的ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config (1)
  namespace: default (2)
data:
  special.how: very (3)
  special.type: charm (3)
1 config map 的名称。
2 config map 所在的项目。config map 只能被同一项目中的 Pod 引用。
3 要注入的环境变量。
包含一个环境变量的ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config (1)
  namespace: default
data:
  log_level: INFO (2)
1 config map 的名称。
2 要注入的环境变量。
步骤
  • 您可以使用configMapKeyRef部分在 Pod 中使用此ConfigMap的键。

    配置为注入特定环境变量的示例Pod规范
    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "env" ]
          env: (1)
            - name: SPECIAL_LEVEL_KEY (2)
              valueFrom:
                configMapKeyRef:
                  name: special-config (3)
                  key: special.how (4)
            - name: SPECIAL_TYPE_KEY
              valueFrom:
                configMapKeyRef:
                  name: special-config (3)
                  key: special.type (4)
                  optional: true (5)
          envFrom: (6)
            - configMapRef:
                name: env-config (7)
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      restartPolicy: Never
    1 ConfigMap提取指定环境变量的节。
    2 正在将键的值注入其中的 Pod 环境变量的名称。
    3 要从中提取特定环境变量的ConfigMap的名称。
    4 要从ConfigMap提取的环境变量。
    5 使环境变量可选。作为可选项,即使指定的ConfigMap和键不存在,Pod 也会启动。
    6 ConfigMap提取所有环境变量的节。
    7 要从中提取所有环境变量的ConfigMap的名称。

    运行此 Pod 时,Pod 日志将包含以下输出

    SPECIAL_LEVEL_KEY=very
    log_level=INFO

由于设置了optional: true,示例输出中未列出SPECIAL_TYPE_KEY=charm

使用 config map 为容器命令设置命令行参数

您可以使用 config map 通过使用 Kubernetes 替换语法$(VAR_NAME)来设置容器中命令或参数的值。

例如,考虑以下 config map

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
步骤
  • 要将值注入容器中的命令,您必须使用要作为环境变量使用的键。然后,您可以使用$(VAR_NAME)语法在容器的命令中引用它们。

    配置为注入特定环境变量的示例 Pod 规范
    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] (1)
          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
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      restartPolicy: Never
    1 使用要作为环境变量使用的键将值注入容器中的命令。

    运行此 Pod 时,在 test-container 容器中运行的 echo 命令的输出如下所示

    very charm

使用 config map 将内容注入卷

您可以使用 config map 将内容注入卷。

示例ConfigMap自定义资源 (CR)
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
步骤

您可以使用 config map 通过几种不同的方法将内容注入卷。

  • 使用 config map 将内容注入卷的最基本方法是使用文件填充卷,其中键是文件名,文件的内容是键的值

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      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
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      volumes:
        - name: config-volume
          configMap:
            name: special-config (1)
      restartPolicy: Never
    1 包含键的文件。

    运行此 Pod 时,cat 命令的输出将是

    very
  • 您还可以控制 config map 键投影到的卷中的路径

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      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
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      volumes:
        - name: config-volume
          configMap:
            name: special-config
            items:
            - key: special.how
              path: path/to/special-key (1)
      restartPolicy: Never
    1 config map 键的路径。

    运行此 Pod 时,cat 命令的输出将是

    very