在K8S中,ConfigMap是一种用于存储配置数据的API对象,一般用于存储Pod中应用所需的一些配置信息,或者环境变量。将配置于 Pod 分开,避免应为修改配置导致还需要重新构建 镜像与容器。
可以使用 kubectl create configmap -h 查看示例
# configmap 可以简写成cm
kubectl create configmap <config名称> --from-file=./test
# 查看有哪些configMap
kubectl get cm
# 具体查看某个configMap的内容
kubectl describe <config名称>
# 后面可以是相对路径也可以是绝对路径
kubectl create cm <cm名称> --from-file=/data/k8s/configMap/test/appcation.yaml
# 重命名一个新的文件
kubectl create cm <cm名称> --from-file=<重命名一个文件名>=/data/k8s/configMap/test/appcation.yaml
kubectl create cm test-key-value-config --from-literal=username=root --from-literal=password=123456
apiVersion: v1
kind: Pod
metadata:
name: test-keyvalue-cm-po
spec:
containers:
- name: env-root
image: alpine
command: ["/bin/sh", "-c" , "env;sleep 3600"] # 打印环境变量
imagePullPolicy: IfNotPresent
env:
- name: name
valueFrom:
configMapKeyRef:
name: test-key-value-config #configMap的名称
key: username #指定的那个config中key为username的
- name: password
valueFrom:
configMapKeyRef:
name: test-key-value-config
key: password
restartPolicy: Never
kubectl logs -f test-keyvalue-cm-po
apiVersion: v1
kind: Pod
metadata:
name: test-files-cm-po
spec:
containers:
- name: env-root
image: alpine
command: ["/bin/sh", "-c" , "env;sleep 3600"]
imagePullPolicy: IfNotPresent
volumeMounts: # 加载数据卷
- name: redis-config
mountPath: "/usr/local/redis"
restartPolicy: Never
volumes:
- name: redis-config #数据卷的名称
configMap:
name: test-dir-config #configMap中的名称
items: #加载test-dir-config中的其中某些项,不指定就是全部
- key: 'redis.config' # configMap中的key
path: 'redis.conf' # 子路径地址,可以将key转化为文件
subPath
的作用是允许在容器内部选择性的挂载Volume中的特定文件或者目录,而不是将整个Volume挂载到容器中。
configMap里 nginx-html
和 nginx-config
提前创建好的, nginx-html
下有两个文件,一个是test.html和index.html ;nginx-config
下面有一个文件,nginx.conf;
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
- name: conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: html
configMap:
name: nginx-html
items:
- key: 'index.html'
path: 'index.html'
- name: conf
configMap:
name: nginx-config
将整个html文件覆盖到nginx的容器里,nginx.conf只覆盖容器中的nginx.conf文件, 如果conf
没加上subPath
的话,容器中/etc/nginx/
就会只剩下nginx.conf
文件
只覆盖html文件夹中index.html到容器中的index.html
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/index.html
subPath: index.html #需要和items[0].path值对应上, 且要被mountPath包含
volumes:
- name: html
configMap:
name: nginx-html
items:
- key: 'index.html'
path: 'index.html'
subPath一定要被volumeMounts中的mountPath包含,如果configMap下指定了items,下面的path一定要和volumeMounts下的subPath对应上
在使用configMap挂载到pod后,有时需要修改配置,并且更新到 pod中。
而有些场景下是Pod是不会更新配置的:
1、使用subPath
2、变量的形式,如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的。
对于 subPath 的方式,我们可以取消 subPath 的使用,将配置文件挂载到一个不存在的目录,避免目录的覆盖,然后再利用软连接的形式,将该文件链接到目标位置
但是如果目标位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除命令,将默认的文件删除即可
kubectl edit cm spring-boot-test-yaml
# (--dry-run=client -o yaml | kubectl replace -f -) 是固定格式
kubectl create cm <cm名称> --from-file=./test --dry-run=client -o yaml | kubectl replace -f -
–dry-run 参数,该参数的意思打印 yaml 文件,但不会将该文件发送给 apiserver,再结合 -oyaml 输出 yaml 文件就可以得到一个配置好但是没有发给 apiserver 的文件,然后再结合 replace 监听控制台输出得到 yaml 数据即可实现替换
kubectl create cm --from-file=nginx.conf --dry-run -oyaml | kubectl replace -f-
遇到禁止配置文件修改,可以直接修改cm的信息,添加immutable: true
即可,例如
apiVersion: v1
data:
appcation.yaml: |
...配置文件信息
kind: ConfigMap
metadata:
creationTimestamp: "2023-10-18T13:16:22Z"
name: spring-boot-test-yaml
namespace: default
resourceVersion: "558771"
uid: ba7d135f-7aff-4005-8360-5eba74bc7d31
# 加上这列
immutable: true
加上immutable: true
后,当再次修改这个配置文件时,就会提示报错
# * data: Forbidden: field is immutable when `immutable` is set