一、ConfigMap实践概览

可以通过单个ConfigMap定义环境变量,也通过多个ConfigMap定义环境变量和将ConfigMap作为卷挂载成文件使用等。valueFrom通常用于使用ConfigMap的单个Key设置环境变量,但实际使用时更常用的是把ConfigMap里面所有的数据都作为环境变量,此时可以使用envFrom参数。

二、使用valueFrom定义单个环境变量

1.创建工作目录

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

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/game.conf
lives=3
secret.code=true

3.创建ConfigMap

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

4.验证

[root@k8s-master01 conf]# kubectl get cm
NAME               DATA   AGE
cmfromdir          2      25m
cmfromfile         1      20m
cmspecialname      1      10m
cmspecialname2     2      7m51s
gameenvcm          2      11s
kube-root-ca.crt   1      26h

[root@k8s-master01 conf]# kubectl get cm gameenvcm -oyaml
apiVersion: v1
data:
  lives: "3"
  secret.code: "true"
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:39:30Z"
  name: gameenvcm
  namespace: default
  resourceVersion: "36100"
  uid: 62346419-855c-48de-8f78-9b17bb5da665

[root@k8s-master01 ~]# kubectl describe cm gameenvcm
Name:         gameenvcm
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
lives:
----
3
secret.code:
----
true

BinaryData
====

Events:  <none>

5.编写一个deployment的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
        env:
        - name: TEST_ENV
          value: testenv
        - name: LIVES
          valueFrom:
            configMapKeyRef:
              name: gameenvcm
              key: lives

上面内容分析

    env:
    #手动创建
    - name: TEST_ENV
      value: testenv
    #基于valueFrom单个定义环境变量
    - name: LIVES
      valueFrom:
        configMapKeyRef:
          name: gameenvcm
          key: lives

6.创建一个deployment

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

注意:创建的deployment要和configMap位于同一命名空间,且名为gameenvcm的configMap要真实存在,否则Pod起不来

7.验证

[root@k8s-master01 conf]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
dp-cm              1/1     1            1           27s

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

8.查看env

[root@k8s-master01 conf]# kubectl exec dp-cm-6d84dc5fcb-vzrfw -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-6d84dc5fcb-vzrfw
NGINX_VERSION=1.14.2
NJS_VERSION=0.5.0
PKG_RELEASE=1~buster
TEST_ENV=testenv
LIVES=3
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
NGINX_PORT=tcp://10.0.239.136:80
NGINX_PORT_80_TCP_PORT=80
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
NGINX_SERVICE_HOST=10.0.239.136
NGINX_PORT_80_TCP=tcp://10.0.239.136:80
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
NGINX_SERVICE_PORT=80
NGINX_PORT_80_TCP_PROTO=tcp
NGINX_PORT_80_TCP_ADDR=10.0.239.136
HOME=/root

三、使用envFrom定义多个环境变量

1.创建工作目录

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

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/game.conf
lives=3
secret.code=true

3.创建ConfigMap

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

4.验证

[root@k8s-master01 conf]# kubectl get cm
NAME               DATA   AGE
cmfromdir          2      25m
cmfromfile         1      20m
cmspecialname      1      10m
cmspecialname2     2      7m51s
gameenvcm          2      11s
kube-root-ca.crt   1      26h

[root@k8s-master01 conf]# kubectl get cm gameenvcm -oyaml
apiVersion: v1
data:
  lives: "3"
  secret.code: "true"
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:39:30Z"
  name: gameenvcm
  namespace: default
  resourceVersion: "36100"
  uid: 62346419-855c-48de-8f78-9b17bb5da665

[root@k8s-master01 ~]# kubectl describe cm gameenvcm
Name:         gameenvcm
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
lives:
----
3
secret.code:
----
true

BinaryData
====

Events:  <none>

5.编写一个deployment的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
        envFrom:
        - configMapRef:
           name: gameenvcm
          prefix: fromCm_
        env:
        - name: TEST_ENV
          value: testenv

上面内容分析

        #使用envFrom定义名为gameenvcm的configmap的全部环境变量并在键前面添加前缀fromCm_
        envFrom:
        - configMapRef:
           name: gameenvcm
          prefix: fromCm_
        #手动创建
        env:
        - name: TEST_ENV
          value: testenv

6.创建一个deployment

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

注意:创建的deployment要和configMap位于同一命名空间,且名为gameenvcm的configMap要真实存在,否则Pod起不来

7.验证

[root@k8s-master01 conf]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
dp-cm              1/1     1            1           27s

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

8.查看env

[root@k8s-master01 conf]# kubectl exec dp-cm-6f94dbf6f6-xb2jn  -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=dp-cm-6f94dbf6f6-xb2jn
NGINX_VERSION=1.14.2
fromCm_secret.code=true
fromCm_lives=3
TEST_ENV=testenv
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
HOME=/root

注意:使用envFrom时,环境变量的名字是ConfigMap中数据的key名。prefix参数是将ConfigMap中的key添加一个前缀,比如key名是self-key,加了prefix就是fromCm_self-key,prefix为可选参数。另外需要注意,当使用ConfigMap或者Secret定义Pod变量时,如果ConfigMap和Secret内容有变化,而Pod没有重启的话,Pod里面的变量就不会更新。

四、以文件的形式挂载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

五、自定义文件名挂载名称

很多情况下,需要更改挂载的文件名,可以使用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文件

[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