介绍
ConfigMap 是 Kubernetes 中的一种资源对象,用于存储非敏感的配置数据,例如键值对、环境变量、配置文件等。它提供了一种将配置数据与应用程序解耦的方式,使得应用程序可以更灵活地部署和管理。
- 注意:ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,可以考虑挂载存储卷 或者使用独立的数据库或者文件服务。
ConfigMaps
这是一个 ConfigMap 的示例,它的一些键只有一个值,其他键的值看起来像是 配置的片段格式
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo # ConfigMap 文件名字
data:
# 类属性键;每一个键都映射到一个简单的值
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
# 类文件键 这个会创建两个文件,文件名字为 game.properties 和 user-interface.properties 文件内容如下显示。
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
创建 ConfigMap
基于一个目录来创建 ConfigMap
操作方法
# 创建本地目录
mkdir configmap
# 将示例文件下载到 `configure-pod-container/configmap/` 目录
wget https://kubernetes.io/examples/configmap/game.properties -O configmap/game.properties --no-check-certificate
wget https://kubernetes.io/examples/configmap/ui.properties -O configmap/ui.properties --no-check-certificate
# 创建ConfigMap
kubectl create configmap game-config --from-file=configmap/
查看创建的ConfigMap
kubectl get cm
NAME DATA AGE
game-config 2 13s
或者
kubectl describe cm
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>
基于文件创建 ConfigMap
使用 kubectl create configmap 基于单个文件或多个文件创建 ConfigMap
# 基于单个文件
kubectl create configmap game-config-2 --from-file=configmap/game.properties
# 也可以多次使用 --from-file 参数,从多个数据源创建 ConfigMap
kubectl create configmap game-config-2 --from-file=configmap/game.properties --from-file=configmap/ui.properties
定义从文件创建 ConfigMap 时要使用的键
在使用 --from-file 参数时,你可以定义在 ConfigMap 的 data 部分出现键名, 而不是按默认行为使用文件名:
# kubectl create configmap game-config-3 --from-file=<我的键名>=<文件路径>
kubectl create configmap game-config-3 --from-file=game-special-key=configmap/game.properties
查看创建的ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: game-config-3
namespace: default
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
使用 --from-env-file 选项基于 env 文件创建 ConfigMap
# Env 文件包含环境变量列表。其中适用以下语法规则:
# 这些语法规则适用:
# Env 文件中的每一行必须为 VAR=VAL 格式。
# 以#开头的行(即注释)将被忽略。
# 空行将被忽略。
# 引号不会被特殊处理(即它们将成为 ConfigMap 值的一部分)。
# 将示例文件下载到 `configmap/` 目录
wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configmap/game-env-file.properties --no-check-certificate
wget https://kubernetes.io/examples/configmap/ui-env-file.properties -O configmap/ui-env-file.properties --no-check-certificate
# Env 文件 `game-env-file.properties` 如下所示
cat configure-pod-container/configmap/game-env-file.properties
enemies=aliens
lives=3
allowed="true"
# 此注释和上方的空行将被忽略
创建Env文件
kubectl create configmap game-config-env-file --from-env-file=configmap/game-env-file.properties
将产生以下 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: "2024-04-07T06:19:10Z"
name: game-config-env-file
namespace: default
resourceVersion: "7783916"
uid: 177cfab4-f74a-4e34-854f-78e85582fe3f
data:
allowed: '"true"'
enemies: aliens
lives: "3"
多次指定 --from-env-file 参数来从多个数据源创建 ConfigMap
kubectl create configmap config-multi-env-files \
--from-env-file=configmap/game-env-file.properties \
--from-env-file=configmap/ui-env-file.properties
根据字面值创建 ConfigMap
你可以将 kubectl create configmap 与 --from-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
kind: ConfigMap
metadata:
name: special-config
namespace: default
data: # 下面这两个是创建的时候指定的值
special.how: very
special.type: charm
ConfigMap 使用方法
使用单个 ConfigMap 中的数据定义容器环境变量
在 ConfigMap 中将环境变量定义为键值对:
kubectl create configmap special-config --from-literal=special.how=very
将 ConfigMap 中定义的 special.how 赋值给 Pod 规约中的 SPECIAL_LEVEL_KEY 环境变量。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
restartPolicy: Never
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# 定义环境变量
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef: # ConfigMap 包含你要赋给 SPECIAL_LEVEL_KEY 的值
name: special-config
key: special.how # 指定与取值相关的键名
创建并启动成功以后,Pod 的输出包含环境变量 SPECIAL_LEVEL_KEY=very
使用来自多个 ConfigMap 的数据定义容器环境变量
创建 ConfigMap。 这是你将使用的清单:
kubectl create -f 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
在 Pod 规约中定义环境变量
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: 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 并运行成功后,Pod 的输出包含环境变量 SPECIAL_LEVEL_KEY=very 和 LOG_LEVEL=INFO。
将 ConfigMap 中的所有键值对配置为容器环境变量
创建一个包含多个键值对的 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
使用 envFrom 将所有 ConfigMap 的数据定义为容器环境变量,ConfigMap 中的键成为 Pod 中的环境变量名称。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
Pod 的输出包含环境变量 SPECIAL_LEVEL=very 和 SPECIAL_TYPE=charm
在 Pod 命令中使用 ConfigMap 定义的环境变量
你可以使用 $(VAR_NAME) Kubernetes 替换语法在容器的 command 和 args 属性中使用 ConfigMap 定义的环境变量。
例如,以下 Pod 清单:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: 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 在 test-container 容器中产生以下输出:
kubectl logs dapi-test-pod
very charm
挂载 ConfigMap中的数据
示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
---
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config # ConfigMap 里面的两个文件会挂在到这个目录
volumes:
- name: config-volume
configMap:
name: special-config # 提供包含要添加到容器中的文件的 ConfigMap 的名称
restartPolicy: Never
Pod 运行时,命令 ls /etc/config/ 产生下面的输出:
SPECIAL_LEVEL
SPECIAL_TYPE
将 ConfigMap 数据添加到卷中的特定路径
使用 path 字段为特定的 ConfigMap 项目指定预期的文件路径。 在这里,ConfigMap 中键 SPECIAL_LEVEL 的内容将挂载在 config-volume 卷中 /etc/config/keys 文件中
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: 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 运行时,命令 cat /etc/config/keys 产生以下输出: very
注意:
如前,/etc/config/ 目录中所有先前的文件都将被覆盖。
subPath 使用方法
在 K8S 中,使用 ConfigMap 挂载配置文件时,默认情况下会覆盖容器中已存在的文件。如果在容器中已经存在相同路径下的文件,那么挂载的 ConfigMap 中的文件会覆盖已有的文件,为了避免这种情况,可以通过设置 subPath 字段来指定挂载的文件。这样可以确保只有指定的文件会被挂载,而不会影响相同路径下的其他的文件。
例如:挂载 nginx 配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: apps
data:
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: apps
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
command: ["bash","-c","sleep 3600"]
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf # 正常nginx 这个目录下有很多其他文件但是我只想挂在 nginx.conf 配置文件,就需要制定挂在的具体文件名字和 subPath 字段
subPath: nginx.conf # 指定 configMap 中文件名字,如果不写 subPath 字段 默认会覆盖nginx目录中的其他文件只剩下 nginx.conf 文件
volumes:
- name: nginx-config-volume
configMap:
name: nginx-config
注意: 使用 ConfigMap 作为 subPath 卷挂载的容器将不会收到 ConfigMap 的更新。
挂载的 ConfigMap 会被自动更新
当已挂载的 ConfigMap 被更新时,所投射的内容最终也会被更新。 这适用于 Pod 启动后可选引用的 ConfigMap 重新出现的情况。
Kubelet 在每次定期同步时都会检查所挂载的 ConfigMap 是否是最新的。 然而,它使用其基于 TTL 机制的本地缓存来获取 ConfigMap 的当前值。 因此,从 ConfigMap 更新到新键映射到 Pod 的总延迟可能与 kubelet 同步周期(默认为 1 分钟)+ kubelet 中 ConfigMap 缓存的 TTL(默认为 1 分钟)一样长。 你可以通过更新 Pod 的一个注解来触发立即刷新。
可选的 ConfigMap
你可以在 Pod 规约中将对 ConfigMap 的引用标记为可选(optional)。 如果 ConfigMap 不存在,那么它在 Pod 中为其提供数据的配置(例如:环境变量、挂载的卷)将为空。 如果 ConfigMap 存在,但引用的键不存在,那么数据也是空的。
例如,以下 Pod 规约将 ConfigMap 中的环境变量标记为可选:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: a-config
key: akey
optional: true # 将环境变量标记为可选
restartPolicy: Never
不能修改的 ConfigMap
Kubernetes 特性 Immutable Secret 和 ConfigMaps 提供了一种将各个 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。