Kubernetes中使用ConfigMap大全
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes中使用ConfigMap大全相关的知识,希望对你有一定的参考价值。
参考技术A ConfigMap在K8S中经常会使用到,它能使容器镜像和配置内容解耦,它可以绑定在volume上供容器访问,它的创建和使用也是灵活多样,这篇文章翻译自Kubernetes官网,详细演示了如何创建ConfigMap和如何使用ConfigMap配置Pod,内容比较全面,希望能帮助到大家。可以使用 kubectl create configmap 或 kustomization.yaml 中的 ConfigMap 生成器来创建 ConfigMap。 请注意,kubectl 从 1.14 开始支持 kustomization.yaml。
使用 kubectl create configmap 命令可以从目录、文件或文字值创建 ConfigMap。
其中 <map-name> 是您要分配给 ConfigMap 的名称,<data-source> 是从中提取数据的目录、文件或文字值。 ConfigMap 对象的名称必须是有效的 DNS 子域名。
基于文件创建ConfigMap时,<data-source>中的key默认为文件的basename,value默认为文件内容。
您可以使用 kubectl describe 或 kubectl get 来检索有关 ConfigMap 的信息。
您可以使用 kubectl create configmap 从同一目录中的多个文件创建一个 ConfigMap。 当你基于目录创建 ConfigMap 时,kubectl 会识别基本名称是目录中有效键的文件,并将这些文件中的每一个打包到新的 ConfigMap 中。 除常规文件外的任何目录条目都将被忽略(例如子目录、符号链接、设备、管道等)。例如:
上述命令将 configure-pod-container/configmap/ 目录中的每个文件(在本例中为 game.properties 和 ui.properties)打包到 game-config ConfigMap 中。 你可以使用以下命令显示 ConfigMap 的详细信息:
输入结果类似如下:
configure-pod-container/configmap/ 目录中的 game.properties 和 ui.properties 文件在 ConfigMap 的数据部分中表示。
输出如下:
可以使用 kubectl create configmap 从单个文件或多个文件创建 ConfigMap。例如:
使用kubectl describe可以查看
输出如下:
我们可以多次传入 --from-file 参数以从多个数据源创建 ConfigMap。
使用以下命令显示 game-config-2 ConfigMap 的详细信息:
输出如下:
当 kubectl 从非 ASCII 或 UTF-8 输入创建 ConfigMap 时,该工具会将这些放入 ConfigMap 的 binaryData 字段中,而不是数据中。 文本和二进制数据源都可以组合在一个 ConfigMap 中。 如果要查看 ConfigMap 中的 binaryData 键(及其值),可以运行 kubectl get configmap -o jsonpath='.binaryData' <name>。
使用选项 --from-env-file 从 env-file 创建一个 ConfigMap,例如:
运行下面的两个命令将创建如下的ConfigMap
输出如下:
如下实例:
输出如下:
使用 --from-file 参数时,您可以定义要在 ConfigMap 的数据部分中使用的文件名以外的键:
其中 <my-key-name> 是您要在 ConfigMap 中使用的键,<path-to-file> 是您希望该键表示的数据源文件的位置。
例如:
将产生如下的输出:
可以使用带有 --from-literal 参数的 kubectl create configmap 从命令行定义文字值:
产生输出如下:
kubectl 从 1.14 开始支持 kustomization.yaml。 您还可以从Generator创建一个 ConfigMap,然后应用它在 Apiserver 上创建对象。 Generator应在目录内的 kustomization.yaml 中指定。
例如,从文件 configure-pod-container/configmap/game.properties 生成一个 ConfigMap
应用 kustomization 目录来创建 ConfigMap 对象。
使用以下命令来check ConfigMap内容:
你可以定义要在 ConfigMap 生成器中使用的文件名以外的键。 例如,要从文件 configure-pod-container/configmap/game.properties 中生成一个 ConfigMap,其key为 game-special-key。
应用 kustomization 目录来创建 ConfigMap 对象。
如下实例:
应用 kustomization 目录来创建 ConfigMap 对象。
1)从单个ConfigMap的Data中定义容器环境变量
如下实例,
第一步,创建ConfigMap
第二步,在Pod specification中使用ConfigMap中定义的值赋给环境变量
实例如下:
第一步,声明多个ConfigMaps
第二步,创建ConfigMaps
第三步,在pod specification中使用ConfigMap中的Data
实例如下:
第一步,声明ConfigMap
第二步,创建ConfigMap
第三步,使用envFrom定义ConfigMap中所有data作为容器的环境变量。
第四步,创建POD
现在Pod中的环境变量包括SPECIAL_LEVEL=very 和 SPECIAL_TYPE=charm.
实例如下:
上面的实例中演示了从文件中创建ConfigMaps,文件名成为了key,文件内容成为了键值。
第一步,创建ConfigMap
第二步,使用ConfigMap里的存储的数据绑定到volume
在 Pod specification的volume部分下添加 ConfigMap 名称。 这会将 ConfigMap 数据添加到指定为 volumeMounts.mountPath 的目录(在本例中为 /etc/config)。 命令部分列出了名称与 ConfigMap 中的键匹配的目录文件。
创建Pod
当pod运行后,命令 ls /etc/config/产生下面的输出
实例如下:
创建Pod
当pod运行后,命令 ls /etc/config/产生下面的输出
ConfigMap Reference可以被标记为“可选”。 如果 ConfigMap 不存在,则挂载的卷将为空。 如果 ConfigMap 存在,但引用的键不存在,则安装点下方将不存在路径。
当挂载的ConfigMap 更新时,映射内容最终也会更新。 这适用于在 pod 启动后存在可选引用的 ConfigMap 的情况。
Kubelet 在每次定期同步时检查挂载的 ConfigMap 是否是最新的。 但是,它使用其本地基于TTL的缓存来获取 ConfigMap 的当前值。 因此,从更新 ConfigMap 到将新key投射到Pod的总延迟可以达到kubelet同步周期(默认为 1 分钟)+ ConfigMaps 缓存的 TTL(默认为 1 分钟) )。 在 kubelet 中,您可以通过更新 pod 的注释之一来触发立即刷新。
ConfigMap API 资源将配置数据存储为键值对。 数据可以在 pod 中使用,也可以为控制器等系统组件提供配置。 ConfigMap类似于Secrets,但提供了一种处理不包含敏感信息的字符串的方法。 用户和系统组件都可以在ConfigMap中存储配置数据。
输出类似结果:
Kubernetes-ConfigMap
1. 简介
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods
可以将其用作环境变量
、命令行参数
或者存储卷中的配置文件
。
ConfigMap 将您的环境配置信息和容器镜像解耦,便于应用配置的修改。
注意:ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret。
ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,你可能希望考虑挂载存储卷 或者使用独立的数据库或者文件服务。
2. 4种创建方式
2.1 通过key-value创建
$ kubectl create configmap redis-1.conf --from-literal=requirepass=123456 --from-literal=appendonly=yes
创建一个名称为redis-1.conf
的cm,且参数信息为
-
requirepass=123456
:redis 开启密码认证且密码为123456 -
appendonly=yes
:redis 开启aof
还有种简单的创建方式创建此种类型的ConfigMap
$ kubectl create configmap redis-1.conf --from-env-file=./redis-env
2.2 * 通过配置文件创建
--from-file 可以多次使用,挂载进多个文件
$ kubectl create configmap redis-2.conf --from-file=./redis.conf
2.3 通过配置文件的目录创建
$ kubectl create configmap redis-3.conf --from-file=./
2.4 * 直接编写ConfigMap文件
apiVersion: v1
data:
redis.conf: |
requirepass 123456
appendonly yes
kind: ConfigMap
metadata:
name: redis-4.conf
namespace: default
ConfigMap 使用 data
和 binaryData
字段。这些字段能够接收键-值对作为其取值。data
和 binaryData
字段都是可选的。data
字段设计用来保存 UTF-8 字节序列,而 binaryData
则 被设计用来保存二进制数据作为 base64 编码的字串。
2.5 小节
以上四种方式都可以创建cm,但是仔细看会发现创建的文件内容其实都不太一样
- 2.1 创建的cm如果以volume方式挂载到pod中,最终会在pod中生成两个文件
requirepass
(内容为123456),appendonly
(内容为yes),这种方式即使挂载成功了也不是我们所期望的结果,验证步骤如3.1.1 - 2.2 创建的cm如果以volume方式挂载到pod中,其效果和2.4一样,最终会生成一个配置文件redis.conf,且文件内容为
requirepass 123456 appendonly yes
符合所期望的,验证步骤如3.1.2 - 2.3 则是将制定目录下的文件都囊括到了cm中,将cm挂载到 pod中后,其实和当前的文件夹的内容一致,验证步骤如3.1.3
3. 3种挂载方式
3.1 通过volume方式挂载
3.1.1 挂载2.1中的cm
将2.1中的cm(redis-1.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-1
spec:
containers:
- name: redis-1
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /etc/redis
name: config
volumes:
- name: config
configMap:
# 指定cm name
name: redis-1.conf
# 如果想挂载特定的key 可以使用以下方式
#items:
# - key: requirepass # data key
# path: requirepass.txt # 挂载进pod后的文件名称
3.1.2 挂载2.2中的cm
将2.2中的cm(redis-2.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-2
spec:
containers:
- name: redis-2
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
# 指定启动的配置文件
command:
- redis-server
# 指的是redis容器内部的位置
- "/etc/redis/redis.conf"
volumeMounts:
- mountPath: /etc/redis
name: config
volumes:
- name: config
configMap:
name: redis-2.conf
3.1.3 挂载2.3中的cm
将2.3中的cm(redis-3.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-3
spec:
containers:
- name: redis-3
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
command:
- redis-server
- "/etc/redis/redis.conf"
volumeMounts:
- mountPath: /etc/redis
name: config
volumes:
- name: config
configMap:
name: redis-3.conf
3.1.4 挂载2.4中的cm
将2.4中的cm(redis-4.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-4
spec:
containers:
- name: redis-4
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
command:
- redis-server
- "/etc/redis/redis.conf" #指的是redis容器内部的位置
volumeMounts:
- mountPath: /etc/redis
name: config
volumes:
- name: config
configMap:
name: redis-4.conf
3.2 通过环境变量方式挂载
3.2.1 挂载2.1中的cm
将2.1中的cm(redis-1.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-env-1
spec:
containers:
- name: redis-env-1
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
env:
# 定义环境变量
- name: REDIS_CONF_PASSWORD # 请注意这里和 ConfigMap 中的键名是不一样的
valueFrom:
configMapKeyRef:
name: redis-1.conf # 这个值来自 ConfigMap
key: appendonly # 需要取值的键
- name: REDIS_CONF_APPENDONLY
valueFrom:
configMapKeyRef:
name: redis-1.conf
key: requirepass
也可以直接导入ConfigMap中的所有key value
apiVersion: v1
kind: Pod
metadata:
name: redis-env-1
spec:
containers:
- name: redis-env-1
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
envFrom:
- configMapRef:
# cm name
name: redis-1.conf
3.2.2 挂载2.2中的cm
将2.2中的cm(redis-2.conf)挂载到pod中看下效果
apiVersion: v1
kind: Pod
metadata:
name: redis-env-2
spec:
containers:
- name: redis-env-2
image: redis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
env:
# 定义环境变量
- name: REDIS_CONF # 请注意这里和 ConfigMap 中的键名是不一样的
valueFrom:
configMapKeyRef:
name: redis-2.conf # 这个值来自 ConfigMap
key: redis.conf # 需要取值的键
从输出内容上看,把文件中的内容转成了一个字符串,所以如果要挂载环境变量的内容,还是使用2.1的cm会更合理点。
3.3 通过命令行参数挂载
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","--"]
args:
# 输出环境变量
- "echo requirepass\':\'$requirepass;echo appendonly\':\'$appendonly"
envFrom:
- configMapRef:
name: redis-1.conf
restartPolicy: Never
4. subPath
如果我们想挂载配置文件时,只覆盖指定mountPath
下的指定文件(因为默认会把ConfigMap中的信息挂载到mountPath下,此时mountPath下只有ConfigMap的配置文件,mountPath下本来有的配置文件会被清除掉),那么需要使用subpath
来指定要被覆盖的文件
我在volume的6.0中详细的写了相关的配置,感兴趣的可以了解下。
5. 被挂载的 ConfigMap 内容会被自动更新
当卷中使用的 ConfigMap 被更新时,所投射的键最终也会被更新。 kubelet 组件会在每次周期性同步时检查所挂载的 ConfigMap 是否为最新。 不过,kubelet 使用的是其本地的高速缓存来获得 ConfigMap 的当前值。 高速缓存的类型可以通过 KubeletConfiguration 结构 的 ConfigMapAndSecretChangeDetectionStrategy
字段来配置。
ConfigMap 既可以通过 watch 操作实现内容传播(默认形式),也可实现基于 TTL 的缓存,还可以直接经过所有请求重定向到 API 服务器。 因此,从 ConfigMap 被更新的那一刻算起,到新的主键被投射到 Pod 中去,这一 时间跨度可能与 kubelet 的同步周期加上高速缓存的传播延迟相等。 这里的传播延迟取决于所选的高速缓存类型 (分别对应 watch 操作的传播延迟、高速缓存的 TTL 时长或者 0)。
以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要重新启动 Pod。
6. 不可变更的 ConfigMap
从 v1.19 开始,你可以添加一个 immutable
字段到 ConfigMap 定义中,创建 不可变更的 ConfigMap
。
Kubernetes 特性 不可变更的 Secret 和 ConfigMap 提供了一种将各个 Secret 和 ConfigMap 设置为不可变更的选项。对于大量使用 ConfigMap 的 集群(至少有数万个各不相同的 ConfigMap 给 Pod 挂载)而言,禁止更改 ConfigMap 的数据有以下好处:
- 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
- 通过大幅降低对 kube-apiserver 的压力提升集群性能,这是因为系统会关闭 对已标记为不可变更的 ConfigMap 的监视操作。
你可以通过将 immutable
字段设置为 true
创建不可变更的 ConfigMap。 例如:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
一旦某 ConfigMap 被标记为不可变更,则 无法 逆转这一变化,,也无法更改 data
或 binaryData
字段的内容。你只能删除并重建 ConfigMap。 因为现有的 Pod 会维护一个对已删除的 ConfigMap 的挂载点,建议重新创建 这些 Pods。
以上是关于Kubernetes中使用ConfigMap大全的主要内容,如果未能解决你的问题,请参考以下文章
kubernetes部署springboot项目使用configmap尝试