1. 什么是ConfigMap
ConfigMap在kubernetes中是一个抽象概念,将配置与Pod和组件分开,这有助于保持工作负载的可移植性,使配置更易于更改和管理。
对于不同的环境,根据需要配置不同的ConfigMap挂载到容器中,而不用对代码频繁的修改。
ConfigMap更倾向于存储和共享非敏感、未加密的配置信息,假如在集群中使用敏感信息,最好使用Secret。
2. 创建ConfigMap
ConfigMap可以用目录(目录下有多个文件)、单个文件或字符值的方式创建。
kubectl create configmap <map-name> <data-source>
map-name:ConfigMap的名称。
data-source:数据源,可以是数据目录、文件或字符值。
ConfigMap中的数据是以键-值对(key-value pair)的形式保存的,其中:
key:文件名或密钥。
value:文件内容或字符值。
1. 基于目录创建ConfigMap
假如一次性需要多个文件来创建ConfigMap,可以使用命令从同一个目录中的多个文件创建ConfigMap。
kubectl create configmap game-config --from-file=conf
game-config为ConfigMap的名称,--from-file为需要指定的目录。
# cat ./conf/game.properties
key1=value1
key2=value2
# cat ./conf/ui.properties
hello1=hi1
hell02=hi2
# kubectl get cm game-config -oyaml
apiVersion: v1
data:
game.properties: |
key1=value1
key2=value2
ui.properties: |
hello1=hi1
hell02=hi2
kind: ConfigMap
metadata:
name: game-config
namespace: default
说明:由于没有指定ConfigMap的Key名,因此默认是按照目录下的文件名作为ConfigMap数据中的Key名。
同时,ConfigMap是按照Namespace隔离的,不同的Namespace之间ConfigMap名称可以相同,但是不能跨Namespace进行访问。默认是在default命名空间下。
2. 基于文件创建ConfigMap
# kubectl create cm game-config-2 --from-file=conf/game.properties
configmap/game-config-2 created
# kubectl get cm game-config-2 -oyaml
apiVersion: v1
data:
game.properties: |
key1=value1
key2=value2
kind: ConfigMap
metadata:
name: game-config-2
namespace: default
如果需要单独设置Key名,可以使用以下方法:
# kubectl create cm game-config-3 --from-file=my-key=conf/game.properties
configmap/game-config-3 created
# kubectl get cm game-config-3 -oyaml
apiVersion: v1
data:
my-key: |
key1=value1
key2=value2
kind: ConfigMap
metadata:
name: game-config-3
namespace: default
可以使用--from-file多次传入参数以从多个数据源创建ConfigMap,此方法和基于文件夹类似,只不过可以单独设置ConfigMap的Key名:
# kubectl create cm game-config-4 --from-file=conf/game.properties --from-file=conf/ui.properties
configmap/game-config-4 created
# kubectl get cm game-config-4 -oyaml
apiVersion: v1
data:
game.properties: |
key1=value1
key2=value2
ui.properties: |
hello1=hi1
hell02=hi2
kind: ConfigMap
metadata:
name: game-config-4
namespace: default
3. 基于ENV文件创建ConfigMap
# cat ./conf/game-env-file.properties
enemies=alines
lives=3
allowed="true"
# kubectl create cm game-config-env --from-env-file=conf/game-env-file.properties
configmap/game-config-env created
# kubectl get cm game-config-env -o yaml
apiVersion: v1
data:
allowed: '"true"'
enemies: alines
lives: "3"
kind: ConfigMap
metadata:
name: game-config-env
namespace: default
说明:此时ConfigMap的data内容已经变成了key冒号(:)的形式,而不是之间和文件内容一样的数据。
需要注意的是,如果多次传入参数从多个数据源创建ConfigMap,仅最后一个生效。
4. 基于字符集创建ConfigMap
如果只有几个简单的key=value的参数,可以直接使用命令创建。
# kubectl create cm special-config --from-literal=special.how=very --from-literal=special.type=charm
configmap/special-config created
# kubectl get cm special-config -oyaml
apiVersion: v1
data:
special.how: very
special.type: charm
kind: ConfigMap
metadata:
name: special-config
namespace: default
3. ConfigMap实践
1. 使用valueFrom定义容器环境变量:
首先使用--from-literal或--from-env-file创建key=value形式的ConfigMap。
# kubectl create cm special-configmap --from-literal=special.how=very --from-literal=special.level=info
configmap/special-config created
然后将ConfigMap中定义的值special.how分配给Deployment(其他资源也可以)中的一个Pod当做环境变量,并命名为SPECIAL_LEVEL_KEY。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap # Deployment的名称;
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- env:
- name: TZ
value: Asia/Shanghai
- name: LANG
value: C.UTF-8
- name: SPECIAL_LEVEL_KEY # 环境变量的名称
valueFrom: # 注意valueFrom的位置
configMapKeyRef:
key: special.how # 需要引入的key
name: special-configmap # ConfigMap名称
- name: MULTIPLE_CM # 环境变量的名称
valueFrom: # 注意valueFrom的位置
configMapKeyRef:
key: special.level # 需要引入的key
name: special-configmap # ConfigMap名称
name: nginx
image: registry.cn-beijing.aliyuncs.com/jiangxiaonan/nginx:1.22.1
ports:
- containerPort: 80
# kubectl exec -it nginx-configmap-5c6f54cc7d-bv9hr -c nginx -- /bin/bash
root@nginx-configmap-5c6f54cc7d-bv9hr:/# env | grep SPECIAL_LEVEL_KEY
SPECIAL_LEVEL_KEY=very
root@nginx-configmap-5c6f54cc7d-bv9hr:/# env | grep MULTIPLE_CM
MULTIPLE_CM=info
root@nginx-configmap-5c6f54cc7d-bv9hr:/#
2. 基于envFrom定义容器的环境变量
valueFrom通常用于使用ConfigMap的单个Key设置环境变量,但实际使用时更常用的是把ConfigMap里面所有的数据作为环境变量,此时需要使用到envFrom。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap-envfrom # Deployment的名称;
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- env:
- name: TZ
value: Asia/Shanghai
- name: LANG
value: C.UTF-8
envFrom: # 注意envFrom的位置
- configMapRef:
name: game-config-env # ConfigMap名称
prefix: feomCm_ # 将ConfigMap中的key添加一个前缀,是一个可选参数
name: nginx
image: registry.cn-beijing.aliyuncs.com/jiangxiaonan/nginx:1.22.1
ports:
- containerPort: 80
# kubectl exec -it nginx-configmap-envfrom-5476bb5c7f-fxsc9 -c nginx -- /bin/bash
root@nginx-configmap-envfrom-5476bb5c7f-fxsc9:/# env | grep allowed
feomCm_allowed="true"
root@nginx-configmap-envfrom-5476bb5c7f-fxsc9:/# env | grep enemies
feomCm_enemies=alines
root@nginx-configmap-envfrom-5476bb5c7f-fxsc9:/# env | grep lives
feomCm_lives=3
需要注意的是,ConfigMap不能支持热更新,如果修改了ConfigMap,需要重启pod才能生效。
valueFrom是通过选择单个值的形式设置环境变量,而evnFrom是将整个文件的内容作为环境变量。envFrom的效率更高。
3. 以文件形式挂载ConfigMap
大部分情况下,ConfigMap定义的是配置文件,而不是环境变量,因此需要将ConfigMap中的文件(一般为--from-file创建)挂载到Pod中,然后在容器中引用进行使用。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap-envfrom # Deployment的名称;
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-beijing.aliyuncs.com/jiangxiaonan/nginx:1.22.1
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: game-config-2
# kubectl exec -it nginx-configmap-map-86db6d8d8c-56h5q -c nginx -- /bin/bash
root@nginx-configmap-map-86db6d8d8c-56h5q:/# cd /etc/config
root@nginx-configmap-map-86db6d8d8c-56h5q:/etc/config# ls
game.properties
root@nginx-configmap-map-86db6d8d8c-56h5q:/etc/config# cat game.properties
key1=value1
key2=value2
4. 自动以文件名挂载ConfigMap并设置权限
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap-file1 # Deployment的名称;
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-beijing.aliyuncs.com/jiangxiaonan/nginx:1.22.1
ports:
- containerPort: 80
volumeMounts:
- name: game
mountPath: /etc/config-1/game-me.properties # 这里是挂载文件路径,可以重命名文件
subPath: game.properties
- name: ui
mountPath: /etc/config-2/ui-me.properties # 这里是挂载文件路径,可以重命名文件
subPath: ui.properties
volumes:
- name: game
configMap:
name: game-config-4 # ConfigMap名称
defaultMode: 420 # 设置权限
- name: ui
configMap:
name: game-config-4 # ConfigMap名称
defaultMode: 493 # 设置权限
[root@k8s-master01 config]# kubectl exec -it nginx-configmap-file1-b445ffc4f-7hnnb -c nginx -- /bin/bash
root@nginx-configmap-file1-b445ffc4f-7hnnb:/# cd /etc/config-1
root@nginx-configmap-file1-b445ffc4f-7hnnb:/etc/config-1# ls -l
total 4
-rw-r--r-- 1 root root 24 Dec 3 11:42 game-me.properties
root@nginx-configmap-file1-b445ffc4f-7hnnb:/etc/config-1# cat game-me.properties
key1=value1
key2=value2
root@nginx-configmap-file1-b445ffc4f-7hnnb:/etc/config-1# cd /etc/config-2
root@nginx-configmap-file1-b445ffc4f-7hnnb:/etc/config-2# ls -l
total 4
-rwxr-xr-x 1 root root 22 Dec 3 11:42 ui-me.properties
本来ConfigMap中有多个文件,通过这种方式可以灵活的选择文件并挂载到不同的路径。
subPath主要用于将同一个Volume的数据挂载到不同的路径,同时也能用subPath的功能解决挂载覆盖的问题。
说明,Linux中文件权限为八进制,420对应644,493对应755,511对应777。