k8s存储介绍(一)configmap
一、config介绍
1. ConfigMap 的核心概念
1.1 什么是 ConfigMap?
ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的资源对象。它可以将配置信息(如环境变量、配置文件、命令行参数等)与应用程序代码分离,从而实现配置的集中管理和动态更新。
-
ConfigMap 是键值对(key-value)的集合。
-
ConfigMap 可以存储纯文本、JSON、XML、YAML 等格式的数据。
-
ConfigMap 是命名空间(Namespace)级别的资源,只能在同一个命名空间内使用。
1.2 ConfigMap 的特点
-
非敏感数据:ConfigMap 不适合存储敏感信息(如密码、密钥等),敏感数据应使用 Secret。
-
动态更新:ConfigMap 的数据可以动态更新,但更新后需要重启 Pod 或使用其他机制使配置生效。
-
多种使用方式:可以通过环境变量、配置文件挂载、命令行参数等方式将 ConfigMap 注入到 Pod 中。
2. ConfigMap 的使用场景
2.1 环境变量注入
将 ConfigMap 中的数据作为环境变量注入到容器中,适用于需要动态配置的环境变量。
2.2 配置文件挂载
将 ConfigMap 中的数据挂载为容器内的配置文件,适用于需要加载外部配置文件的应用程序。
2.3 命令行参数
将 ConfigMap 中的数据作为容器的启动参数,适用于需要动态调整启动参数的场景。
2.4 统一管理配置
集中管理多个应用的配置,便于维护和更新。
3. 创建 ConfigMap
3.1 通过 YAML 文件创建
以下是一个 ConfigMap 的 YAML 示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
# 键值对
log.level: "info"
app.name: "my-app"
# 配置文件
app.properties: |
server.port=8080
db.url=jdbc:mysql://localhost:3306/mydb
db.username=admin
3.2 通过命令行创建
可以通过 kubectl create configmap
命令创建 ConfigMap。
因为是yaml文件,这里使用kubectl create -f 创建
从键值对创建:
kubectl create configmap app-config --from-literal=log.level=info --from-literal=app.name=my-app
从文件创建:
kubectl create configmap app-config --from-file=app.properties=path/to/app.properties
从目录创建:
kubectl create configmap app-config --from-file=path/to/config/dir
4. 使用 ConfigMap
4.1 作为环境变量注入
将 ConfigMap 中的数据作为环境变量注入到 Pod 中。
示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: busybox
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: app-config
key: app.name
说明:
-
LOG_LEVEL
和APP_NAME
是从 ConfigMap 中提取的环境变量。 -
如果 ConfigMap 中的键不存在,Pod 将无法启动。
4.2 作为配置文件挂载
将 ConfigMap 中的数据挂载为容器内的配置文件。
示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: busybox
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: app.properties
path: app.properties
说明:
-
ConfigMap 中的
app.properties
文件会被挂载到容器的/etc/config/app.properties
路径。 -
如果 ConfigMap 更新,挂载的文件也会自动更新(可能需要几分钟)。
-
进入容器查看
可以发现其中内容
4.3 作为命令行参数
将 ConfigMap 中的数据作为容器的启动参数。
示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: busybox
command: ["/bin/sh", "-c", "echo $(LOG_LEVEL) $(APP_NAME)"]
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: app-config
key: app.name
说明:
-
通过环境变量将 ConfigMap 的值传递给容器的启动命令。
启动后查看log,可发现打印的内容
5. 注意事项
5.1 大小限制
-
ConfigMap 的大小限制为 1MB。如果需要存储更大的配置文件,可以考虑将文件存储在外部存储系统中,或者将文件拆分为多个 ConfigMap。
5.2 更新与重启
-
如果 ConfigMap 是通过环境变量注入的,更新 ConfigMap 后需要重启 Pod 才能使新配置生效。
-
如果 ConfigMap 是通过文件挂载的,更新 ConfigMap 后,文件会自动更新,但应用程序可能需要重新加载配置文件。
5.3 敏感数据
-
ConfigMap 不适合存储敏感数据(如密码、密钥等),应使用 Secret。
5.4 命名空间
-
ConfigMap 是命名空间级别的资源,确保在正确的命名空间中创建和使用。
6. 综合示例
场景描述
假设我们有一个应用程序,需要以下配置:
-
环境变量:
LOG_LEVEL=info
、APP_NAME=my-app
-
配置文件:
app.properties
,内容如下:server.port=8080 db.url=jdbc:mysql://localhost:3306/mydb db.username=admin
实现步骤
1. 创建 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
log.level: "info"
app.name: "my-app"
app.properties: |
server.port=8080
db.url=jdbc:mysql://localhost:3306/mydb
db.username=admin
2. 创建 Pod
apiVersion: v1
kind: Pod
metadata:
name: my-pod4
spec:
containers:
- name: my-container
image: busybox
command: ["sh", "-c", "while true; do sleep 3600; done"]
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: log.level
- name: APP_NAME
valueFrom:
configMapKeyRef:
name: app-config
key: app.name
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: app.properties
path: app.properties
3. 验证
-
进入 Pod 查看环境变量:
kubectl exec -it my-pod -- env | grep LOG_LEVEL kubectl exec -it my-pod -- env | grep APP_NAME
二、configmap热更新
1. ConfigMap 热更新的原理
1.1 什么是热更新?
热更新是指在不重启 Pod 的情况下,动态更新应用程序的配置。对于 ConfigMap 来说,如果将其挂载为文件(Volume),Kubernetes 会自动更新文件内容,但应用程序需要支持重新加载配置文件才能生效。
1.2 热更新的限制
-
环境变量:如果 ConfigMap 是通过环境变量注入的,更新 ConfigMap 后需要重启 Pod 才能使新配置生效。
-
文件挂载:如果 ConfigMap 是通过文件挂载的,Kubernetes 会自动更新文件内容,但应用程序需要支持重新加载配置文件(如通过 SIGHUP 信号或定期检查文件变化)。
2. 热更新示例
2.1 场景描述
假设我们有一个应用程序,使用 ConfigMap 挂载的配置文件 app.properties
,内容如下:
properties
server.port=8080 app.name=my-app
我们希望在不重启 Pod 的情况下,动态更新 app.properties
文件的内容。
2.2 实现步骤
1. 创建 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8080
app.name=my-app
通过以下命令创建 ConfigMap:
kubectl apply -f app-config.yaml
2. 创建 Pod
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: busybox
args:
- /bin/sh
- -c
- |
while true; do
echo "Current config:"
cat /etc/config/app.properties
sleep 10
done
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
通过以下命令创建 Pod:
kubectl apply -f my-pod.yaml
3. 验证初始配置
进入 Pod 查看挂载的配置文件:
kubectl exec -it my-pod -- cat /etc/config/app.properties
输出应为:
4. 更新 ConfigMap
修改 app-config.yaml
,更新 app.properties
的内容:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
server.port=8081
app.name=my-app-v2
通过以下命令修改 ConfigMap:
5. 观察热更新
Kubernetes 会自动更新 Pod 中挂载的配置文件。可以通过以下命令观察文件内容的变化:
kubectl logs my-pod -f
输出示例:
可以看到,配置文件的内容已经更新,而 Pod 并未重启。
3. 注意事项
3.1 更新延迟
ConfigMap 的更新可能会有一定的延迟(通常为几秒到几分钟),具体取决于 Kubernetes 的配置和集群状态。
3.2 应用程序支持
热更新需要应用程序支持动态加载配置文件,否则即使文件更新了,应用程序也不会生效。
3.3 文件权限
挂载的 ConfigMap 文件默认是只读的,应用程序不能修改这些文件。
4. 总结
通过 ConfigMap 的热更新机制,可以在不重启 Pod 的情况下动态更新应用程序的配置。关键在于:
-
将 ConfigMap 挂载为文件(Volume)。
-
应用程序需要支持动态加载配置文件。