• 【原创】Kuberneters-ConfigMap的实践


    一、什么是ConfigMap

           ConfigMap翻译过来即为“配置字典”,在实际的生产环境中,应用程序配置经常需要且又较为复杂,参数、config文件、变量等如果直接打包到镜像中,将会降低镜像的可移植性,因此期望有一种方式可以将配置从应用程序中解耦出来,ConfigMap正是在此背景下诞生的,它用于保存配置数据的键值(key-value)对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap 跟 secret 很类似,但它可以更方便地处理不包含敏感信息的字符串。

    二、适用场景?

         适用于存储不包含敏感信息的变量、属性或文件。

         比如在一个集群中,可将应用程序所需的参数、变量、配置文件存放到ConfigMap中,在开发、测试和生产环境将同1个ConfigMap(前提是同1个namespace)挂载到Pod中,这样既可以实现配置和容器镜像的分离,也可方便的实现统一管理,比如可以利用其热更新的机制,修改完成后会同步到挂载了此ConfigMap的所有Pod中。

    三、ConfigMap的创建

    1、文件目录创建

    支持以目录的方式创建ConfigMap,其中文件名将作为key,文件内容作为value,有几个文件将会存在几个键值对,如下图,先创建1个目录,此目录下存在两个文件

    [root@k8s-master confdirtest]# ls
    conftest1.txt  conftest.txt
    [root@k8s-master consecret]# kubectl create configmap con-dir-test --from-file=confdirtest/
    configmap/con-dir-test created

    其格式为kubectl creat configmap "configmap的名字" --from-file="目录"/,这种适用于将某个目录下的所有文件作为key,文件内容作为value进行创建。

    [root@k8s-master consecret]# kubectl get cm | grep con-dir-test
    con-dir-test          2      20s
    [root@k8s-master consecret]# kubectl describe cm con-dir-test 
    Name:         con-dir-test
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    conftest.txt:
    ----
    name=this is test                #文件conftest.txt的内容
    
    conftest1.txt:
    ----
    name=this is test1               #文件conftest1.txt的内容
    
    Events:  <none>

    2、文件方式创建

         --from-file的方式除了用于目录的方式之外,同样还适用于指定文件的方式进行创建,其中文件名称将作为key名称,文件内容作为value,如下所示,先建立一个配置文件testconf.cfg

    [root@k8s-master consecret]# cat testconf.cfg 
    listenport=8080
    name=testconf
    serverip=10.0.0.1

    接下里将其生成1个configmap文件,如下所示,其格式为:kubectl create configmap "configmap名称" --from-file=“文件名”

    [root@k8s-master consecret]# kubectl create configmap conf-file-test --from-file=testconf.cfg 
    configmap/conf-file-test created
    [root@k8s-master consecret]# kubectl describe cm conf-file-test 
    Name:         conf-file-test
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    testconf.cfg:
    ----
    listenport=8080
    name=testconf
    serverip=10.0.0.1
    
    Events:  <none>

    此方式适用于将某个或多个配置文件生成同一个configmap文件的场景

    3、直接创建key-value 

     可直接指定需要data的key-value键值对进行创建,如下所示,使用"--from-literal"选项可在命令行直接创建configmap对象,若是创建多个,可重复多次进行创建,但是注意其key的名称不可重复,这种方式适用于直接指定key-value的方式进行创建。

    [root@k8s-master consecret]# kubectl create configmap con-key-value --from-literal=key1=name1
    configmap/con-key-value created
    [root@k8s-master consecret]# kubectl describe cm con-key-value 
    Name:         con-key-value
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    key1:
    ----
    name1
    Events:  <none>
    [root@k8s-master consecret]# kubectl create configmap con-key-value-test --from-literal=class.1=202 --from-literal=class.2=502
    configmap/con-key-value-test created
    [root@k8s-master consecret]# kubectl describe cm con-key-value-test 
    Name:         con-key-value-test
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    class.1:
    ----
    202
    class.2:
    ----
    502
    Events:  <none>

    4、导入环境变量创建

     可将环境变量以--from-env-file的方式进行创建,其格式为:kubectl crete configmap "configmap的名称" --from-env=file=环境变量文件.env

    [root@k8s-master consecret]# echo -e "testenv1=1	estenv2=2" | tee configtest.env
    testenv1=1    estenv2=2
    [root@k8s-master consecret]# kubectl create configmap conf-env-test --from-env-file=configtest.env 
    configmap/conf-env-test created
    [root@k8s-master consecret]# kubectl describe cm conf-env-test
    Name:         conf-env-test
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    testenv1:
    ----
    1        estenv2=2
    Events:  <none>

    四、ConfigMap的使用

    1、热更新(目录形式挂载)

    首先先成功创建一个ConfigMap

    [root@k8s-master consecret]# cat conf-delete-test.yaml 
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: zltest-conf-delete
      namespace: default
    data:
      zltest.show: delete-test
    [root@k8s-master consecret]# kubectl delete deployment dep-deleye-conf-test 
    deployment.apps "dep-deleye-conf-test" deleted
    [root@k8s-master consecret]# kubectl create -f conf-delete-test.yaml 
    configmap/zltest-conf-delete created
    [root@k8s-master consecret]# kubectl get cm | grep zltest-conf-delete
    zltest-conf-delete    1      44s

    将其以卷目录形式挂载到Pod容器中,创建一个deployment

    [root@k8s-master zhanglei]# cat dep-delete-con.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dep-deleye-conf-test
      namespace: default
      labels:
        app: nginx-delete-conf-test
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx-deployment-delete
      template:
        metadata:
          labels:
            app: nginx-deployment-delete
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - name: testconf
              containerPort: 80
            volumeMounts:
            - name: nginxconf
              mountPath: /data/deletetest
          volumes:
          - name: nginxconf  
            configMap:
              name: zltest-conf-delete
    [root@k8s-master zhanglei]# kubectl create -f dep-delete-con.yaml 
    deployment.apps/dep-deleye-conf-test created
    [root@k8s-master zhanglei]# kubectl get deployment |grep dep-deleye-conf-test
    dep-deleye-conf-test   2/2     2            2           56s

    执行以上的步骤后,名为zltest-conf-delete的ConfigMap已被成功挂载到Pod的容器中,如果在运行的过程中,修改下ConfigMap的文件,会出现怎样的情况呢?先edit下ConfigMap,增加一个键值对

    [root@k8s-master zhanglei]# kubectl describe cm zltest-conf-delete 
    Name:         zltest-conf-delete
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    zltest.show:
    ----
    delete-test
    Events:  <none>
    [root@k8s-master consecret]# kubectl edit cm zltest-conf-delete 
    
    # Please edit the object below. Lines beginning with a '#' will be ignored,
    # and an empty file will abort the edit. If an error occurs while saving this file will be
    # reopened with the relevant failures.
    #
    apiVersion: v1
    data:
      zltest.show: delete-test
      addkey: addvalue                      # 新增的键值对
    kind: ConfigMap
    metadata:
      creationTimestamp: "2020-07-23T11:29:11Z"
      managedFields:
      - apiVersion: v1
        fieldsType: FieldsV1
        fieldsV1:
          f:data:
            .: {}
            f:zltest.show: {}
        manager: kubectl
        operation: Update
        time: "2020-07-23T11:29:11Z"
      name: zltest-conf-delete
      namespace: default

    [root@k8s-master consecret]# kubectl edit cm zltest-conf-delete
    configmap/zltest-conf-delete edited

    验证下新增的键值对是否会同步热更新到Pod的容器中,通过exec的方式登录到容器中进行查看,新添加的键值对以同步更新到Pod的容器中,

    不需要以容器进行额外的操作,这是卷目录的形式挂载的热更新,但是若是通过环境变量env或者通过文件的形式挂载到容器中,是不会支持热更新的,这里需要注意下。

    [root@k8s-master consecret]# kubectl exec -it dep-deleye-conf-test-869747b77f-67w9h -- bash
    root@dep-deleye-conf-test-869747b77f-67w9h:/# cd data
    root@dep-deleye-conf-test-869747b77f-67w9h:/data# ls
    deletetest
    root@dep-deleye-conf-test-869747b77f-67w9h:/data# cd deletetest/
    root@dep-deleye-conf-test-869747b77f-67w9h:/data/deletetest# ls
    addkey    zltest.show

    如果删除已将挂载到Pod中的容器的ConfigMap会出现怎样的情况呢,先删除ConfigMap,然后再次登录到容器中进行验证

    [root@k8s-master consecret]# kubectl delete cm zltest-conf-delete 
    configmap "zltest-conf-delete" deleted
    [root@k8s-master consecret]# kubectl exec -it dep-deleye-conf-test-869747b77f-67w9h -- bash
    root@dep-deleye-conf-test-869747b77f-67w9h:/data/deletetest# ls
    addkey    zltest.show

    若未对Pod进行删除的操作,删除ConfigMap成功,但是挂载到容器的目录依然会存在,并不会一起被删除,此时若删除Pod,副本控制器会重新拉

    起1个Pod,会创建成功吗?接下来验证下

    [root@k8s-master consecret]# kubectl get pod | grep dep-deleye-conf-test
    dep-deleye-conf-test-869747b77f-kgzqt   1/1     Running             0          134m
    dep-deleye-conf-test-869747b77f-mf6vc   0/1     ContainerCreating   0          2m13s

    重新拉起Pod一直会是ContainerCreating状态,详细查看下原因

    [root@k8s-master consecret]# kubectl describe pod dep-deleye-conf-test-869747b77f-mf6vc
    Name:           dep-deleye-conf-test-869747b77f-mf6vc
    Namespace:      default
    Priority:       0
    Node:           k8s-master/192.168.126.129
    Start Time:     Thu, 23 Jul 2020 21:47:00 +0800
    Labels:         app=nginx-deployment-delete
                    pod-template-hash=869747b77f
    Annotations:    <none>
    Status:         Pending
    IP:             
    IPs:            <none>
    Controlled By:  ReplicaSet/dep-deleye-conf-test-869747b77f
    Containers:
      nginx:
        Container ID:   
        Image:          nginx:latest
        Image ID:       
        Port:           80/TCP
        Host Port:      0/TCP
        State:          Waiting
          Reason:       ContainerCreating
        Ready:          False
        Restart Count:  0
        Environment:    <none>
        Mounts:
          /data/deletetest from nginxconf (rw)
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-74s86 (ro)
    Conditions:
      Type              Status
      Initialized       True 
      Ready             False 
      ContainersReady   False 
      PodScheduled      True 
    Volumes:
      nginxconf:
        Type:      ConfigMap (a volume populated by a ConfigMap)
        Name:      zltest-conf-delete
        Optional:  false
      default-token-74s86:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-74s86
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  <none>
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
    Events:
      Type     Reason       Age                From                 Message
      ----     ------       ----               ----                 -------
      Normal   Scheduled    <unknown>          default-scheduler    Successfully assigned default/dep-deleye-conf-test-869747b77f-mf6vc to k8s-master
      Warning  FailedMount  11s (x8 over 75s)  kubelet, k8s-master  MountVolume.SetUp failed for volume "nginxconf" : configmap "zltest-conf-delete" not found

    可以看到是FailedMount,volume异常了,K8S中删除的时候是不会判断这个依赖关系的,因此在生产的实际使用中,这点还是需要注意。

    2、通过环境变量引入

        除了通过volume的方式挂载到容器中使用之外,还可将configmap作为环境变量的方式引入到容器中,这里以con-key-value-test作为例子

    [root@k8s-master consecret]# kubectl get cm |grep con-key-value-test
    con-key-value-test    2      34m
    [root@k8s-master zhanglei]# cat dep-conf-test.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-conf-env-test
      namespace: default
      labels:
        app: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx-deployment
      template:
        metadata:
          labels:
            app: nginx-deployment
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            #  command: [ "/bin/bash","-c","env" ]
            ports:
            - containerPort: 80
            env:
            - name: test-env1-conf                        # 环境变量名称1
              valueFrom:
                configMapKeyRef:
                  name: con-key-value-test 
                  key: class.1                            # 指定key名称即可
            - name: test-env2-conf                        # 环境变量名称2
              valueFrom:
                configMapKeyRef:
                  name: con-key-value-test                # 引入configmap
                  key: class.2
    [root@k8s-master zhanglei]# kubectl create -f dep-conf-test.yaml 
    deployment.apps/nginx-conf-env-test created
    [root@k8s-master zhanglei]# kubectl get pod |grep env-test
    nginx-conf-env-test-56f5c9b88-xt86x        1/1     Running            0          34s

     可以看到Pod处于running的状态,登入到容器验证下以存在环境变量,如下所示,验证成功,值得注意的是,这种方式相当于新生成的环境变量指向configmap中的key所对应的value

    root@nginx-conf-env-test-56f5c9b88-xt86x:/# ls
    bin   docker-entrypoint.d   home   media  proc    sbin  tmp
    boot  docker-entrypoint.sh  lib    mnt      root    srv   usr
    dev   etc            lib64  opt      run    sys   var
    root@nginx-conf-env-test-56f5c9b88-xt86x:/# env
    test-env2-conf=502                   # 环境变量=原class.1的value
    test-env1-conf=202

    五、总结

     configmap是K8s中重要的配置管理方式,本文介绍了configmap的概念、使用场景、多种创建的方式、最后介绍了如何进行使用,希望能给大家的学习带来一点帮助。

     作者简介:云计算容器DockerK8sServerless方向产品经理,学点技术,为更好地设计产品。

  • 相关阅读:
    【重点】2020年宝山区义务教育阶段学校校区范围与招生计划(初中)
    转: 彻底理解 Spring 容器和应用上下文
    转《深入理解 Java 内存模型》读书笔记
    Mysql Update 流程摘抄
    统一支付接口设计
    支付系统 简版设计
    订单1:n支付单 设计讨论
    RocketMQ 使用情况梳理
    转 Java jar (SpringBoot Jar)转为win可执行的exe程序
    Git flow 工作流与规范
  • 原文地址:https://www.cnblogs.com/gdut1425/p/13365914.html
Copyright © 2020-2023  润新知