美文网首页Kubernetes
Kubernetes 配置Pod和容器(十二)configmap

Kubernetes 配置Pod和容器(十二)configmap

作者: YiQinGuo | 来源:发表于2017-04-11 17:00 被阅读4920次

    很多应用程序需要一些配置通过组合的配置文件,命令行参数和环境变量。这些配置应该与镜像内容分离以保持容器化应用程序的可移植性。ConfigMap API资源提供了将配置数据注入容器的机制,同时保持容器不受kubernetes的影响。ConfigMap可用于存储细粒度信息如单个属性,或粗粒度信息如整个配置文件或JSON对象。

    ConfigMap概述

    ConfigMap API资源保存配置数据的键值对,可以在pods中使用或者可以用于存储系统组件的配置数据。ConfigMap类似于Secrets,但是旨在更方便的使用不包含敏感信息的字符串。

    注意:ConfigMap不打算充当属性文件的替换者。你可以认为类似于/etc目录,以及Linux计算机上的文件。一个例子是从ConfigMap创建一个Kubernetes卷,其中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字段包含配置信息。可以看到ConfigMap可以用于细粒度的单个属性,或者是配置文件的内容。

    配置数据在pods中有多种使用方式。ConfigMap有以下几种使用方式:

    1.填充环境变量的值

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

    3.填充卷的配置文件

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

    新建ConfigMap

    可以使用kubectl create configmap 命令行非常容易的从字面值,文件或目录中创建configmaps。

    让我们尝试用不同的方式创建一个ConfigMap:

    从目录创建

    比如说我们有一个目录其中包含一些已经已经包含要填充ConfigMap数据的文件:

    $ 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
    

    kubectl create configmap 可用于创建一个保存此目录中每个文件内容的ConfigMap:

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

    当 --from-file指向一个目录,每个目录中的文件直接用于填充ConfigMap中的key,key的名称是文件名称,key的值是这个文件的内容。让我们看看上面命令创建的ConfigMap:

    $ kubectl describe configmaps game-config
    Name:           game-config
    Namespace:      default
    Labels:         <none>
    Annotations:    <none>
    
    Data
    ====
    game.properties:        158 bytes
    ui.properties:          83 bytes
    

    可以看到map中的两个key是从我们指向的kubectl的目录中的文件名创建的。因为这些建的内容可能很大,kubectl describe你只能看到他们key的名称和大小。如果想看这些key的值,可以通过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
    

    从文件创建

    也可以通过--from-file指定文件,并将他多次传递给kubectc。下面的命令和上面的示例产生相同的结果:

    $ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties
    
    $ 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
    

    我们可以通过key=value表达式为每个文件设置key:

    --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties

    $ 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
    

    通过字面值创建

    也可以通过kubectl create configmap创建ConfigMap使用字面值。--from-literal选项使用一个key=value语法,允许直接在命令行中直接提供字面值:

    $ 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
    

    pods使用ConfigMap

    用例:在环境变量中使用ConfigMap

    ConfigMap可用于填充各个环境变量或者整个使用。例如下面的例子:

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

    可以在pod中这样使用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
          envFrom:
            - configMapRef:
                name: env-config
      restartPolicy: Never
    

    当这个pod运行起来的时候,它输出包含下面的行:

    SPECIAL_LEVEL_KEY=very
    SPECIAL_TYPE_KEY=charm
    log_level=INFO
    

    可选ConfigMap在环境变量中

    有些情况环境变量不是总是需要。这些环境变量可以标记为可选的在pods:

    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: a-config
                  key: akey
                  optional: true
      restartPolicy: Never
    

    当这个pod运行,输出是空的。

    设置命令行参数用ConfigMap

    ConfigMaps可以用于设置容器里面的命令行参数的值。这是使用Kubernetes替换$(value)语法完成的。考虑ConfigMap:

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

    为了把值注入到命令行,我们必须使用我们作为环境变量的键,例如上一个例子。我们可以参考在容器内命令行使用$(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
    

    当pod运行起来的时候,从test-container容器的输出会是:

    very charm

    用例:使用ConfigMap通过卷插件

    ConfigMaps也可以在卷内使用。再次返回我们的示例:

    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", "cat /etc/config/special.how" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: special-config
      restartPolicy: Never
    

    当这个pod运行起来,会输出下面的内容:

    very

    我们还可以控制卷中的路径通过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","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
    

    当这个pod运行起来,会输出下面:

    very

    映射key指定的路径和权限

    你可以在每个文件基础上指定key映射的特定路径和权限。Secrets用户指南介绍语法。

    可选ConfigMap通过卷插件

    卷和文件也可以标记为可选。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", "ls /etc/config" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: no-config
            optional: true
      restartPolicy: Never
    

    当pod运行起来,输出将是空。

    真实的示例:配置Redis

    让我看一个真实示例:使用ConfigMap配置redis。加入我们想用推荐的配置注入redis作为缓存。redis的配置文件应该包含:

    maxmemory 2mb
    maxmemory-policy allkeys-lru
    

    这个文件在docs/user-guide/configmap/redis,我们可以用下面的命令新建一个ConfigMap:

    $ kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config
    
    $ 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
    

    现在我们新建一个pod使用这个配置:

    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
    

    注意,这个pod有一个ConfigMap卷,它将example-redis-config ConfigMap的redis-config键的值放入一个名为redis.conf的文件中。这个卷是挂载到redis容器里面的/redis-master目录里面,我们的配置文件在/redis-master/redis.conf,这个redis注解点在镜像里面的配置文件。

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

    运行kubectl exec进入到这个pod里面并运行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配置的各个组件。

    通过configMapKeyRef引用命名ConfigMap中不存在的键将阻止他的启动。

    ConfigMaps用于填充环境变量通过envFrom,它们被认为具有无效的环境变量名称的键将跳过这些键。该pod被允许启动。将会有一个事件,原因是InvalidVariabelNames,该消息包含被跳过的无效的键的列表。该示例显示一个pod它指的是 default/myconfig ConfigMap包含两个无效的键,1badkey和2alsobad。

    $ kubectl.sh get events
    LASTSEEN   FIRSTSEEN   COUNT     NAME            KIND      SUBOBJECT                         TYPE      REASON
    0s         0s          1         dapi-test-pod   Pod                                         Warning   InvalidEnvironmentVariableNames   kubelet, 127.0.0.1      Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
    

    ConfigMap驻留到namespace里面。他们可以被引用和pod相同的namespace。ConfigMap配额大小是一个计划功能。

    kubelet仅支持pod使用ConfigMap获取从API server。这包括使用kubectl创建每个pod,或者间接通过副本控制器。

    相关文章

      网友评论

        本文标题:Kubernetes 配置Pod和容器(十二)configmap

        本文链接:https://www.haomeiwen.com/subject/dyjuattx.html