• Kubernetes——应用程序配置管理及 ConfigMap 资源


    应用程序配置管理及 ConfigMap 资源

      说到配置中心,大家接触过微服务的话,应该不陌生,像国内的分布式配置中心相关开源项目有 Diamond(阿里)、Apollo(携程)、Qconf(奇虎360)和 disconf(百度)等。

      作为分布式系统的 Kubernetes 也提供了统一配置管理方案——ConfigMap。

      Kubernetes 基于 ConfigMap 对象实现了将配置文件从容器镜像中解耦,从而增强了容器应用的可移植性。简单来说,一个 ConfigMap 对象就是一系列配置数据的集合,这些数据可 "注入" 到 Pod 对象中,并为容器应用所用,注入方式有挂载为存储卷和传递为环境变量两种。

      ConfigMap 对象将配置数据以键值对的形式进行存储,这些数据可以在 Pod 对象中使用或者为系统组件提供配置。无论应用程序如何使用 ConfigMap 对象中的数据,用户都完全可以通过在不同的环境中创建名称相同但内容不同的 ConfigMap 对象,从而为不同环境中同一功能的 Pod 资源提供不同的配置信息,实现应用与配置的灵活勾兑。

    一、创建 ConfigMap 对象

      Kubernetes 的不少资源既可以使用 kubectl create 命令创建,也可以使用清单创建,例如前面讲到的 namespace。

      ConfigMap 是另一个两种创建方式都比较常用的资源。而且,通过使用 "kubectl create configmap" 命令,用户可以根据目录、文件或直接值创建 ConfigMap对象。命令的语法格式如下所示:

    root@mh-k8s-master-247-10 ~]# kubectl create configmap --help
    Create a configmap based on a file, directory, or specified literal value.
    
     A single configmap may package one or more key/value pairs.
    
     When creating a configmap based on a file, the key will default to the basename of the file, and
    the value will default to the file content.  If the basename is an invalid key, you may specify an
    alternate key.
    
     When creating a configmap based on a directory, each file whose basename is a valid key in the
    directory will be packaged into the configmap.  Any directory entries except regular files are
    ignored (e.g. subdirectories, symlinks, devices, pipes, etc).
    
    Aliases:
    configmap, cm
    
    Examples:
      # Create a new configmap named my-config based on folder bar
      kubectl create configmap my-config --from-file=path/to/bar
      
      # Create a new configmap named my-config with specified keys instead of file basenames on disk
      kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt
    --from-file=key2=/path/to/bar/file2.txt
      
      # Create a new configmap named my-config with key1=config1 and key2=config2
      kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
      
      # Create a new configmap named my-config from the key=value pairs in the file
      kubectl create configmap my-config --from-file=path/to/bar
      
      # Create a new configmap named my-config from an env file
      kubectl create configmap my-config --from-env-file=path/to/bar.env
    
    Options:
          --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or
    map key is missing in the template. Only applies to golang and jsonpath output formats.
          --append-hash=false: Append a hash of the configmap to its name.
          --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the
    object that would be sent, without sending it. If server strategy, submit server-side request
    without persisting the resource.
          --from-env-file='': Specify the path to a file to read lines of key=val pairs to create a
    configmap (i.e. a Docker .env file).
          --from-file=[]: Key file can be specified using its file path, in which case file basename
    will be used as configmap key, or optionally with a key and file path, in which case the given key
    will be used.  Specifying a directory will iterate each named file in the directory whose basename
    is a valid configmap key.
          --from-literal=[]: Specify a key and literal value to insert in configmap (i.e.
    mykey=somevalue)
      -o, --output='': Output format. One of:
    json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
          --save-config=false: If true, the configuration of current object will be saved in its
    annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to
    perform kubectl apply on this object in the future.
          --template='': Template string or path to template file to use when -o=go-template,
    -o=go-template-file. The template format is golang templates
    [http://golang.org/pkg/text/template/#pkg-overview].
          --validate=true: If true, use a schema to validate the input before sending it
    
    Usage:
      kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1]
    [--dry-run=server|client|none] [options]
    
    Use "kubectl options" for a list of global command-line options (applies to all commands).
    [root@mh-k8s-master-247-10 ~]# 
    

      其中,<map-name> 即为 ConfigMap 对象的名称,而 <data-source> 是数据源,它可以通过直接值、文件或目录来获取。无论是哪一种数据源供给方式,它都要转换为 ConfigMap 对象中的 Key-Value 数据,其中 Key 由用户在命令行给出或是文件数据源的文件名,它仅能由字母、数字、连接号和点号组成,而 Value 则是直接值或文件数据源的内容。

    1、利用直接值创建

      为 "kubectl create configmap" 命令使用 "--from-literal" 选项可在命令行直接给出键值对来创建 ConfigMap 对象,重复使用此选项则可以传递多个键值对。命令格式如下:

    kubectl create configmap configmap_name --from-literal=key-name-1=value-1 --from-literal=key-name-2=value-2
    
    help:
       --from-literal=[]: Specify a key and literal value to insert in configmap (i.e.mykey=somevalue)

      "kubectl get configmap" 命令可用于查看创建的 ConfigMap 对象 special-config 的相关信息。举个例子:

    [root@mh-k8s-master-247-10 ~]# kubectl get configmap
    NAME                 DATA   AGE
    istio-ca-root-cert   1      74d
    [root@mh-k8s-master-247-10 ~]# kubectl get configmap istio-ca-root-cert -o yaml
    apiVersion: v1
    data:
      root-cert.pem: |
        -----BEGIN CERTIFICATE-----
                  省略
        -----END CERTIFICATE-----
    kind: ConfigMap
    metadata:
      creationTimestamp: "2022-04-12T05:23:11Z"
      labels:
        istio.io/config: "true"
      managedFields:
      - apiVersion: v1
        fieldsType: FieldsV1
        fieldsV1:
          f:data:
            .: {}
            f:root-cert.pem: {}
          f:metadata:
            f:labels:
              .: {}
              f:istio.io/config: {}
        manager: pilot-discovery
        operation: Update
        time: "2022-04-12T05:23:11Z"
      name: istio-ca-root-cert
      namespace: default
      resourceVersion: "6208"
      selfLink: /api/v1/namespaces/default/configmaps/istio-ca-root-cert
      uid: e03bd294-dd7d-417c-a6eb-3a6066cde0dd
    [root@mh-k8s-master-247-10 ~]# 
    

    2、基于文件创建

      为 "kubeclt create configmap" 命令使用 "--from-file" 选项即可基于文件内容来创建 ConfigMap 对象,可以重复多次使用 "--from-file" 选项以传递多个文件内容,它的命令格式如下:

    Usage:
      kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none] [options]
    

      例如,下面命令可以把事先准备好的 Nginx 配置文件模板保存于 ConfigMap 对象 nginx-config:

    kubectl create configmap nginx-config\
    --from-file=./data/configs/nginx/conf.d/www.aaa.com.conf \
    --from-file=./data/configs/nginx/conf.d/www.bbb.com.conf
    

      如果需要自行指定键名,则可在 "--from-file" 选项中直接指定自定义的键,命令格式如下:

    kubectl create configmap nginx-config\
    --from-file=aaa=./data/configs/nginx/conf.d/www.aaa.com.conf \
    --from-file=bbb=./data/configs/nginx/conf.d/www.bbb.com.conf
    

    3、基于目录创建  

      如果配置文件数量较多且存储于有限的目录中时,kubeclt 还提供了基于目录直接将多个文件分别纳为键值数据的 ConfigMap 资源创建方式。将 "--from-file" 选项后面所跟的路径指向一个目录路径就能将目录下的所有创建于同一 ConfigMap 资源中,命令格式如下:

    Usage:
      kubectl create configmap <configmap_nam>[--from-file=<path-to-directory>]
    

      如下面的命令,将 /data/configs/nginx/conf.d/  目录下的所有文件都保存于 nginx-config-files 对象中:

    kubect  create configmap nginx-config-file --from-file=./data/confnigs/nginx/conf.d/
    

    4、使用清单创建

      基于配置文件创建 ConfigMap 资源时,它所使用的字段包括通常的 apiVersion、kind 和 metadata 字段,以及用于存储数据的关键字段 "data"。例如下面的示例代码:

    apiVersion: v1
    kind: configMap
    metadata:
      name: configmap-demo
      namespace: default
    data:
      log_level: INFO
      log_file: /var/log/test.log
    

      如果其值来自于文件内容时,则使用配置文件创建 ConfigMap 资源的便捷性还不如直接通过命令行的方式,因此建议直接使用命令行加载文件或目录的方式进行创建。为了便于配置留存,可以在创建完成后使用 get -o yaml 命令获取到相关信息后再进行编辑留存。

     二、向 Pod 环境变量传递 ConfigMap 对象键值数据

      Pod 资源的环境变量的获得方式之一包括引用 ConfigMap 对象中的数据,这一点通过在 env 字段中为 valueFrom 内嵌 configMapKeyRef 对象即可实现,其使用格式如下:

    valueFrom:
      configMapKeyRef:
        key:
    	name:
    	  optional:
    

      下面是保存于配置文件 configmap-env.yaml 的资源定义示例,它包含了两个资源,彼此之间使用 "---" 互相分隔。

      1. 第一个资源是 busybox-httpd-config 的 ConfigMap 对象,它包含了两个键值数据;
      2. 第二个资源是 configmap-env-demo 的 Pod 对象,它通过环境变量引用了 busybox-httpd-config 对象中的键值数据,并将其直接传递给了自定义运行的容器应用 httpd:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: busybox-httpd-config
      namespace: default
    data:
      http_port: "8080"
      verbose_level: "-vv"
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-env-demo
      namespace: default
    spec:
      containers:
      - image: busybox-httpd
        command: ["/bin/httpd"]
    	args: ["-f", "-p", "$(HTTPD_PORT)","$(HTTPD_LOG_VERBOSE)"]
    	env:
    	- name: HTTP_PORT
    	  valueFrom:
    	    configMapKeyRef:
    		  name: busybox-httpd-config
    		  key: httpd_port
        - name: HTTPD_LOG_VERBOSE
    	  valueFrom:
    	    configMapKeyRef
    		  name: busybox-httpd-config
    		  key: verbose_level
    		  optional: true
    

      注意,在 command 或 args 字段中引用环境变量要使用 "$(VAR_NAME)" 的格式。待上面配置文件中的资源创建完成后,可以通过如下命令验证 pod 资源监听的端口等配置信息是否为 busybox-httpd-config 中定义的内容:

    kubectl exec configmap-env-demo ps aux
    

      ConfigMap 是名称空间级别的资源,它必须与引用它的 Pod 资源在同一空间中。

    三、ConfigMap 存储卷

      若 ConfigMap 对象中的键值来源于较长的文件内容,那么使用环境变量将其导入会使得变量值占据过多的内存空间而且不易处理。此类数据通常用于为容器应用提供配置文件,因此将其内容直接作为文件进行引用是较好的选择。其实现方式是,在定义 Pod 资源时,将此类 ConfigMap 对象配置为 ConfigMap 类型的存储卷,而后由容器将其挂载至特定的挂载点后直接进行访问。

    1)挂载整个存储卷

      关联为 Pod 资源的存储卷时,ConfigMap 对象中的每个键都对应地表现为一个文件,键名转为文件名,而键值则为相应文件的内容,即便是通过直接值创建的键值数据,也一样表现为文件视图。挂载于容器上之后,由键值数据表现出的文件位于挂载点目录中,容器中的进程可直接读取这些文件的内容。
      配置 Pod 资源时,基于存储卷的方式引用 ConfigMap 对象的方法非常简单,仅需要指明存储卷名称及要应用的 ConfigMap 对象名称即可。

      下面是于配置文件 configmap-volume-pod.yaml 中定义的 Pod 资源,具体如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-volume-demo
      namespace: default
    spec:
      containers:
      - image: nginx:alpine
        name: nginx-server
    	volumeMounts:
    	- name: ngxconfig
    	  mountPath: /etc/nginx/conf.d/
    	  readOnly: true
      volumes:
      - name: ngxconfig
        configMap:
          name: nginx-config-files
    

    2)挂载存储卷中的部分键值

      有时候,我们可能期望在容器中挂载某 ConfigMap 存储卷后,只 "导出" 部分文件内容(只导出部分 key:value 数据),示例如下:

    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-volume-demo-2
      namespace: default
    spec:
      containers:
      - image: nginx:alpine
        name: nginx-server
    	volumeMounts:
    	- name: ngxconfig
    	  mountPath: /etc/nginx/conf.d/
    	  readOnly: true
      volumes:
      - name: ngxconfig
        configMap:
          name: nginx-config-files
    	  items:
    	  - key: myserver.conf
    	    path: myserver.conf
    		mode: 0644
    	  items:
    	  - key: youserver.conf
    	    path: youserver.conf
    		mode: 0644
    

      pod.spec.volumes.configMap 字段定义如下:

    [root@mh-k8s-master-247-10 ~]# kubectl explain pod.spec.volumes.configMap
    KIND:     Pod
    VERSION:  v1
    
    RESOURCE: configMap <Object>
    
    DESCRIPTION:
         ConfigMap represents a configMap that should populate this volume
    
         Adapts a ConfigMap into a volume. The contents of the target ConfigMap's
         Data field will be presented in a volume as files using the keys in the
         Data field as the file names, unless the items element is populated with
         specific mappings of keys to paths. ConfigMap volumes support ownership
         management and SELinux relabeling.
    
    FIELDS:
       defaultMode	<integer>
         Optional: mode bits to use on created files by default. Must be a value
         between 0 and 0777. Defaults to 0644. Directories within the path are not
         affected by this setting. This might be in conflict with other options that
         affect the file mode, like fsGroup, and the result can be other mode bits
         set.
    
       items	<[]Object>
         If unspecified, each key-value pair in the Data field of the referenced
         ConfigMap will be projected into the volume as a file whose name is the key
         and content is the value. If specified, the listed keys will be projected
         into the specified paths, and unlisted keys will not be present. If a key
         is specified which is not present in the ConfigMap, the volume setup will
         error unless it is marked optional. Paths must be relative and may not
         contain the '..' path or start with '..'.
    
       name	<string>
         Name of the referent. More info:
         https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
    
       optional	<boolean>
         Specify whether the ConfigMap or its keys must be defined
    
    [root@mh-k8s-master-247-10 ~]# 
    

      pod.spec.volumes.configMap.items 字段定义如下:

    [root@mh-k8s-master-247-10 ~]# kubectl explain pod.spec.volumes.configMap.items
    KIND:     Pod
    VERSION:  v1
    
    RESOURCE: items <[]Object>
    
    DESCRIPTION:
         If unspecified, each key-value pair in the Data field of the referenced
         ConfigMap will be projected into the volume as a file whose name is the key
         and content is the value. If specified, the listed keys will be projected
         into the specified paths, and unlisted keys will not be present. If a key
         is specified which is not present in the ConfigMap, the volume setup will
         error unless it is marked optional. Paths must be relative and may not
         contain the '..' path or start with '..'.
    
         Maps a string key to a path within a volume.
    
    FIELDS:
       key	<string> -required-
         The key to project.
    
       mode	<integer>
         Optional: mode bits to use on this file, must be a value between 0 and
         0777. If not specified, the volume defaultMode will be used. This might be
         in conflict with other options that affect the file mode, like fsGroup, and
         the result can be other mode bits set.
    
       path	<string> -required-
         The relative path of the file to map the key to. May not be an absolute
         path. May not contain the path element '..'. May not start with the string
         '..'.
    
    [root@mh-k8s-master-247-10 ~]# 
    

    3)独立挂载存储卷中的键值

      前面几种方式中,无论是挂载所有文件还是部分文件,挂载点目录下原有的文件都会被隐藏。对于期望将 ConfigMap 对象提供的配置文件补充于挂载点目录下,并且不影响原本就存在的一些文件,这种方式显然难以如愿。

      例如:/etc/nginx/conf.d 目录中原本就存在一些文件(如 default.conf),用户期望将 nginx-config-files 中的全部或部分文件装载进此目录中而不影响其原有的文件。

      解决办法:使用容器的 volumeMounts 字段中使用的 subPath 字段来解决,它可以支持用户从存储卷挂载单个文件或单个目录而非整个存储卷。

    apiVersion: v1
    kind: Pod
    metadata:
      name: configmap-volume-demo-3
      namespace: default
    spec:
      containers:
      - image: nginx:alpine
        name: nginx-server
    	volumeMounts:
    	- name: ngxconfig
    	  mountPath: /etc/nginx/conf.d/myserver.conf
    	  subPath: myserver.conf
    	  readOnly: true
    	- name: ngxconfig
    	  mountPath: /etc/nginx/conf.d/yourserver.conf
    	  subPath: yourserver.conf
    	  readOnly: true
      volumes:
      - name: ngxconfig
        configMap:
    	  name: nginx-config-files
    

      pod.spec.containers.volumeMounts 字段定义如下:

    [root@mh-k8s-master-247-10 ~]# kubectl explain pod.spec.containers.volumeMounts
    KIND:     Pod
    VERSION:  v1
    
    RESOURCE: volumeMounts <[]Object>
    
    DESCRIPTION:
         Pod volumes to mount into the container's filesystem. Cannot be updated.
    
         VolumeMount describes a mounting of a Volume within a container.
    
    FIELDS:
       mountPath	<string> -required-
         Path within the container at which the volume should be mounted. Must not
         contain ':'.
    
       mountPropagation	<string>
         mountPropagation determines how mounts are propagated from the host to
         container and the other way around. When not set, MountPropagationNone is
         used. This field is beta in 1.10.
    
       name	<string> -required-
         This must match the Name of a Volume.
    
       readOnly	<boolean>
         Mounted read-only if true, read-write otherwise (false or unspecified).
         Defaults to false.
    
       subPath	<string>
         Path within the volume from which the container's volume should be mounted.
         Defaults to "" (volume's root).
    
       subPathExpr	<string>
         Expanded path within the volume from which the container's volume should be
         mounted. Behaves similarly to SubPath but environment variable references
         $(VAR_NAME) are expanded using the container's environment. Defaults to ""
         (volume's root). SubPathExpr and SubPath are mutually exclusive.
    
    [root@mh-k8s-master-247-10 ~]# 
    

    4)容器应用重载新配置

      建议:重启容器。

  • 相关阅读:
    BZOJ 1202: [HNOI2005]狡猾的商人( 差分约束 )
    BZOJ 1800: [Ahoi2009]fly 飞行棋( 枚举 )
    BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
    BZOJ 1029: [JSOI2007]建筑抢修( 贪心 )
    FZU 2233 ~APTX4869 贪心+并查集
    FZU2232 炉石传说 最大匹配
    FZU 2237 中位数 主席树 树上k大
    CodeForcesGym 100753B Bounty Hunter II 二分图最小路径覆盖
    NOIP2010关押罪犯 二分+二染色
    POJ2236 Wireless Network 并查集
  • 原文地址:https://www.cnblogs.com/zuoyang/p/16411978.html
Copyright © 2020-2023  润新知