ConfigMap

一、概念

在K8S中,ConfigMap是一种用于存储配置数据的API对象,一般用于存储Pod中应用所需的一些配置信息,或者环境变量。将配置于 Pod 分开,避免应为修改配置导致还需要重新构建 镜像与容器。

二、创建

可以使用 kubectl create configmap -h 查看示例

2.1、基于目录创建
# configmap 可以简写成cm
kubectl create configmap <config名称> --from-file=./test
2.2、获取配置信息
# 查看有哪些configMap
kubectl get cm

# 具体查看某个configMap的内容
kubectl describe <config名称>
2.3、基于文件创建
# 后面可以是相对路径也可以是绝对路径
kubectl create cm <cm名称> --from-file=/data/k8s/configMap/test/appcation.yaml

# 重命名一个新的文件
kubectl create cm <cm名称> --from-file=<重命名一个文件名>=/data/k8s/configMap/test/appcation.yaml
2.4、基于键值对创建
kubectl create cm test-key-value-config --from-literal=username=root --from-literal=password=123456

三、使用配置

3.1、使用键值对配置
  • 创建一个pod的配置文件
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
3.2、挂在文件路径
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

subPath 的作用是允许在容器内部选择性的挂载Volume中的特定文件或者目录,而不是将整个Volume挂载到容器中。

4.1、准备工作,创建cm

configMap里 nginx-htmlnginx-config 提前创建好的, nginx-html 下有两个文件,一个是test.html和index.html ;nginx-config下面有一个文件,nginx.conf;

4.2、文件夹全覆盖,文件单覆盖
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文件

4.3、指定文件夹中某文件覆盖

只覆盖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'
4.4、总结

subPath一定要被volumeMounts中的mountPath包含,如果configMap下指定了items,下面的path一定要和volumeMounts下的subPath对应上

五、配置的热更新

在使用configMap挂载到pod后,有时需要修改配置,并且更新到 pod中。

而有些场景下是Pod是不会更新配置的:

  • 1、使用subPath
  • 2、变量的形式,如果 pod 中的一个变量是从 configmap 或 secret 中得到,同样也是不会更新的。

对于 subPath 的方式,我们可以取消 subPath 的使用,将配置文件挂载到一个不存在的目录,避免目录的覆盖,然后再利用软连接的形式,将该文件链接到目标位置

但是如果目标位置原本就有文件,可能无法创建软链接,此时可以基于前面讲过的 postStart 操作执行删除命令,将默认的文件删除即可

5.1、edit修改configMap
kubectl edit cm spring-boot-test-yaml
5.2、通过 replace 替换
# (--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