ConfigMap

ConfigMap 是一种 API 对象,用来将非机密性的数据保存到健值对中。使用时可以用作环境变量、命令行参数或者存储卷中的配置文件。

ConfigMap 将您的环境配置信息和 容器镜像 解耦,便于应用配置的修改。当您需要储存机密信息时可以使用 Secret 对象。

注意:

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

动机

使用 ConfigMap 来将你的配置数据和应用程序代码分开。

比如,假设你正在开发一个应用,它可以在你自己的电脑上(用于开发)和在云上(用于实际流量)运行。你的代码里有一段是用于查看环境变量 DATABASE_HOST,在本地运行时,你将这个变量设置为 localhost,在云上,你将其设置为引用 Kubernetes 集群中的公开数据库 Service 中的组件。

这让您可以获取在云中运行的容器镜像,并且如果有需要的话,在本地调试完全相同的代码。

ConfigMap 对象

ConfigMap 是一个 API 对象, 让你可以存储其他对象所需要使用的配置。 和其他 Kubernetes 对象都有一个 spec 不同的是,ConfigMap 使用 data 块来存储元素(键名)和它们的值。

ConfigMap 的名字必须是一个合法的 DNS 子域名

ConfigMaps 和 Pods

您可以写一个引用 ConfigMap 的 Pod 的 spec,并根据 ConfigMap 中的数据在该 Pod 中配置容器。这个 Pod 和 ConfigMap 必须要在同一个 命名空间 中。

这是一个 ConfigMap 的示例,它的一些键只有一个值,其他键的值看起来像是配置的片段格式。

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: game-demo
  5. data:
  6. # 类属性键;每一个键都映射到一个简单的值
  7. player_initial_lives: "3"
  8. ui_properties_file_name: "user-interface.properties"
  9. #
  10. # 类文件键
  11. game.properties: |
  12. enemy.types=aliens,monsters
  13. player.maximum-lives=5
  14. user-interface.properties: |
  15. color.good=purple
  16. color.bad=yellow
  17. allow.textmode=true

您可以使用四种方式来使用 ConfigMap 配置 Pod 中的容器:

  1. 容器 entrypoint 的命令行参数
  2. 容器的环境变量
  3. 在只读卷里面添加一个文件,让应用来读取
  4. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

这些不同的方法适用于不同的数据使用方式。对前三个方法,kubelet 使用 ConfigMap 中的数据在 Pod 中启动容器。

第四种方法意味着你必须编写代码才能读取 ConfigMap 和它的数据。然而,由于您是直接使用 Kubernetes API,因此只要 ConfigMap 发生更改,您的应用就能够通过订阅来获取更新,并且在这样的情况发生的时候做出反应。通过直接进入 Kubernetes API,这个技术也可以让你能够获取到不同的命名空间里的 ConfigMap。

这是一个 Pod 的示例,它通过使用 game-demo 中的值来配置一个 Pod:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: configmap-demo-pod
  5. spec:
  6. containers:
  7. - name: demo
  8. image: game.example/demo-game
  9. env:
  10. # 定义环境变量
  11. - name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
  12. valueFrom:
  13. configMapKeyRef:
  14. name: game-demo # 这个值来自 ConfigMap
  15. key: player_initial_lives # 需要取值的键
  16. - name: UI_PROPERTIES_FILE_NAME
  17. valueFrom:
  18. configMapKeyRef:
  19. name: game-demo
  20. key: ui_properties_file_name
  21. volumeMounts:
  22. - name: config
  23. mountPath: "/config"
  24. readOnly: true
  25. volumes:
  26. # 您可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
  27. - name: config
  28. configMap:
  29. # 提供你想要挂载的 ConfigMap 的名字
  30. name: game-demo

ConfigMap 不会区分单行属性值和多行类似文件的值,重要的是 Pods 和其他对象如何使用这些值。比如,定义一个卷,并将它作为 /config 文件夹安装到 demo 容器内,并创建四个文件:

  • /config/player_initial_lives
  • /config/ui_properties_file_name
  • /config/game.properties
  • /config/user-interface.properties

如果您要确保 /config 只包含带有 .properties 扩展名的文件,可以使用两个不同的 ConfigMaps,并在 spec 中同时引用这两个 ConfigMaps 来创建 Pod。第一个 ConfigMap 定义了 player_initial_livesui_properties_file_name,第二个 ConfigMap 定义了 kubelet 放进 /config 的文件。

说明:

ConfigMap 最常见的用法是为同一命名空间里某 Pod 中运行的容器执行配置。您也可以单独使用 ConfigMap。

比如,您可能会遇到基于 ConfigMap 来调整其行为的 插件 或者 operator

接下来