k8s configMap
configMap
可变配置管理
cofigMap
卷 提供了向 Pod 注入配置数据的方法。 ConfigMap 对象中存储的数据可以被 configMap
类型的卷引用,然后被 Pod 中运行的 容器化应用使用。简单说config就是放置配置信息,加密信息可以使用Secret
存放。
说明
配置 Pod 使用 ConfigMap
创建 ConfigMap
你可以使用 kubectl create configmap
的 ConfigMap 生成器 来创建 ConfigMap。
使用 kubectl create configmap 创建 ConfigMap
你可以使用 kubectl create configmap
命令基于 目录
、文件
或者字面值
来创建 ConfigMap:
1 | kubectl create configmap <map-name> <data-source> |
其中,map-name 是要设置的 ConfigMap 名称,data-source 是要从中提取数据的目录、 文件或者字面值。 ConfigMap 对象的名称必须是合法的 DNS 子域名.
基于目录创建 ConfigMap
你可以使用 kubectl create configmap
基于同一目录中的多个文件创建 ConfigMap。 当你基于目录来创建 ConfigMap 时,kubectl 识别目录下基本名可以作为合法键名的 文件,并将这些文件打包到新的 ConfigMap 中。普通文件之外的所有目录项都会被 忽略(例如,子目录、符号链接、设备、管道等等)。
1 | 创建本地目录 |
以上命令将 configure-pod-container/configmap
目录下的所有文件,也就是 game.properties
和 ui.properties
打包到 game-config ConfigMap 中。你可以使用下面的命令显示 ConfigMap 的详细信息:
1 | kubectl describe configmaps game-config |
输出类似以下内容:
1 | kubectl describe configmaps game-config |
configure-pod-container/configmap/
目录中的 game.properties
和 ui.properties
文件出现在 ConfigMap 的 data
部分。
1 | kubectl get configmaps game-config -o yaml |
输出类似以下内容:
1 | apiVersion: v1 |
基于文件创建 ConfigMap
你可以使用 kubectl create configmap
基于单个文件或多个文件创建 ConfigMap。
from-file
单个文件
例如
1 | kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties |
将产生以下 ConfigMap:
1 | kubectl describe configmaps game-config-2 |
输出类似以下内容:
1 | Name: game-config-2 |
多个文件
例如
1 | kubectl create configmap game-config-3 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties |
描述上面创建的 game-config-3
configmap
1 | kubectl describe configmaps game-config-3 |
输出以下内容:
1 | Name: game-config-3 |
from-env-file
使用 --from-env-file
选项从环境文件创建 ConfigMap,例如:
Env 文件包含环境变量列表。 其中适用以下语法规则:
- Env 文件中的每一行必须为 VAR=VAL 格式。
- 以#开头的行(即注释)将被忽略。
- 空行将被忽略。
- 引号不会被特殊处理(即它们将成为 ConfigMap 值的一部分)。
将示例文件下载到 configure-pod-container/configmap/
目录
1 | wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties |
env 文件 game-env-file.properties
如下所示:
1 | cat configure-pod-container/configmap/game-env-file.propertiesenemies=alienslives=3allowed="true" |
1 | kubectl create configmap game-config-env-file \ |
将产生以下 ConfigMap:
1 | kubectl get configmap game-config-env-file -o yaml |
输出类似以下内容:
1 | apiVersion: v1 |
注意: 当多次使用
--from-env-file
来从多个数据源创建 ConfigMap 时,仅仅最后一个 env 文件有效。
定义从文件创建 ConfigMap 时要使用的键
在使用 --from-file
参数时,你可以定义在 ConfigMap 的 data
部分出现键名, 而不是按默认行为使用文件名:
1 | kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file> |
<my-key-name>
是你要在 ConfigMap 中使用的键名,<path-to-file>
是你想要键表示数据源文件的位置。
例如:
1 | kubectl create configmap game-config-4 --from-file=game-special-key=configure-pod-container/configmap/game.properties |
将产生以下 ConfigMap:
1 | kubectl get configmaps game-config-4 -o yaml |
输出类似以下内容:
1 | apiVersion: v1 |
根据字面值创建 ConfigMap
from-literal参数
你可以将 kubectl create configmap
与 --from-literal
参数一起使用,从命令行定义文字值:
1 | kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm |
你可以传入多个键值对。命令行中提供的每对键值在 ConfigMap 的 data
部分中均表示为单独的条目。
1 | kubectl get configmaps special-config -o yaml |
输出类似以下内容:
1 | apiVersion: v1 |
key-value形式的键值
使用 key-value
形式的键值对来配置数据,这些数据可以在 Pod 里面使用,如下所示的资源清单:
1 | kind: ConfigMap |
其中配置数据在 data
属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件。
我们可以看到 config
后面有一个竖线符 |
,这在 yaml 中表示保留换行,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留。
1 | { |
除了竖线之外还可以使用 >
右尖括号,用来表示折叠换行,只有空白行才会被识别为换行,原来的换行符都会被转换成空格
1 | kind: ConfigMap |
1 | kubectl get configmaps cm-demo -o json |
除了这两个指令之外,我们还可以使用竖线和加号或者减号进行配合使用,+
表示保留文字块末尾的换行,-
表示删除字符串末尾的换行。
1 | apiVersion: v1 |
1 | kubectl get configmaps game-config-2 -o json |
使用
ConfigMap
创建成功了,那么我们应该怎么在 Pod 中来使用呢?我们说 ConfigMap
这些配置数据可以通过很多种方式在 Pod 里使用,主要有以下几种方式:
- 设置环境变量的值
- 在容器里设置命令行参数
- 在数据卷里面挂载配置文件
设置环境变量
使用单个 ConfigMap 中的数据定义容器环境变量
在 ConfigMap 中将环境变量定义为键值对:
1
kubectl create configmap special-config --from-literal=special.how=very
将 ConfigMap 中定义的
special.how
值分配给 Pod 规范中的SPECIAL_LEVEL_KEY
环境变量。pods/pod-single-configmap-env-variable.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: v1
kind: Podmeta
data:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: 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创建 Pod:
1
kubectl create -f https://kubernetes.io/examples/pods/pod-single-configmap-env-variable.yaml
现在,Pod 的输出包含环境变量
SPECIAL_LEVEL_KEY=very
。
使用来自多个 ConfigMap 的数据定义容器环境变量
与前面的示例一样,首先创建 ConfigMap。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: 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:
1
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
在 Pod 规范中定义环境变量。
pods/pod-multiple-configmap-env-variable.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/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:
1
kubectl create -f https://kubernetes.io/examples/pods/pod-multiple-configmap-env-variable.yaml
现在,Pod 的输出包含环境变量
SPECIAL_LEVEL_KEY=very
和LOG_LEVEL=INFO
。
将 ConfigMap 中的所有键值对配置为容器环境变量
说明: Kubernetes v1.6 和更高版本支持此功能。
创建一个包含多个键值对的 ConfigMap。
configmap/configmap-multikeys.yaml
1
2
3
4
5
6
7
8apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm创建 ConfigMap:
1
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
使用
envFrom
将所有 ConfigMap 的数据定义为容器环境变量,ConfigMap 中的键成为 Pod 中的环境变量名称。pods/pod-configmap-envFrom.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never创建 Pod:
1
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-envFrom.yaml
现在,Pod 的输出包含环境变量
SPECIAL_LEVEL=very
和SPECIAL_TYPE=charm
。
在容器里设置命令行参数
在 Pod 命令中使用 ConfigMap 定义的环境变量
你可以使用 $(VAR_NAME)
Kubernetes 替换语法在容器的 command
和 args
部分中使用 ConfigMap 定义的环境变量。
例如,以下 Pod 规范
pods/pod-configmap-env-var-valueFrom.yaml
1 | apiVersion: v1 |
通过运行下面命令创建 Pod:
1 | kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-env-var-valueFrom.yaml |
在 test-container
容器中产生以下输出:
1 | very charm |
在数据卷里面挂载配置文件
将 ConfigMap 数据添加到一个卷中
如基于文件创建 ConfigMap 中所述,当你使用 --from-file
创建 ConfigMap 时,文件名成为存储在 ConfigMap 的 data
部分中的键, 文件内容成为键对应的值。
本节中的示例引用了一个名为 special-config 的 ConfigMap,如下所示:
configmap/configmap-multikeys.yaml
1 | apiVersion: v1 |
创建 ConfigMap:
1 | kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml |
使用存储在 ConfigMap 中的数据填充数据卷
在 Pod 规约的 volumes
部分下添加 ConfigMap 名称。 这会将 ConfigMap 数据添加到指定为 volumeMounts.mountPath
的目录(在本例中为 /etc/config
)。 command
部分引用存储在 ConfigMap 中的 special.level
。
pods/pod-configmap-volume.yaml
1 | apiVersion: v1 |
创建 Pod:
1 | kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume.yaml |
Pod 运行时,命令 ls /etc/config/
产生下面的输出:
1 | SPECIAL_LEVELSPECIAL_TYPE |
注意: 如果在 /etc/config/
目录中有一些文件,它们将被删除。
说明: 文本数据会使用 UTF-8 字符编码的形式展现为文件。如果使用其他字符编码, 可以使用 binaryData
。
将 ConfigMap 数据添加到数据卷中的特定路径
使用 path
字段为特定的 ConfigMap 项目指定预期的文件路径。 在这里,ConfigMap中,键值 SPECIAL_LEVEL
的内容将挂载在 config-volume
数据卷中 /etc/config/keys
文件下。
pods/pod-configmap-volume-specific-key.yaml
1 | apiVersion: v1 |
创建Pod:
1 | kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume-specific-key.yaml |
当 pod 运行时,命令 cat /etc/config/keys
产生以下输出:
1 | very |
注意: 如前,/etc/config/
目录中所有先前的文件都将被删除
映射键以指定路径和文件权限
你可以通过指定键名到特定目录的投射关系,也可以逐个文件地设定访问权限。 Secret 用户指南 中对这一语法提供了解释。
挂载的 ConfigMap 将自动更新
更新已经在数据卷中使用的 ConfigMap 时,已映射的键最终也会被更新。 kubelet
在每次定期同步时都会检查已挂载的 ConfigMap 是否是最新的。 但是,它使用其本地的基于 TTL 的缓存来获取 ConfigMap 的当前值。 因此,从更新 ConfigMap 到将新键映射到 Pod 的总延迟可能与 kubelet 同步周期 + ConfigMap 在 kubelet 中缓存的 TTL 一样长。
说明: 使用 ConfigMap 作为 subPath 的数据卷将不会收到 ConfigMap 更新。
了解 ConfigMap 和 Pod
ConfigMap API 资源将配置数据存储为键值对。 数据可以在 Pod 中使用,也可以提供系统组件(如控制器)的配置。 ConfigMap 与 Secret 类似, 但是提供了一种使用不包含敏感信息的字符串的方法。 用户和系统组件都可以在 ConfigMap 中存储配置数据。
说明: ConfigMap 应该引用属性文件,而不是替换它们。可以将 ConfigMap 理解为类似于 Linux /etc
目录及其内容的东西。例如,如果你从 ConfigMap 创建 Kubernetes 卷,则 ConfigMap 中的每个数据项都由该数据卷中的单个文件表示。
ConfigMap 的 data
字段包含配置数据。如下例所示,它可以简单 (如用 --from-literal
的单个属性定义)或复杂 (如用 --from-file
的配置文件或 JSON blob定义)。
1 | apiVersion: v1 |
限制
在 Pod 规范中引用之前,必须先创建一个 ConfigMap(除非将 ConfigMap 标记为”可选”)。 如果引用的 ConfigMap 不存在,则 Pod 将不会启动。同样,引用 ConfigMap 中不存在的键也会阻止 Pod 启动。
如果你使用
envFrom
基于 ConfigMap 定义环境变量,那么无效的键将被忽略。 可以启动 Pod,但无效名称将记录在事件日志中(InvalidVariableNames
)。 日志消息列出了每个跳过的键。例如:1
kubectl get events
输出与此类似:
1
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE0s 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 位于特定的名字空间 中。每个 ConfigMap 只能被同一名字空间中的 Pod 引用.
你不能将 ConfigMap 用于 静态 Pod, 因为 Kubernetes 不支持这种用法。
只有通过 Kubernetes API 创建的 Pod 才能使用
ConfigMap
,其他方式创建的(比如静态 Pod)不能使用;ConfigMap 文件大小限制为1MB
(ETCD 的要求)。