容器配置管理

编者注:这是我们在 系列深入帖子 Kubernetes 1.2的新功能

A 好习惯 编写应用程序时将应用程序代码与配置分开。我们希望使应用程序作者能够轻松地在Kubernetes中采用这种模式。虽然Secrets API允许从应用程序中分离诸如凭据和密钥之类的信息,但过去对于普通的非秘密配置不存在任何对象。在 Kubernetes 1.2,我们添加了一个名为ConfigMap的新API资源来处理这种类型的配置数据。

ConfigMap的基础

ConfigMap API在概念上很简单。从数据角度来看,ConfigMap类型只是一组键-值对。应用程序以不同的方式配置,因此我们需要灵活地让用户存储和使用配置数据。有三种在容器中使用ConfigMap的方法:

  • 命令行参数
  • 环境变量
  • 卷中的文件

这些不同的方法适用于对正在使用的数据进行建模的不同方法。为了尽可能灵活,我们使ConfigMap保留了细粒度和/或粗粒度的数据。此外,由于应用程序从环境变量和包含配置数据的文件中读取配置设置,因此我们构建了ConfigMap以支持这两种访问方法。让我们看一下包含两种配置类型的ConfigMap示例:

apiVersion: v1

kind: ConfigMap

metadata:

  Name: example-configmap

data:

  # property-like keys

  game-properties-file-name: game.properties

  ui-properties-file-name: ui.properties

  # file-like keys

  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

使用Secrets的用户会发现开始使用ConfigMap很容易-他们非常相似。这些API的主要区别在于Secret值存储为字节数组,以支持存储二进制文件(如SSH密钥)。在JSON和YAML中,字节数组被序列化为base64编码的字符串。这意味着从查看序列化的表格中分辨出Secret的内容并不容易。由于ConfigMap仅用于保存配置信息,不包含二进制文件,因此值存储为字符串,因此可以序列化形式读取。

We want creating ConfigMaps to be as flexible as storing data in them. To create a ConfigMap object, we’ve added a kubectl command called kubectl create configmap that offers three different ways to specify key-value pairs:

  • 指定文字键和值
  • 指定单个文件
  • 指定目录以为每个文件创建密钥

这些不同的选项可以在单个命令中混合,匹配和重复:

    $ kubectl create configmap my-config \

    - from-literal=literal-key=literal-value \

    - from-file=ui.properties \
    - from=file=path/to/config/dir

消费ConfigMap很简单,而且Secrets的用户也会很熟悉。这是一个使用上面的ConfigMap运行虚拟游戏服务器的Deployment的示例:

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: configmap-example-deployment

  labels:

    name: configmap-example-deployment

spec:

  replicas: 1

  selector:

    matchLabels:

      name: configmap-example

  template:

    metadata:

      labels:

        name: configmap-example

    spec:

      containers:

      - name: game-container

        image: imaginarygame

        command: ["game-server", "--config-dir=/etc/game/cfg"]

        env:

        # consume the property-like keys in environment variables

        - name: GAME\_PROPERTIES\_NAME

          valueFrom:

            configMapKeyRef:

              name: example-configmap

              key: game-properties-file-name

        - name: UI\_PROPERTIES\_NAME

          valueFrom:

            configMapKeyRef:

              name: example-configmap

              key: ui-properties-file-name

        volumeMounts:

        - name: config-volume

          mountPath: /etc/game

      volumes:

      # consume the file-like keys of the configmap via volume plugin

      - name: config-volume

        configMap:

          name: example-configmap

          items:

          - key: ui.properties

            path: cfg/ui.properties

         - key: game.properties

           path: cfg/game.properties
      restartPolicy: Never

在上面的示例中,部署通过两个可用的不同机制使用ConfigMap的键。 ConfigMap的类似于属性的键用作Deployment模板中单个容器的环境变量,而类似文件的键则填充一个卷。有关更多详细信息,请参见 ConfigMap文档.

我们希望这些基本原语易于使用,并期待看到人们使用ConfigMap构建的内容。感谢社区成员提供了有关此功能的反馈。特别要感谢塔默·塔斯(Tamer Tas),他为ConfigMap的建议和实施做出了巨大贡献。

如果您对Kubernetes和配置感兴趣,请参加:

当然,有关该项目的更多信息,请访问 www.kubernetes.io 并在Twitter上关注我们 @Kubernetesio.

- 红帽高级软件工程师Paul Morie