×

理解ConfigMap

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

ConfigMap对象提供机制,可在容器中注入配置数据,同时保持容器与AWS上的Red Hat OpenShift Service无关。ConfigMap可用于存储细粒度信息(如单个属性)或粗粒度信息(如整个配置文件或JSON blob)。

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 指向包含非UTF8数据的文件,例如二进制Java密钥库文件。输入Base 64中的文件数据。

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

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

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

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

  • 填充卷中的配置文件

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

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

ConfigMap限制

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

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

ConfigMap对象驻留在项目中。

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

Kubelet仅支持将其从API服务器获取的Pod使用ConfigMap。

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

在AWS Web控制台中创建Red Hat OpenShift Service上的ConfigMap

您可以在AWS Web控制台中创建Red Hat OpenShift Service上的ConfigMap。

步骤
  • 要作为集群管理员创建ConfigMap:

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

    2. 在页面右上方,选择**创建ConfigMap**。

    3. 输入ConfigMap的内容。

    4. 选择**创建**。

  • 要作为开发者创建ConfigMap:

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

    2. 在页面右上方,选择**创建ConfigMap**。

    3. 输入ConfigMap的内容。

    4. 选择**创建**。

使用CLI创建ConfigMap

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

步骤
  • 创建ConfigMap

    $ oc create configmap <configmap_name> [options]

从目录创建ConfigMap

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

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

例如,以下命令创建包含example-files目录内容的ConfigMap

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

查看ConfigMap中的键

$ 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的输出仅显示键的名称及其大小。

前提条件
  • 您必须有一个包含要填充ConfigMap数据的文件的目录。

    以下步骤使用这些示例文件: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
步骤
  • 通过输入以下命令来创建一个包含此目录中每个文件内容的ConfigMap

    $ 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

从文件创建ConfigMap

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

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

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

如果从文件创建配置映射,您可以包含此字段中包含非 UTF8 数据的文件,而不会损坏非 UTF8 数据。Red Hat OpenShift Service on AWS 会检测二进制文件并将其透明地编码为MIME。在服务器上,MIME有效负载将被解码并存储,而不会损坏数据。

前提条件
  • 您必须有一个包含要填充ConfigMap数据的文件的目录。

    以下步骤使用这些示例文件: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
步骤
  • 通过指定特定文件来创建配置映射

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

    $ 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 这是您在上一步中设置的键。

从字面量创建配置映射

您可以为配置映射提供字面量值。

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

步骤
  • 通过指定字面量值来创建配置映射

    $ 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 中使用配置映射

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

使用配置映射填充容器中的环境变量

您可以使用配置映射填充容器中的单个环境变量,或填充构成有效环境变量名称的所有键的容器中的环境变量。

例如,考虑以下配置映射

具有两个环境变量的ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config (1)
  namespace: default (2)
data:
  special.how: very (3)
  special.type: charm (3)
1 配置映射的名称。
2 配置映射所在的项目。配置映射只能被同一项目中的 Pod 引用。
3 要注入的环境变量。
具有一个环境变量的ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config (1)
  namespace: default
data:
  log_level: INFO (2)
1 配置映射的名称。
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

示例输出中未列出SPECIAL_TYPE_KEY=charm,因为已设置optional: true

使用配置映射设置容器命令的命令行参数

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

例如,考虑以下配置映射

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

使用配置映射将内容注入卷

您可以使用配置映射将内容注入卷。

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

您可以使用几种不同的方法使用配置映射将内容注入卷。

  • 使用配置映射将内容注入卷的最基本方法是用文件填充卷,其中键是文件名,文件的內容是键的值。

    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
  • 您还可以控制配置映射键投影到卷中的路径

    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 配置映射键的路径。

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

    very