Kubernetes的ConfigMap

文章目录

  • 环境
  • 概念
  • 配置pod使用ConfigMap
    • 创建ConfigMap
      • kubectl create configmap
        • 目录
        • 文件
        • 自定义key值
        • literal值
      • 产生器(generator)
        • 文件
        • 自定义key值
        • literal值
    • 定义容器环境变量
      • 单个ConfigMap
      • 多个ConfigMap
    • 配置ConfigMap里所有键值对为环境变量
    • 在pod命令里使用ConfigMap定义的环境变量
    • 添加ConfigMap数据到volume
      • 使用ConfigMap的数据填充volume
      • 添加ConfigMap的数据到volume的指定路径
      • 文件权限
      • 可选引用
      • mount的ConfigMap会自动更新
    • 理解ConfigMap和pod
    • 可选的ConfigMap
    • 限制
  • 示例:使用ConfigMap配置Redis
  • 参考

在这里插入图片描述

环境

  • RHEL 9.3
  • Docker Community 24.0.7
  • minikube v1.32.0

概念

ConfigMap是一种API对象,用来在键-值对里存储非机密信息。Pod可以以环境变量、命令行参数、volume里的配置文件等方式来消费ConfigMap。

ConfigMap把环境特有的配置和容器image解耦,从而提高了应用的移植性。

注意:ConfigMap不提供保密或加密功能。对于机密数据,应使用Secret或者三方工具。

比如,应用在开发阶段运行在本地电脑上,在生产阶段运行在云上。代码使用了环境变量 DATABASE_HOST 。在本地,可将其设置为 localhost ,在云端,将其设置为指向一个Kubernetes service。

注意:ConfigMap并不是设计为存储大量数据,其容量不能超过1MB。如果数据量大,可以考虑mount一个volume,或者使用数据库/文件。

不像大部分Kubernetes对象有 spec 字段,ConfigMap有 databinaryData 字段,里面存储一些键-值对。二者都是可选的。 data 用来存储UTF-8字符串,而 binaryData 把二进制数据存储为base64编码的字符串。

databinaryData 里的key值必须字母、数字、 -_. 组成。二者的key值不能重复。

在pod的 spec 里可以引用ConfigMap,并基于ConfigMap的数据来配置容器。Pod和ConfigMap必须在同一个namespace。

注意:静态pod的 spec 里不能引用ConfigMap和其它任何API对象。

例如:

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # property-like keys; each key maps to a simple value
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # file-like keys
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true    

可使用四种方式来使用ConfigMap配置pod里的容器:

  • 在容器的 commandargs
  • 容器的环境变量
  • 在只读volume里添加文件,以便应用来读取
  • 编写代码,在pod里运行,通过Kubernetes API来读取ConfigMap

对于前三种方法,当 kubelet 启动pod里的容器时,会用到ConfigMap的数据。

第四种方法意味着必须编写代码才能读取ConfigMap。不过,由于直接使用Kubernetes API,因此只要ConfigMap发生更改,应用就能够通过订阅来获取更新,并做出反应。 直接访问Kubernetes API时,可获取其它namespace里的ConfigMap。

例如:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # Define the environment variable
        - name: PLAYER_INITIAL_LIVES # Notice that the case is different here
                                     # from the key name in the ConfigMap.
          valueFrom:
            configMapKeyRef:
              name: game-demo           # The ConfigMap this value comes from.
              key: player_initial_lives # The key to fetch.
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: game-demo
              key: ui_properties_file_name
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
  # You set volumes at the Pod level, then mount them into containers inside that Pod
  - name: config
    configMap:
      # Provide the name of the ConfigMap you want to mount.
      name: game-demo
      # An array of keys from the ConfigMap to create as files
      items:
      - key: "game.properties"
        path: "game.properties"
      - key: "user-interface.properties"
        path: "user-interface.properties"

ConfigMap不区分单行属性值或多行类似文件的值。重要的是pod和其它对象如何消费这些值。

在本例中,定义了一个volume,并将其mount到 demo 容器的 /config 路径,创建了两个文件: /config/game.properties/config/user-interface.properties 。由于在 volumes 处指定了 items 数组,所以只有两个文件。如果省略 items 数组,则ConfigMap里的每个key值都会创建一个同名文件,也就是四个文件。

$ kubectl apply -f cm1.yaml 
configmap/game-demo created
$ kubectl apply -f pod1.yaml
pod/configmap-demo-pod created
$ kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
configmap-demo-pod   1/1     Running   0          19s
$ kubectl exec configmap-demo-pod -- ls /config
game.properties
user-interface.properties
$ kubectl exec configmap-demo-pod -- cat /config/game.properties
enemy.types=aliens,monsters
player.maximum-lives=5
$ kubectl exec configmap-demo-pod -- cat /config/user-interface.properties
color.good=purple
color.bad=yellow
allow.textmode=true

CongiMap可以mount为数据volume,也可以被系统的其它部分所用,而不是直接暴露给pod。例如,ConfigMap可持有系统其它部分用来配置的数据。

ConfigMap最常见的用法是为同一namespace里的pod的容器提供配置。也可以单独使用ConfigMap。比如,addon或operator基于ConfigMap来调节其行为。

把ConfigMap用作pod的volume:

  1. 创建或使用已有的ConfigMap。多个pod可引用同一个ConfigMap。
  2. 修改pod定义,在 .spec.volumes[] 下添加一个volume。为volume命名,并用 .spec.volumes[].configMap.name 字段来引用ConfigMap对象。
  3. 在每个需要ConfigMap的容器里添加 .spec.containers[].volumeMounts[] ,设置 .spec.containers[].volumeMounts[].readOnly = true ,设置 .spec.containers[].volumeMounts[].mountPath 为一个未使用的目录。
  4. 修改image或命令行,以便程序能够从该目录找到文件。ConfigMap data 下的每个key值将成为 mountpath 下的一个文件。

例如:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    configMap:
      name: myconfigmap

所有ConfigMap都要在 .spec.volumes 里引用。

如果pod里有多个容器,则每个容器都需要它自己的 volumeMounts ,但对于每个ConfigMap,只需一个 .spec.volumes

当volume里ConfigMap有更新时,投射的key最终也会更新。kubelet会在每次周期性同步时,检查所mount的ConfigMap是否为最新。但是,kubelet使用的是本地缓存来获取ConfigMap的当前值。缓存的类型可通过 KubeletConfiguration 结构的 configMapAndSecretChangeDetectionStrategy 字段来配置。ConfigMap可通过watch(默认)、ttl-based(注:Time To Live,生存时间)传播,也可通过把所有请求直接重定向到API服务器来传播。因此,从ConfigMap更新,到新的key被投射到pod里,期间的总体延迟可能等于“kubelet同步周期 + 缓存的传播延迟”。 这里的缓存传播延迟取决于缓存类型(分别对应watch传播延迟、缓存ttl,或者0)。

若ConfigMap用作环境变量,则不会自动更新,需要重启pod。

注意:把ConfigMap用作subPath volume mount的容器,不会收到ConfigMap更新。

Kubernetes v1.21起可将Secret和ConfigMap设置为不可变(immutable)。对于使用大量ConfigMap(比如一万个)的集群,阻止数据变化有如下优点:

  • 防止无意的错误更新导致outage
  • 提升性能,通过关闭不可变ConfigMap的watch,减少kube-apiserver的负载
apiVersion: v1
kind: ConfigMap
metadata:
  ...
data:
  ...
immutable: true

一旦ConfigMap被标记为不可变,则无法再回退,也无法更改 databinaryData 字段的内容。你只能删除并重建ConfigMap。由于现有的pod维护了被删除ConfigMap的挂载点(mount point),建议重建这些 Pods。

配置pod使用ConfigMap

很多应用在初始化或运行期间使用一些配置,并且多数时候,都有调整配置参数的需求。ConfigMap作为Kubernetes的一种机制,把配置注入到应用pod里。

ConfigMap把配置和image内容解耦,提高了容器化应用的可移植性。比如,可以下载并运行同一个image,用于本地开发、系统测试,或者运行实时的用户负载。

创建ConfigMap

可用 kubectl create configmap 或者 kustomization.yaml 里的ConfigMap生成器来创建ConfigMap。

kubectl create configmap

kubectl create configmap <map-name> <data-source>

其中:

  • <map-name> :ConfigMap的名字
  • <data-source> :目录、文件、或者literal值

使用文件时,默认情况下,key是文件的基本名(basename),value是文件内容。

可用 kubectl describe 或者 kubectl get 命令来获取ConfigMap信息。

目录

当基于一个目录创建ConfigMap时,kubectl选择目录里命名符合key值的文件,打包到ConfigMap里。非常规文件将会被忽略(比如: 子目录,symlinks,设备,管道)。

注意:可接受的文件名包括字母、数字、 -_. 。如果目录里有不可接受的文件名,则 kubectl 命令会失败,但不会打印错误。

创建目录 configure-pod-container/configmap

mkdir -p configure-pod-container/configmap/

在该目录中,创建 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

创建ConfigMap game-config

$ kubectl create configmap game-config --from-file=configure-pod-container/configmap/
configmap/game-config created

查看ConfigMap game-config

$ kubectl describe configmaps game-config
Name:         game-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

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


BinaryData
====

Events:  <none>
$ 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: "2024-01-21T10:11:13Z"
  name: game-config
  namespace: default
  resourceVersion: "70852"
  uid: 78b6ab26-9c5b-4ee2-bd3a-19122c2125b1
文件

可从一个或多个文件创建ConfigMap。比如:

kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
kubectl create configmap game-config-3 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties
$ kubectl describe configmaps game-config-2
Name:         game-config-2
Namespace:    default
Labels:       <none>
Annotations:  <none>

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

BinaryData
====

Events:  <none>
$ kubectl describe configmaps game-config-3
Name:         game-config-3
Namespace:    default
Labels:       <none>
Annotations:  <none>

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


BinaryData
====

Events:  <none>

使用 --from-env-file 选项,从env文件创建ConfigMap。

configure-pod-container/configmap 目录里创建文件 game-env-file.properties 如下:

enemies=aliens
lives=3
allowed="true"

# This comment and the empty line above it are ignored

configure-pod-container/configmap 目录里创建文件 ui-env-file.properties 如下:

color=purple
textmode=true
how=fairlyNice

创建ConfigMap game-config-env-file

kubectl create configmap game-config-env-file \
       --from-env-file=configure-pod-container/configmap/game-env-file.properties

查看ConfigMap game-config-env-file

$ kubectl get configmap game-config-env-file -o yaml
apiVersion: v1
data:
  allowed: '"true"'
  enemies: aliens
  lives: "3"
kind: ConfigMap
metadata:
  creationTimestamp: "2024-01-21T10:27:11Z"
  name: game-config-env-file
  namespace: default
  resourceVersion: "71751"
  uid: 25f4bedc-6c9c-4e4e-ba08-ed4aa9e3c7fc

可见,通过 --from-env-file ,properties文件里的每个属性都成为ConfigMap里的一个key。

注意引号会被当作literal的字符。

从Kubernetes v1.23起, kubectl 支持多个 --from-env-file 参数。

kubectl create configmap config-multi-env-files2 \
        --from-env-file=configure-pod-container/configmap/game-env-file.properties \
        --from-env-file=configure-pod-container/configmap/ui-env-file.properties
$ kubectl get configmap config-multi-env-files2 -o yaml
apiVersion: v1
data:
  allowed: '"true"'
  color: purple
  enemies: aliens
  how: fairlyNice
  lives: "3"
  textmode: "true"
kind: ConfigMap
metadata:
  creationTimestamp: "2024-01-21T11:21:20Z"
  name: config-multi-env-files2
  namespace: default
  resourceVersion: "74787"
  uid: 508daa61-cceb-472d-a35d-8f548987b8c9
自定义key值
kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file>

其中, <my-key-name> 是自定义的key值。比如:

kubectl create configmap game-config-4 --from-file=game-special-key=configure-pod-container/configmap/game.properties
$ kubectl get configmaps game-config-4 -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: "2024-01-21T11:25:07Z"
  name: game-config-4
  namespace: default
  resourceVersion: "75002"
  uid: 42fbe599-ea55-4f56-8c78-95f80a8151b3
literal值

比如:

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: "2024-01-21T11:26:53Z"
  name: special-config
  namespace: default
  resourceVersion: "75100"
  uid: 62b75de5-31e6-4006-aa8c-ee21cf9a814a

产生器(generator)

需要在 kustomization.yaml 文件里指定产生器。

文件

在当前目录(注意不是 configure-pod-container/configmap 目录)创建文件 kustomization.yaml 如下:

configMapGenerator:
- name: game-config-4
  options:
    labels:
      game-config: config-4
  files:
  - configure-pod-container/configmap/game.properties
$ kubectl apply -k .
configmap/game-config-4-tbg7c4gc77 created
$ kubectl describe configmap/game-config-4-tbg7c4gc77
Name:         game-config-4-tbg7c4gc77
Namespace:    default
Labels:       game-config=config-4
Annotations:  <none>

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

BinaryData
====

Events:  <none>
自定义key值

在当前目录(注意不是 configure-pod-container/configmap 目录)创建文件 kustomization.yaml 如下:

configMapGenerator:
- name: game-config-5
  options:
    labels:
      game-config: config-5
  files:
  - game-special-key=configure-pod-container/configmap/game.properties

注意多了 game-special-key=

$ kubectl apply -k .
configmap/game-config-5-tfhf8f4fkf created
$ kubectl describe configmap/game-config-5-tfhf8f4fkf
Name:         game-config-5-tfhf8f4fkf
Namespace:    default
Labels:       game-config=config-5
Annotations:  <none>

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

BinaryData
====

Events:  <none>
literal值

在当前目录(注意不是 configure-pod-container/configmap 目录)创建文件 kustomization.yaml 如下:

configMapGenerator:
- name: special-config-2
  literals:
  - special.how=very
  - special.type=charm
$ kubectl apply -k .
configmap/special-config-2-2b86tk8fhm created
$ kubectl describe configmap/special-config-2-2b86tk8fhm
Name:         special-config-2-2b86tk8fhm
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
special.how:
----
very
special.type:
----
charm

BinaryData
====

Events:  <none>

定义容器环境变量

单个ConfigMap

先把ConfigMap special-config 删掉重建:

kubectl delete configmap special-config
kubectl create configmap special-config --from-literal=special.how=very

在pod的specification里,把 special.how 赋给 SPECIAL_LEVEL_KEY 环境变量。创建文件 pods/pod-single-configmap-env-variable.yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # Define the environment variable
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
              name: special-config
              # Specify the key associated with the value
              key: special.how
  restartPolicy: Never

注:如果访问不了 registry.k8s.io ,则需事先把image放到能访问的地方,比如 docker.io

      image: docker.io/kaiding1/busybox

创建pod:

kubectl create -f pods/pod-single-configmap-env-variable.yaml

查看pod:

$ kubectl get pod dapi-test-pod
NAME            READY   STATUS      RESTARTS   AGE
dapi-test-pod   0/1     Completed   0          70s
$ kubectl describe pod dapi-test-pod
......
    Environment:
      SPECIAL_LEVEL_KEY:  <set to the key 'special.how' of config map 'special-config'>  Optional: false
......

查看pod的log:

$ kubectl logs dapi-test-pod
......
SPECIAL_LEVEL_KEY=very
......

注:log内容包含了pod的标准输出(stdout),本例中创建pod时指定了 command: [ "/bin/sh", "-c", "env" ] ,也就是说,启动容器时运行 env 命令查看环境变量。从pod的log可知,环境变量里包含了 SPECIAL_LEVEL_KEY=very

多个ConfigMap

删除ConfigMap special-configenv-config

kubectl delete cm special-config env-config

删除pod dapi-test-pod

kubectl delete pod dapi-test-pod

创建文件 configmap/configmaps.yaml 如下:

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

创建ConfigMap:

kubectl create -f configmap/configmaps.yaml

创建文件 pods/pod-multiple-configmap-env-variable.yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      # image: registry.k8s.io/busybox
      image: docker.io/kaiding1/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: env-config
              key: log_level
  restartPolicy: Never

创建pod:

kubectl create -f pods/pod-multiple-configmap-env-variable.yaml

查看pod:

$ kubectl get pod dapi-test-pod
NAME            READY   STATUS      RESTARTS   AGE
dapi-test-pod   0/1     Completed   0          70s
$ kubectl logs dapi-test-pod
......
LOG_LEVEL=INFO
SPECIAL_LEVEL_KEY=very
......

最后,删除pod:

kubectl delete pod dapi-test-pod

配置ConfigMap里所有键值对为环境变量

创建文件 configmap/configmap-multikeys.yaml 如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  SPECIAL_LEVEL: very
  SPECIAL_TYPE: charm

删掉ConfigMap special-config

kubectl delete cm special-config

重建:

kubectl create -f configmap/configmap-multikeys.yaml

创建文件 pods/pod-configmap-envFrom.yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      # image: registry.k8s.io/busybox
      image: docker.io/kaiding1/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never

创建pod test-container

kubectl create -f pods/pod-configmap-envFrom.yaml
$ kubectl get pod dapi-test-pod
NAME            READY   STATUS      RESTARTS   AGE
dapi-test-pod   0/1     Completed   0          44s
$ kubectl logs dapi-test-pod
......
SPECIAL_LEVEL=very
SPECIAL_TYPE=charm
......

最后,删除pod:

kubectl delete pod dapi-test-pod

在pod命令里使用ConfigMap定义的环境变量

可以在容器的 commandargs 里,通过 $(VAR_NAME) Kubernetes替换语法,使用ConfigMap定义的环境变量。

创建文件 pods/pod-configmap-env-var-valueFrom.yaml

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      # image: registry.k8s.io/busybox
      image: docker.io/kaiding1/busybox
      command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_LEVEL
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_TYPE
  restartPolicy: Never

创建pod dapi-test-pod

kubectl create -f pods/pod-configmap-env-var-valueFrom.yaml
$ kubectl get pod dapi-test-pod
NAME            READY   STATUS      RESTARTS   AGE
dapi-test-pod   0/1     Completed   0          42s
$ kubectl logs dapi-test-pod
very charm

最后,删除pod:

kubectl delete pod dapi-test-pod

添加ConfigMap数据到volume

前面提到,使用 --from-file 创建ConfigMap时,文件名作为key存储在ConfigMap的 data 部分,而文件内容作为key所对应的value。

之前创建过文件 configmap/configmap-multikeys.yaml ,并以此创建ConfigMap special-config

使用ConfigMap的数据填充volume

在pod的specification的 volumes 下添加ConfigMap名字。这将会添加ConfigMap的数据到 volumeMounts.mountPath (本例中为 /etc/config )。

创建文件 pods/pod-configmap-volume.yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      # image: registry.k8s.io/busybox
      image: docker.io/kaiding1/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: special-config
  restartPolicy: Never

创建pod dapi-test-pod

kubectl create -f pods/pod-configmap-volume.yaml
$ kubectl logs dapi-test-pod
SPECIAL_LEVEL
SPECIAL_TYPE

文本数据会展现为UTF-8字符编码的文件。要想使用其它字符编码,可以使用 binaryData

注意:如果容器image的 /etc/config 目录里有文件,volume mount将会导致该image中的这些文件无法访问。

最后,删除pod:

kubectl delete pod dapi-test-pod

添加ConfigMap的数据到volume的指定路径

使用 patch 字段来指定文件路径。本例中, SPECIAL_LEVEL 会被mount到 config-volume volume的 /etc/config/keys

创建文件 pods/pod-configmap-volume-specific-key.yaml 如下:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      # image: registry.k8s.io/busybox
      image: docker.io/kaiding1/busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: SPECIAL_LEVEL
          path: keys
  restartPolicy: Never

创建pod test-container

kubectl create -f pods/pod-configmap-volume-specific-key.yaml
$ kubectl logs dapi-test-pod
very

可见, cat /etc/config/keys 的输出结果是 very

注意:如果容器image的 /etc/config 目录里有文件,volume mount将会导致该image中的这些文件无法访问。

最后,删除pod:

kubectl delete pod dapi-test-pod

文件权限

默认情况下,文件权限是 0644 。可通过 defaultMode 设置文件权限,比如:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    configmap:
      name: mycm
      defaultMode: 0400

注意:如果使用JSON定义Pod或Pod模板,请注意JSON不支持八进制的literal数值,因为JSON会把 0400 当作十进制的 400 。在JSON中,要用十进制的 defaultMode

可选引用

ConfigMap引用可被标记为 optional 。如果ConfigMap不存在,则mount的volume为空。如果ConfigMap存在,但引用的key不存在,则mount point下的路径将不存在。

mount的ConfigMap会自动更新

当mount的ConfigMap更新时,所投射的内容最终也会更新。这适用于pod启动后,可选引用的ConfigMap出现的情况。

Kubelet在每次定期同步时都会检查mount的ConfigMap是否是最新的。然而,它使用基于TTL的缓存来获取ConfigMap的当前值。因此,从“ConfigMap更新”到“新键投射到pod”的总延迟可能与“kubelet同步周期(默认为1分钟)” + “kubelet中ConfigMap缓存的TTL(默认为1分钟)”一样长。可通过更新pod的一个注解来触发立即刷新。

注意:把ConfigMap作为subPath volume的容器不会收到ConfigMap更新。

理解ConfigMap和pod

ConfigMap API资源把配置数据存储为键-值对。这些数据可以在pod里被消费,或者为系统组件比如控制器提供配置。ConfigMap和secret类似,但提供的是一种处理不含敏感信息的字符串的方法。用户和系统组件都可以在ConfigMap中存储配置数据。

注意:ConfigMap应该引用properties文件,而不是替换它们。可以把ConfigMap理解为类似于Linux /etc 目录及其内容的东西。例如,如果从ConfigMap创建volume,则ConfigMap中的每个数据项都由volume中的一个文件来表示。

ConfigMap的 data 字段包含了配置数据。从下面的例子可见,它可以很简单(比如 --from-literal 定义的单个属性)或者很复杂(比如 --from-file 定义的配置文件或JSON blob)。

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: 2016-02-18T19:14:38Z
  name: example-config
  namespace: default
data:
  # example of a simple property defined using --from-literal
  example.property.1: hello
  example.property.2: world
  # example of a complex property defined using --from-file
  example.property.file: |-
    property.1=value-1
    property.2=value-2
    property.3=value-3

kubectl 从非ASCII或UTF-8编码的输入创建ConfigMap时,会将其放入ConfigMap的 binaryData 字段,而不是 data 字段。文本和二进制数据源都可以组合在一个ConfigMap中。

要想查看 binaryData 的key和value,使用 kubectl get configmap -o jsonpath='{.binaryData}' <name>

Pod可以从使用 databinaryData 的ConfigMap中加载数据。

可选的ConfigMap

在pod的specification里,可以把对ConfigMap的引用标记为 optional 。如果ConfigMap不存在,则对应的配置为空。如果ConfigMap存在但引用的key不存在,则配置也为空。

比如:

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 # mark the variable as optional
  restartPolicy: Never
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 # mark the source ConfigMap as optional
  restartPolicy: Never

限制

  • 在pod的specification中引用ConfigMap之前,必须先创建它,或者将其标记为 optional。如果所引用的ConfigMap不存在,也没有标记为 optional ,则pod将无法启动。同样,引用ConfigMap中不存在的key也会使得pod无法启动,除非将key引用标记为 optional
  • 如果使用 envFrom 来从ConfigMap定义环境变量,则无效的key将被忽略。Pod可以启动,但无效名称将被记录在事件日志中( InvalidVariableNames )。日志消息列出了每个被跳过的key。例如:
kubectl get events

输出结果类似于:

LASTSEEN FIRSTSEEN COUNT NAME          KIND  SUBOBJECT  TYPE      REASON                            SOURCE                MESSAGE
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。
  • ConfigMap不能用于静态pod,因为kubelet不支持。

示例:使用ConfigMap配置Redis

创建文件 example-redis-config.yaml 如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: ""
kubectl apply -f example-redis-config.yaml
$ kubectl describe cm example-redis-config
Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:
----


BinaryData
====

Events:  <none>

创建文件 redis-pod.yaml 如下(参考 https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/config/redis-pod.yaml ):

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis:5.0.4
    command:
      - redis-server
      - "/redis-master/redis.conf"
    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
kubectl apply -f redis-pod.yaml

/redis-master-data 是一个空目录:

kubectl exec redis -- ls /redis-master-data

/redis-master/redis.conf 是一个空文件:

kubectl exec redis -- cat /redis-master/redis.conf

进入容器里的 redis-cli

kubectl exec -it redis -- redis-cli
127.0.0.1:6379>

检查 maxmemory

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"

检查 maxmemory-policy

127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

修改文件 example-redis-config.yaml 如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru
kubectl apply -f example-redis-config.yaml
$ kubectl describe configmap/example-redis-config
Name:         example-redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis-config:
----
maxmemory 2mb
maxmemory-policy allkeys-lru


BinaryData
====

Events:  <none>
kubectl exec -it redis -- redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

可见,配置没有变化,这是因为pod需要重启:

kubectl delete pod redis
kubectl apply -f redis-pod.yaml
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"

可见,现在配置更新了。

参考

  • https://kubernetes.io/docs/concepts/configuration/configmap
  • https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap
  • https://kubernetes.io/docs/tutorials/configuration/configure-redis-using-configmap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/342028.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

透明拼接屏在汽车领域的应用

随着科技的进步&#xff0c;透明拼接屏作为一种新型的显示技术&#xff0c;在汽车领域的应用越来越广泛。尼伽小编将围绕透明拼接屏在汽车本身、4S店、展会、工厂等方面的应用进行深入探讨&#xff0c;并展望未来的设计方向。 一、透明拼接屏在汽车本身的应用 车窗显示&#x…

JeecgBoot 3.6.1使用Online表单开发生成代码,如何定义自定义查询条件

一、使用Online表单生成代码&#xff0c;运行结果如下 二、如果我们想要加入一些筛选条件&#xff0c;例如用姓名查询 1.可在生成的前端代码中加入如下代码&#xff0c;文件为****data.ts //查询数据 export const searchFormSchema: FormSchema[] [ ];2.对如上代码进行编辑…

3D应用开发工具HOOPS引领数字化工厂浪潮:制造业转型的关键角色!

随着科技的迅猛发展&#xff0c;制造业正经历着数字化转型的浪潮。在这一变革的前沿&#xff0c;Tech Soft 3D 的 HOOPS技术正扮演着关键的角色。 本文将深入研究HOOPS技术如何在数字化工作流程中发挥作用&#xff0c;以及它是如何引领制造业朝着更高效、智能的未来迈进的。 …

【C语言进阶】预处理详解

引言 对预处理的相关知识进行详细的介绍 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 预定义符号 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 …

空气净化器or宠物空气净化器?五款猫用空气净化器优质推荐!

作为一个养猫家庭的主人&#xff0c;每天都要面对清理猫砂盘的挑战&#xff0c;这种令人难以形容的气味实在让人难以忍受。尤其是家里有小孩和老人&#xff0c;他们可能会出现过敏性鼻炎等问题&#xff0c;而抵抗力较差的人更容易受到影响。此外&#xff0c;换毛季节到来时&…

Qt 拖拽事件示例

一、引子 拖拽这个动作,在桌面应用程序中是非常实用和具有很友好的交互体验的。我们常见的譬如有,将文件拖拽到某个窗口打开,或者拖拽文件到指定位置上传;在绘图软件中,选中某个模板、并拖拽到画布上,画布上变回绘制该模板的图像… 诸如此类,数不胜数。 那么,在Qt中我…

【MySQL】最左匹配原则

最左匹配原则 0x1 简单说下什么是最左匹配原则 顾名思义&#xff1a;最左优先&#xff0c;以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like&#xff09;就会停止匹配。 例如&#xff1a;b 2 如果建立(a&#xff0c;b&#xff09;顺序…

远程桌面--虚拟机与主机的文件传输

注意&#xff1a; 确保VMware开头的服务全部在运行进入虚拟机打开文件管理器点击计算机右键选择属性在选择远程管理选择允许 1.winR 输入mstsc 2.输入虚拟机的ip地址 2.输入虚拟机的密码 上面的Administrator是虚拟机的用户名&#xff0c;有时会需要我们手动输入 3.验证…

MySQL连表操作之一对多

MySQL连表操作之一对多 目录 引入外键 Navicat创建外键使用外键SQL命令创建外键代码删除外键代码增加外键通过外键进行数据操作 正文 回到顶部 引入 当我们在数据库中创建表的时候&#xff0c;有可能某些列中值内容量很大&#xff0c;而且重复。 例子&#xff1a;创建一个…

基于SpringBoot Vue二手闲置物品交易系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

C语言之反汇编查看函数栈帧的创建与销毁

文章目录 一、 什么是函数栈帧&#xff1f;二、 理解函数栈帧能解决什么问题呢&#xff1f;三、 函数栈帧的创建和销毁解析3.1、什么是栈&#xff1f;3.2、认识相关寄存器和汇编指令3.2.1 相关寄存器3.2.2 相关汇编命令 3.3、 解析函数栈帧的创建和销毁3.3.1 预备知识3.3.2 代码…

Python 猎户星空Orion-14B,截止到目前为止,各评测指标均名列前茅,综合指标最强;Orion-14B表现强大,LLMs大模型

1.简介 Orion-14B-Base是一个具有140亿参数的多语种大模型&#xff0c;该模型在一个包含2.5万亿token的多样化数据集上进行了训练&#xff0c;涵盖了中文、英语、日语、韩语等多种语言。在多语言环境下的一系列任务中展现出卓越的性能。在主流的公开基准评测中&#xff0c;Orio…

Qt —— 自定义飞机仪表控件(附源码)

示例效果 部署环境 本人亲测版本Vs2017+Qt5.12.4,其他版本应该也可使用。 源码1 qfi_ADI::qfi_ADI( QWidget *parent ) :QGraphicsView ( parent ),m_scene ( nullptr )

英语连读技巧12

1. this thing – 这件事 连读听起来就像是&#xff1a;【the sing】 连读的音标为&#xff1a; 例句&#xff1a;i cannot get this thing off my mind. 发音指导&#xff1a;注意 “this” 和 “thing” 两个词在连读时&#xff0c;“s” 和 “th” 的音接近融合&#xf…

浏览器提示“此网站的安全证书有问题”

有时候在浏览一些网站的时候&#xff0c;点进去的时候不是直接显示内容&#xff0c;而是弹出来一个警告的界面&#xff0c;告诉你此网站的安全证书有问题&#xff0c;浏览器是建议你不要再继续访问了&#xff0c;当然你也可以选择继续访问。那么&#xff0c;你还敢继续访问一个…

2.1.2 关系模式

1. 什么是关系模式 2. 定义关系模式 3. 关系模式与关系 1&#xff0e;什么是关系模式 关系模式是型&#xff0c;关系是值 。 关系模式是对关系的描述&#xff1a; 描述关系元组集合的结构 &#xff0c; 属性构成 l&#xff0c;属性来自的域 l&#…

品牌营销:长期价值与潜在利益的共赢之路

在当今品牌营销面临着前所未有的挑战。品牌信息的传递不仅需要迅速&#xff0c;更要持久。而在这个过程中&#xff0c;产品的长期价值和潜在利益成为品牌营销的核心。本文迅腾文化将通过奥卡姆剃刀定律和霍夫曼编码的视角&#xff0c;探讨品牌营销如何实现长期价值和潜在利益的…

gitlab.rb主要配置

根据是否docker安装,进入挂载目录或安装目录 修改此文件,我一般是在可视化窗口中修改,有时候也在命令行手敲 将下面的配置复制到该文件中 external_url http://192.168.100.50 # nginx[listen_port] = 8000 (docker安装的这一行不需要,因为端口映射导致此处修改会导致访问…

助力公益事业,吉林长春市第二社会福利院与清雷科技达成合作

“通过部署清雷科技智慧康养大屏和毫米波雷达监测设备&#xff0c;可以实时查看全院入住人员的生命体征情况&#xff0c;包括呼吸、心率、在离床状态、睡眠报告等&#xff0c;对呼吸异常、跌倒风险异常的人员还会特别标注提醒&#xff0c;提高护理员工作效率的同时&#xff0c;…

SCT9430TVBR:3.8V-36V输入,3A同步降压DCDC转换器

• 通过开关节点无振铃降低 EMI • 400KHz固定开关频率&#xff0c;6% 抖频拓展频谱 • 轻载条件下的脉冲跳跃模式 PSM • 3.8V-36V 宽输入电压范围 • 最大连续3A输出负载 • 0.8V 1% 反馈参考电压 • 集成80mΩ (Rdson) 上端MOSFET 和 42mΩ (Rdson) 下端MOSFET • 1uA 关断电…