K8S ConfigMap 快速开始

K8S ConfigMap 快速开始

一、什么是 ConfigMap?

ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的 API 对象,支持以键值对(Key-Value)或文件的形式存储配置,允许将配置与镜像解耦,实现配置的集中管理和动态更新。

二、主要用途

存储配置数据

应用的配置文件(如 config.properties、app.yaml)。环境变量(如数据库连接字符串、API 地址)。命令行参数或启动脚本。解耦配置与镜像同一镜像可通过不同 ConfigMap 适配不同环境(如开发环境使用本地数据库,生产环境使用远程数据库)。使用 ConfigMap 可以统一管理不同环境(开发、测试、生产)的配置差异。解耦应用配置与镜像,避免硬编码配置到镜像中。动态更新配置修改 ConfigMap 后,可通过重启 Pod 或热加载(依赖应用支持)使新配置生效。

三、局限性

ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,你可能希望考虑挂载存储卷 或者使用独立的数据库或者文件服务。ConfigMap 的热加载依赖应用自己实现。

四、创建 ConfigMap 的方式

ConfigMap 可通过 kubectl 命令或 YAML 文件创建,支持三种数据源:文件、目录、字面量。

4.1、通过 kubectl 命令创建

4.1.1、使用字面量创建

kubectl create configmap my-config --from-literal=username=admin --from-literal=password=123456

--from-literal=key1=config1 --from-literal=key2=config2literal 字面量的意思configmap 可以简写为 cm

kubectl describe cm my-config

4.1.2、使用文件创建

# 单个文件

kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt

# 文件名 file1.txt 作为 key

kubectl create configmap my-config --from-file=/path/to/bar/file1.txt

# 多个文件

kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

单个文件

vim config.properties

### 文件内容如下

server.port=8080

application.name=myapp

kubectl create configmap my-config --from-file=config=./config.properties

# 文件名作为 key

kubectl create cm my-config --from-file=config.properties

多个文件

vim db.properties

### 文件内容如下

datasource.username=root

datasource.password=123456

datasource.url=jdbc:mysql://localhost:3306/order

kubectl create configmap my-config --from-file=config.properties --from-file=db.properties

4.1.3、使用目录创建

kubectl create configmap my-config --from-file=path/to/bar

mkdir conf

cd conf

vim application.yaml

### 文件内容如下

server:

port: 8080

spring:

cloud:

nacos:

discovery:

username: nacos

password: nacos

group: DEFAULT_GROUP

server-addr: 127.0.0.1:8848

application:

name: order-service

###

vim db.properties

### 文件内容如下

datasource.username=root

datasource.password=123456

datasource.url=jdbc:mysql://localhost:3306/order

###

cd ..

kubectl create cm my-config --from-file=conf

4.2、通过 YAML 文件创建

configmap.yaml

apiVersion: v1

kind: ConfigMap

metadata:

name: my-config

data:

username: "admin"

password: "123456"

application.yaml: |

server:

port: 8080

db.properties: |

datasource.username=root

datasource.password=123456

| 表示下面的内容为多行。

kubectl apply -f configmap.yaml

五、在 Pod 中使用 ConfigMap

ConfigMap 可通过 环境变量 或 Volume 挂载 注入到容器中。

我们以 4.2 节创建的 my-config 为例,来讲解如何在 Pod 中使用 ConfigMap。

5.1、作为环境变量注入 env

apiVersion: v1

kind: Pod

metadata:

name: envcm-pod

spec:

restartPolicy: Never

containers:

- name: envcm-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["sleep", "3600"]

env:

- name: USERNAME # 定义容器中的环境变量

valueFrom:

configMapKeyRef:

name: my-config # ConfigMap 的名字

key: username # ConfigMap 中的 key

- name: PASSWORD

valueFrom:

configMapKeyRef:

name: my-config

key: password

像 Alpine 镜像,或者基于 Alpine 制作的工具镜像,容器内没有运行服务,需要启动后休眠一段时间,防止容器被 K8S 杀掉。restartPolicy: Never 休眠结束后容器退出就退出了,不需要 K8S 重启该容器。默认是 Always 总是重启。设为 Never 防止浪费系统资源。

进入容器查看环境变量

kubectl exec -it envcm-pod -- /bin/sh

/# env

USERNAME=admin

PASSWORD=123456

5.2、作为环境变量注入 envFrom

apiVersion: v1

kind: Pod

metadata:

name: envfrom-pod

spec:

restartPolicy: Never

containers:

- name: envcm-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["sleep", "3600"]

envFrom:

- configMapRef:

name: my-config

以整个 ConfigMap 作为环境变量数据源。

进入容器查看环境变量

kubectl exec -it envfrom-pod -- /bin/sh

/ # env

5.3、环境变量方式使用的 ConfigMap 数据不会被自动更新

以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要重新启动 Pod。

# 编辑 ConfigMap

kubectl edit cm my-config

# 把 password 从 123456 -> 456789

# 像 vim 一样 wq 保存退出

进入容器查看环境变量

kubectl exec -it envcm-pod -- /bin/sh

/# env

USERNAME=admin

# 还是 123456

PASSWORD=123456

kubectl exec -it envfrom-pod -- /bin/sh

# 还是 123456

password=123456

5.4、通过 Volume 挂载为文件

apiVersion: v1

kind: Pod

metadata:

name: volumes-pod

spec:

restartPolicy: Never

volumes:

- name: volumes-name # 卷的名字

configMap:

name: my-config # ConfigMap 的名字

containers:

- name: volumes-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["sleep", "3600"]

volumeMounts:

- name: volumes-name

mountPath: /data/conf # 挂载到容器哪个目录

进入容器查看文件

kubectl exec -it volumes-pod -- /bin/sh

以 Volume 形式挂载 ConfigMap,ConfigMap 每一个 key 都会生成一个文件。

进入容器查看环境变量

kubectl exec -it volumes-pod -- /bin/sh

/# env

环境变量中不会有配置信息

5.5、热加载

# 编辑 ConfigMap

kubectl edit cm my-config

# 把 password 从 456789 -> 111111

# 像 vim 一样 wq 保存退出

进入容器查看文件

kubectl exec -it volumes-pod -- /bin/sh

容器内文件的值被更新了。但是会有一定的延迟。具体延迟多少,官方介绍取决于高速缓存类型。

5.6、items 选取 key

我们知道,以 Volume 形式挂载 ConfigMap,ConfigMap 的每一个 key 都会生成一个文件。

对于 4.2 的 ConfigMap:

apiVersion: v1

kind: ConfigMap

metadata:

name: my-config

data:

username: "admin"

password: "123456"

application.yaml: |

server:

port: 8080

db.properties: |

datasource.username=root

datasource.password=123456

会生成 username、password、application.yaml、db.properties 这四个文件。

那么,如果我们希望普通的属性,像 username、password 注入到环境变量,而 application.yaml、db.properties 这种,生成文件,要怎么做呢?

apiVersion: v1

kind: Pod

metadata:

name: volumes-items-pod

spec:

restartPolicy: Never

volumes:

- name: volumes-name # 卷的名字

configMap:

name: my-config # ConfigMap 的名字

items:

- key: "application.yaml" # ConfigMap 的 key

path: "application.yaml" # key 映射成的文件

- key: "db.properties"

path: "db.properties"

containers:

- name: volumes-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["sleep", "3600"]

env:

- name: USERNAME # 定义容器中的环境变量

valueFrom:

configMapKeyRef:

name: my-config # ConfigMap 的名字

key: username # ConfigMap 中的 key

- name: PASSWORD

valueFrom:

configMapKeyRef:

name: my-config

key: password

volumeMounts:

- name: volumes-name

mountPath: /data/conf

通过 .volumes.configMap.items 选取需要做成卷的 ConfigMap key-value。

kubectl exec -it volumes-items-pod -c volumes-pod -- /bin/sh

/ # env

USERNAME=admin

PASSWORD=111111

5.7、名称空间限定

ConfigMap 是一种名称空间限定的资源。某一名称空间下的 Pod,只能引用同一名称空间下的 ConfigMap。

对于 4.2 的 ConfigMap,我们没有写,就是默认 default 名称空间下。现在我们 dev 名称空间下的一个 Pod:

apiVersion: v1

kind: Pod

metadata:

name: cmns-pod

namespace: dev

spec:

restartPolicy: Never

containers:

- name: cmns-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["sleep", "3600"]

env:

- name: USERNAME # 定义容器中的环境变量

valueFrom:

configMapKeyRef:

name: my-config # ConfigMap 的名字

key: username # ConfigMap 中的 key

- name: PASSWORD

valueFrom:

configMapKeyRef:

name: my-config

key: password

容器会报 CreateContainerConfigError 起不来。

5.8、多环境配置

ConfigMap 是名称空间限定的资源,所以在多名称空间环境下(比如 dev、prod),我们可以给每个名称空间创建同名的配置,然后在不同名称空间下的 Pod 引用这些配置。

# 创建名称空间

kubectl create ns dev

kubectl create ns prod

# 创建 ConfigMap

apiVersion: v1

kind: ConfigMap

metadata:

name: app-config

namespace: dev

data:

username: "dev"

password: "123456"

###

apiVersion: v1

kind: ConfigMap

metadata:

name: app-config

namespace: prod

data:

username: "prod"

password: "123456"

dev 下启动 Pod:

apiVersion: v1

kind: Pod

metadata:

name: cmns-pod

namespace: dev

spec:

restartPolicy: Never

containers:

- name: cmns-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["env"]

env:

- name: USERNAME # 定义容器中的环境变量

valueFrom:

configMapKeyRef:

name: app-config # ConfigMap 的名字

key: username # ConfigMap 中的 key

- name: PASSWORD

valueFrom:

configMapKeyRef:

name: app-config

key: password

prod 下启动 Pod:

apiVersion: v1

kind: Pod

metadata:

name: cmns-pod

namespace: prod

spec:

restartPolicy: Never

containers:

- name: cmns-pod

image: alpine:latest

imagePullPolicy: IfNotPresent

command: ["env"]

env:

- name: USERNAME # 定义容器中的环境变量

valueFrom:

configMapKeyRef:

name: app-config # ConfigMap 的名字

key: username # ConfigMap 中的 key

- name: PASSWORD

valueFrom:

configMapKeyRef:

name: app-config

key: password

六、Java 项目使用 ConfigMap 热加载配置

到此,我们知道了 ConfigMap 如果作为 Spring Boot 项目的配置的话,存在一些不足:

1、时效性不高。ConfigMap 可以作为配置文件挂载进容器文件系统,但是这中间会有一些延迟。而且,Spring Boot 项目在启动的时候加载了一次 application.yml 之类的配置文件后,就不会再加载了。这个时候 ConfigMap 再更新配置文件其实没什么意义。

2、时效性更好的环境变量的方式,ConfigMap 却无法更新。

所以,Spring Boot 项目需要自己监听 ConfigMap 变化,然后更新 Environment。

相关推荐

陌陌交友快聊在哪里 陌陌快聊怎么玩
365体育注册送365

陌陌交友快聊在哪里 陌陌快聊怎么玩

📅 07-06 👁️ 5397
小米电动助力自行车,甩掉共享单车几条街
365体育注册送365

小米电动助力自行车,甩掉共享单车几条街

📅 08-20 👁️ 5803
同是大众的销量王,速腾和朗逸,选哪个更好?