一、以文件的形式挂载ConfigMap

大部分情况下,ConfigMap定义的都是配置文件,而不是环境变量,因此需要将ConfigMap中的文件(一般为--from-file创建)挂载到Pod中,然后Pod中的容器就可以引用,此时可以通过Pod的volume字段进行挂载。

1.创建工作目录

[root@k8s-master01 ~]# mkdir -p configmap/conf

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/redis.conf
Password=123

3.重新创建一个redis的配置文件

[root@k8s-master01 conf]# kubectl create cm redis-conf --from-file=/root/configmap/conf/redis.conf 
configmap/redis.conf created

4.定义一个yaml文件

[root@k8s-master01 conf]# vim dp-cm.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
           name: redis-conf

注意:如果/etc/config/目录被多个进行挂载,就会被覆盖,挂载文件时需要注意这一点。

5.重新部署

[root@k8s-master01 conf]# kubectl replace -f dp-cm.yaml 
deployment.apps/dp-cm replaced

6.验证

[root@k8s-master01 conf]# kubectl get po
NAME                               READY   STATUS    RESTARTS        AGE
dp-cm-7d46cd48d4-c8tlh             1/1     Running   0               6m13s

7.以容器的方式进入Pod,观察到已成功挂载

[root@k8s-master01 conf]# kubectl exec -it dp-cm-7d46cd48d4-c8tlh -- sh      
/ # cat /etc/config/redis.conf 
Password=123

8.可以在线编辑名为redis-conf的cm,将password修改为456

[root@k8s-master01 conf]# kubectl edit cm redis-conf

apiVersion: v1
data:
  redis.conf: |
    Password=456
kind: ConfigMap
metadata:
  creationTimestamp: "2023-05-02T12:15:42Z"
  name: redis-conf
  namespace: default
  resourceVersion: "751275"
  uid: 76e180d6-b696-45b0-ae6a-4dcac8048c4a

9.查看是否修改成功,观察到,已经加载成功。默认每1分钟执行一次配置同步

[root@k8s-master01 conf]# kubectl exec -it dp-cm-7d46cd48d4-c8tlh -- sh
/ # cat /etc/config/redis.conf 
Password=456

4.4 自定义文件名挂载名称

很多情况下,需要更改挂载的文件名,可以使用path字段指定ConfigMap挂载的文件名。

1.创建工作目录

[root@k8s-master01 ~]# mkdir -p configmap/conf

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/redis.conf
Password=123

3.重新创建一个redis的配置文件

[root@k8s-master01 conf]# kubectl create cm redis-conf --from-file=/root/configmap/conf/redis.conf 
configmap/redis.conf created

4.查看key名,这里观察到为redis.conf

[root@k8s-master01 conf]# kubectl get cm redis-conf -oyaml
apiVersion: v1
data:
  redis.conf: |
    Password=456
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:19:26Z"
  name: redis-conf
  namespace: default
  resourceVersion: "33521"
  uid: acf5f51a-5cd8-413e-bf81-14a779b2f2fa

5.定义一个yaml文件,使用items重新配置key

[root@k8s-master01 conf]# vim dp-cm.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
           name: redis-conf
           items: 
             - key: redis.conf
               path: redis.conf.bak

6.重新部署

[root@k8s-master01 conf]# kubectl replace -f dp-cm.yaml 

7.验证,观察到名称已发生改变

[root@k8s-master01 conf]# kubectl get po 
NAME                               READY   STATUS    RESTARTS        AGE
dp-cm-d8574659d-ncmb5              1/1     Running   0               6s

[root@k8s-master01 conf]# kubectl exec -it dp-cm-d8574659d-ncmb5 -- sh
/# ls /etc/config/ -l
total 0
lrwxrwxrwx    1 root     root            21 May  2 12:47 redis.conf.bak -> ..data/redis.conf.bak

4.5 自定义挂载文件权限

ConfigMap在挂载使用时可以更改文件的权限(默认是0644),比如将上述的文件挂载权限自定义为0666(对应Linux的文件权限为rw-rw-rw-)。

1.查看key名,这里观察到为redis.conf

[root@k8s-master01 conf]# kubectl get cm redis-conf -oyaml
apiVersion: v1
data:
  redis.conf: |
    Password=456
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:19:26Z"
  name: redis-conf
  namespace: default
  resourceVersion: "33521"
  uid: acf5f51a-5cd8-413e-bf81-14a779b2f2fa

2.定义一个yaml文件,这里0666是八进制写法

[root@k8s-master01 conf]# vim dp-cm.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
          name: redis-conf
          items: 
            - key: redis.conf
              path: redis.conf.bak
          defaultMode: 0666

上面的配置文件是通过defaultMode来自定义挂载文件权限,也可以通过mode来实现相同的目的。且mode的优先级高于defaultMode

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
          name: redis-conf
          items: 
            - key: redis.conf
              path: redis.conf.bak
              mode: 0666

3.重新部署

[root@k8s-master01 conf]# kubectl replace -f dp-cm.yaml 

4.验证,观察到实际权限为666

[root@k8s-master01 conf]# kubectl get po 
NAME                               READY   STATUS    RESTARTS        AGE
dp-cm-6fdff654c5-fbw75             1/1     Running   0               5s

[root@k8s-master01 conf]# kubectl exec -it dp-cm-6fdff654c5-fbw75 -- sh
#软链接权限
/# ls /etc/config/redis.conf.bak -l
lrwxrwxrwx 1 root root 21 Dec  3 11:35 /etc/config/redis.conf.bak -> ..data/redis.conf.bak
root@dp-cm-6fdff654c5-fbw75:/# cd /etc/config/..data/
#实际权限
root@dp-cm-6fdff654c5-fbw75:/etc/config/..data# ls -l
total 4
-rw-rw-rw- 1 root root 13 Dec  3 11:35 redis.conf.bak

4.6 注意事项-Option字段

注意:默认情况下,如果指定的Key名不存在,Pod会一直处于ContainerCreating。可以添加optional 字段,把 key 必须存在改为非必须

1.创建工作目录

[root@k8s-master01 ~]# mkdir -p configmap/conf

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/redis.conf
Password=123

3.重新创建一个redis的配置文件

[root@k8s-master01 conf]# kubectl create cm redis-conf --from-file=/root/configmap/conf/redis.conf 

4.查看key名,这里观察到为redis.conf

[root@k8s-master01 conf]# kubectl get cm redis-conf -oyaml
apiVersion: v1
data:
  redis.conf: |
    Password=456
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:19:26Z"
  name: redis-conf
  namespace: default
  resourceVersion: "33521"
  uid: acf5f51a-5cd8-413e-bf81-14a779b2f2fa

5.定义一个yaml文件,使用items重新配置key,这里模拟key是不存在的

[root@k8s-master01 conf]# vim dp-cm.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
           name: redis-conf
           items: 
             - key: redis.conf.wrong  # 故意使用错误的 Key 
               path: redis.conf.bak   # 目标文件名

6.重新部署

[root@k8s-master01 conf]# kaf dp-cm.yaml 

7.验证,观察到pod

[root@k8s-master01 ~]# kgp
NAME                     READY   STATUS              RESTARTS   AGE
dp-cm-5c8bd5d58d-894hn   0/1     ContainerCreating   0          48s

8.查看pod一直处于处于创建的原因,观察到key配置错误

[root@k8s-master01 ~]# kd po dp-cm-5c8bd5d58d-894hn
...
...
Events:
  Type     Reason       Age                From               Message
  ----     ------       ----               ----               -------
  Normal   Scheduled    84s                default-scheduler  Successfully assigned default/dp-cm-5c8bd5d58d-894hn to k8s-node02
  Warning  FailedMount  20s (x8 over 83s)  kubelet            MountVolume.SetUp failed for volume "redisconf" : configmap references non-existent config key: redis.conf.wrong

9.添加Option字段

主要添加如下内容信息:

...
...
           optional: true
...
...

添加后的内容如下:

[root@k8s-master01 ~]# cat dp-cm.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: redisconf
           mountPath: /etc/config
      volumes: 
       - name: redisconf
         configMap:
           name: redis-conf
           items: 
             - key: redis.conf.wrong  # 故意使用错误的 Key 名
               path: redis.conf.bak   # 目标文件名
           optional: true

重新应用

[root@k8s-master01 ~]# kaf dp-cm.yaml 

查看pod状态

[root@k8s-master01 ~]# kgp
NAME                     READY   STATUS    RESTARTS   AGE
dp-cm-5d5448f477-ks7dh   1/1     Running   0          6s