• kubernetes之十: ConfigMap


    什么是ConfigMap

    ConfigMap是用来存储配置文件的Kubernetes的资源对象,配置对象存储在Etcd中,配置的形式可以是完整的配置文件或者key/value的形式
    

    ConfigMap可以带来什么好处

    传统的应用服务,每个服务都有自己的配置文件,各自配置文件存储在服务所在节点,对于单体应用,这种存储没有任何问题,
    但是随着用户数量的激增,一个节点不能满足线上用户使用,故服务可能从一个节点扩展到十个节点,这就导致,
    如果有一个配置出现变更,就需要对应修改十次配置文件。这种人肉处理,显然不能满足线上部署要求,
    故引入了各种类似于 ZooKeeper 中间件实现的配置中心,但配置中心属于 “侵入式” 设计,
    需要修改引入第三方类库,它要求每个业务都调用特定的配置接口,破坏了系统本身的完整性,
    Kubernetes 利用了 Volume 功能,完整设计了一套配置中心,其核心对象就是ConfigMap
    使用过程不用修改任何原有设计,即可无缝对 ConfigMap;为什么呢?

     

    使用configmap的限制条件

    ConfigMap必须在Pod之前创建
    
    ConfigMap受Namespace限制,只有处于相同Namespace中的Pod才可以引用它。
    
    ConfigMap中的配额管理还未能实现。
    
    kubelet只支持可以被API Server管理的Pod使用ConfigMap
    
    kubelet在本Node上通过 --manifest-url或–config自动创建的静态Pod将无法引用ConfigMap。
    
    在Pod对ConfigMap进行挂载(volumeMount)操作时,在容器内部只能挂载为“目录”,无法挂载为“文件”,在挂载到容器内部后,在目录下将包含ConfigMap定义的每个item,
    如果在该目录下原来还有其他文件,则容器内的该目录将被挂载的ConfigMap覆盖 如果应用程序需要保留原来的其他文件,则需要进行额外的处理。可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或者链接到(cp或link命令)应用
    所用的实际配置目录下

      

    ConfigMap 三种创建方式

    第一种方式: 指定字面量进行创建,创建命令如下所示

    kubectl create configmap configmaptest --from-literal=foo=bar --from-literal=one=two
    
    
    
    [root@master01 ~]# kubectl get configmap configmaptest -o yaml
    apiVersion: v1
    data:
      foo: bar
      one: two
    kind: ConfigMap
    metadata:
      name: configmaptest
      namespace: default
    

     

    第二种方式: 指定特定文件进行创建

    [root@master01 template]# cat db.properties 
    driverClassName=com.mysql.jdbc.Driver
    
    kubectl create configmap config-files --from-file=/data/k8s/template/db.properties 
    
    
    
    [root@master01 template]# kubectl get configmap config-files -o yaml
    apiVersion: v1
    data:
      db.properties: |
         driverClassName=com.mysql.jdbc.Driver
    kind: ConfigMap
    metadata:
      creationTimestamp: "2020-08-12T13:52:35Z"
      managedFields:
      - apiVersion: v1
        fieldsType: FieldsV1
        fieldsV1:
          f:data:
            .: {}
            f:db.properties: {}
        manager: kubectl
        operation: Update
        time: "2020-08-12T13:52:35Z"
      name: config-files
      namespace: default
      resourceVersion: "491983"
      selfLink: /api/v1/namespaces/default/configmaps/config-files
      uid: bfeacb89-fdd7-41d7-8089-ce1a1629b102
    You have new mail in /var/spool/mail/root
    

     第三种:  指定特定文件夹进行创建

    kubectl create configmap config-dir --from-file=/data/k8s/template/config/
    
    
    [root@master01 ~]# kubectl get configmap config-dir -o yaml
    apiVersion: v1
    data:
      db.properties: |
        driverClassName=com.mysql.jdbc.Driver
      svc.properties: |
        #server
        protocol=tcp
      system.properties: |
        time=100
    kind: ConfigMap
    metadata:
      name: config-dir
      namespace: default
    

     

     ConfigMap 作为环境变量三种使用方式

    1、单个引用
    先创建configmap
    
    kubectl create configmap configmaptest --from-literal=code=25 --from-literal=foo=bar --from-literal=one=two
     
    
    
        spec:
          containers:
          - name: demo-nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            env:
            - name: CODE-TIME   (env变量名)
              valueFrom:
                configMapKeyRef:
                  name: configmaptest   (configmap的名称)
                  key: code           (定义的key)

    验证

    [root@master01 template]# kubectl exec -it demo-nginx-55485d6b97-7wzhq -- /bin/bash
    root@demo-nginx-55485d6b97-7wzhq:/# env|grep CO
    CODE-TIME=25


      

    2)多个引用

    一次性传递所有ConfigMap条目作为环境变量

        spec:
          containers:
          - name: demo-nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            envFrom:
            - prefix: CODE_     #以CODE前缀
              configMapRef:
                name: configmaptest  #configmap名称
    
            ports:
            - name: http
              containerPort: 80

    验证

    [root@master01 template]# kubectl exec -it demo-nginx-6b8dcf7d4f-xzhgk -- /bin/bash
    root@demo-nginx-6b8dcf7d4f-xzhgk:/# env|grep CO
    CODE_code=25
    CODE_one=two
    CODE_foo=bar

    3) args 方式传递环境变量

    容器启动时,传递该变量到服务,运行 shell 脚本,可能会用到,具体设置方式如图(5)所示

       spec:
          containers:
          - name: demo-nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            env:
            - name: CONFIG
              valueFrom:
                configMapKeyRef:
                  name: configmaptest
                  key: code
            args: ["$(CONFIG)"]
    

      

     4)volume挂载

    ......
            - containerPort: 80
    
            volumeMounts:
              - mountPath: /usr/local/nginx/conf/vhost/
                name: http
    
              - mountPath: /usr/local/nginx/html/foo
                subPath: foo
                name: nginx-html
    
          volumes:
          - name: http
            configMap:
              name: nginx-conf
    
          - name: nginx-html
            configMap:
              name: configmaptest
              items: 
              - key: foo
                path: foo
       ......

    如果有特定需求,需要挂载某个特定文件,而不允许覆盖原有文件,可以挂载到指定文件,通过 subPath 配合指定文件。
    但是单个文件挂载这种方式不能实现热更新,即宿主机 ConfigMap 文件发生变化,容器内部不会自动重载

    至于 items 使用就比较简单了,如果一个 ConfigMap 中包含多个配置文件,但是只想暴露出来其中一部分
    那么可以通过 items 方式进行指定。当然你也可以对文件设置读写权限

    像下面的LAMP,可以将同一个volume下的 mysql 和 html目录,挂载到不同的挂载点上,这样就不需要为 mysql 和 html 单独创建volume了

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-lamp-site
    spec:
        containers:
        - name: mysql
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            value: "rootpasswd" 
    
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql
    
        - name: php
          image: php:7.0-apache
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html
    
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-lamp-site-data
    
    apiVersion: v1kind: Pmetadata:
    
      name: pod-volume-test
    spec:
      containers:
        - name: apache
          image: httpd
          ports:
            - containerPort: 80
          volumeMounts:
            - name: volume-test
              mountPath: /var/www/html
      volumes:
        - name: volume-test
          configMap:
            name: cm-apache
            items:
              - key: html
                path: main.html   #文件名
              - key: path
                path: path.txt   #文件名
    
    
    验证:
    root@pod-volume-test:/# cd /var/www/html/ 
    root@pod-volume-test:/var/www/html# ls 
    main.html path.txt
    root@pod-volume-test:/var/www/html#cat main.html 
    
    hello world 
    root@pod-volume-test:/var/www/html# cat path.txt 
    /var/www/html
    

      

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: busybox
        args: [ "/bin/sh", "-c", "sleep 3000" ]
        volumeMounts:
        - name: mysql
          mountPath: "/tmp"
    
      volumes:
      - name: mysql
        configMap:
          name: mysql-cm
          items:
          - key: my.cnf
            path: mysql/my.cnf  
    
    验证
    
    [root@master ~]# kubectl exec -it mypod sh
    / # cat /tmp/mysql/my.cnf 
    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock
    symbolic-links=0
    [mysqld_safe]
    log-error=/var/log/mariadb/mariadb.log
    pid-file=/var/run/mariadb/mariadb.pid
    !includedir /etc/my.cnf.d
    / # exit
    

      

    热更新机制

    当 ConfigMap 作为 Volume 进行挂载时,它的内容是会更新的。分析 ConfigMap volume 的更新机制:

    更新操作由 kubelet 的 Pod 同步循环触发,每次进行 Pod 同步时(默认每 10 秒一次),kubelet 都会将 Pod 的所有 ConfigMap Volume 标记为“需要重新挂载
    (RequireRemount)”,而 kubelet 中的 Volume 控制循环会发现这些需要重新挂载的 Volume,去执行一次挂载操作,在 ConfigMap 的重新挂载过程中,kubelet
    会先比较远端的 ConfigMap 与 Volume 中的 ConfigMap 是否一致,再做更新。要注意,“拿远端的 ConfigMap” 这个操作可能是有缓存的,因此拿到的并不一定是最新版本。
    延迟时间:Pod 同步间隔(默认10秒)+ ConfigMap 本地缓存的 TTL。

      

    部分文件挂载

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        name: busybox
        role: master
      name: busybox
    spec:
      containers:
      - name: busybox
        image: myhub.fdccloud.com/library/busybox
        command:
        - sleep
        - "3600"
    
        volumeMounts:
        - name: configmap-volume
          mountPath: /etc/passwd
          subPath: path/to/passwd
        - name: configmap-volume-1
          mountPath: /etc/group
          subPath: path/to/group
    
      nodeSelector:
        app: busybox
    
      volumes:
      - name: configmap-volume
        configMap:
          name: cmtest
          items:
            - key: passwd
              path: path/to/passwd
    
      - name: configmap-volume-1
        configMap:
          name: cmtest
          items:
            - key: group
              path: path/to/group
    

      

      

     

     

  • 相关阅读:
    安卓使用spinner控件和pull解析实现全国省市县的三级联动(附上xml文件)
    安卓linearlayout布局的一个嵌套实例
    接口回调的例子和安卓中的接口回掉实例
    Android Studio 快捷键
    java比较器 之compareable 和comparato比较
    4.Gradle构建Spring Boot项目
    2.Gradle安装和常用命令
    1.Gradle基础介绍
    6.SpringBoot学习(六)——Spring Boot Banner自定义
    4.SpringBoot学习(四)——Spring Boot Validation校验及原理
  • 原文地址:https://www.cnblogs.com/louis2008/p/kubernetes-configmap.html
Copyright © 2020-2023  润新知