k8s中configmap的作用及使用方式

概述

为了解决传统容器中配置的挂载、变更、管理等问题,在k8s中引入了一个叫做configmap的资源对象,在configmap中,各个配置项都是以key-value的方式存在的,value的数据可以是一个配置文件的内容,这些配置项被保存在k8s使用的持久化存储etcd中。

这样就形成了一个k8s中的配置中心,可以独立的对configmap中的数据进行修改,然后将configmap挂载到pod中进行使用,可以以env的方式,也可以以配置文件的方式在pod中进行引用。

这样配置和pod就实现了解耦,都是k8s中独立的资源对象。

简单说:configmap是k8s中的应用配置管理方案。

常见用法

configmap供容器使用的典型用法:

  1. 生成为容器内的环境变量
  2. 设置容器启动命令的启动参数(需设置为环境变量) 【环境变量先进入容器,然后才是容器启动命令
  1. 以volume的形式挂载为容器内部的文件或目录

1、configmap资源对象的创建

1.1、通过yaml配置文件的方式创建

通过以下的命令创建configmap,其中在data部分有2个key-value,是环境变量的定义:

kubectl apply -f - <<'eof'
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-vars
data:
  apploglevel: info
  appdatadir: /var/data
eof

执行创建configmap过程:

[root@nccztsjb-node-11 ~]# kubectl apply -f - <<'eof'
> apiVersion: v1
> kind: ConfigMap
> metadata:
>   name: cm-vars
> data:
>   apploglevel: info
>   appdatadir: /var/data
> eof
configmap/cm-vars created
[root@nccztsjb-node-11 ~]# kubectl get cm
NAME               DATA   AGE
cm-vars            2      5s
kube-root-ca.crt   1      38d
[root@nccztsjb-node-11 ~]# 

发现configmap cm-vars已经创建成功。

查看创建好的configmap

[root@nccztsjb-node-11 ~]# kubectl get cm cm-vars -o yaml
apiVersion: v1
data:
  appdatadir: /var/data
  apploglevel: info
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"appdatadir":"/var/data","apploglevel":"info"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"cm-vars","namespace":"default"}}
  creationTimestamp: "2022-01-10T07:31:05Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:appdatadir: {}
        f:apploglevel: {}
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2022-01-10T07:31:05Z"
  name: cm-vars
  namespace: default
  resourceVersion: "11021769"
  selfLink: /api/v1/namespaces/default/configmaps/cm-vars
  uid: c513d39b-c128-46d3-9eb7-78da20ec47f2
  
  
[root@nccztsjb-node-11 ~]# kubectl describe cm cm-vars
Name:         cm-vars
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
appdatadir:
----
/var/data
apploglevel:
----
info
Events:  <none>

1.2、通过kubectl命令行的方式创建

以配置文件的方式来创建configmap

(1)通过--from-file参数从文件中进行创建

[root@nccztsjb-node-11 ~]# ls -l nginx.conf kibana.yml 
-rw-r--r-- 1 root root 5279 Dec  2 18:16 kibana.yml
-rw-r--r-- 1 root root 3132 Dec  2 18:10 nginx.conf
[root@nccztsjb-node-11 ~]# kubectl create configmap cm-configfiles --from-file nginx.conf --from-file=kibana.yml 
configmap/cm-configfiles created
[root@nccztsjb-node-11 ~]# 

基于2个配置文件创建configmap,--from-file= [key=],如果不指定key,配置文件就是key的名字

查看已经创建好的configmap

[root@nccztsjb-node-11 ~]# kubectl get cm cm-configfiles -o yaml
apiVersion: v1
data:
  kibana.yml: |
    # Kibana is served by a back end server. This setting specifies the port to use.
    server.port: 25021

    # Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
    # The default is 'localhost', which usually means remote machines will not be able to connect.
    # To allow connections from remote users, set this parameter to a non-loopback address.
    server.host: "0.0.0.0"

    # Enables you to specify a path to mount Kibana at if you are running behind a proxy.
    # Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
    # from requests it receives, and to prevent a deprecation warning at startup.
    # This setting cannot end in a slash.
    server.basePath: "/kibana"

    # Specifies whether Kibana should rewrite requests that are prefixed with
    # `server.basePath` or require that they are rewritten by your reverse proxy.
    # This setting was effectively always `false` before Kibana 6.3 and will
    # default to `true` starting in Kibana 7.0.
    server.rewriteBasePath: true

    # The maximum payload size in bytes for incoming server requests.
    #server.maxPayloadBytes: 1048576

    # The Kibana server's name.  This is used for display purposes.
    #server.name: "your-hostname"
    server.name: "Kibana-25021"

    # The URLs of the Elasticsearch instances to use for all your queries.
    elasticsearch.hosts: ["172.20.45.156:34994"]

    # When this setting's value is true Kibana uses the hostname specified in the server.host
    # setting. When the value of this setting is false, Kibana uses the hostname of the host
    # that connects to this Kibana instance.
    #elasticsearch.preserveHost: true

    # Kibana uses an index in Elasticsearch to store saved searches, visualizations and
    # dashboards. Kibana creates a new index if the index doesn't already exist.
    #kibana.index: ".kibana"

    # The default application to load.
    #kibana.defaultAppId: "home"

    # If your Elasticsearch is protected with basic authentication, these settings provide
    # the username and password that the Kibana server uses to perform maintenance on the Kibana
    # index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
    # is proxied through the Kibana server.
    elasticsearch.username: "elastic"
    elasticsearch.password: "Yonyou123"

    # Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
    # These settings enable SSL for outgoing requests from the Kibana server to the browser.
    #server.ssl.enabled: false
    #server.ssl.certificate: /path/to/your/server.crt
    #server.ssl.key: /path/to/your/server.key

    # Optional settings that provide the paths to the PEM-format SSL certificate and key files.
    # These files are used to verify the identity of Kibana to Elasticsearch and are required when
    # xpack.security.http.ssl.client_authentication in Elasticsearch is set to required.
    #elasticsearch.ssl.certificate: /path/to/your/client.crt
    #elasticsearch.ssl.key: /path/to/your/client.key

    # Optional setting that enables you to specify a path to the PEM file for the certificate
    # authority for your Elasticsearch instance.
    #elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]

    # To disregard the validity of SSL certificates, change this setting's value to 'none'.
    #elasticsearch.ssl.verificationMode: full

    # Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of
    # the elasticsearch.requestTimeout setting.
    #elasticsearch.pingTimeout: 1500

    # Time in milliseconds to wait for responses from the back end or Elasticsearch. This value
    # must be a positive integer.
    #elasticsearch.requestTimeout: 30000

    # List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
    # headers, set this value to [] (an empty list).
    #elasticsearch.requestHeadersWhitelist: [ authorization ]

    # Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten
    # by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration.
    #elasticsearch.customHeaders: {}

    # Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
    #elasticsearch.shardTimeout: 30000

    # Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying.
    #elasticsearch.startupTimeout: 5000

    # Logs queries sent to Elasticsearch. Requires logging.verbose set to true.
    #elasticsearch.logQueries: false

    # Specifies the path where Kibana creates the process ID file.
    #pid.file: /var/run/kibana.pid

    # Enables you specify a file where Kibana stores log output.
    #logging.dest: stdout

    # Set the value of this setting to true to suppress all logging output.
    #logging.silent: false

    # Set the value of this setting to true to suppress all logging output other than error messages.
    #logging.quiet: false

    # Set the value of this setting to true to log all events, including system usage information
    # and all requests.
    #logging.verbose: false

    # Set the interval in milliseconds to sample system and process performance
    # metrics. Minimum is 100ms. Defaults to 5000.
    #ops.interval: 5000

    # Specifies locale to be used for all localizable strings, dates and number formats.
    # Supported languages are the following: English - en , by default , Chinese - zh-CN .
    #i18n.locale: "en"
  nginx.conf: |
    user nginx;
    worker_processes  auto;
    pid /run/nginx.pid;

    events {
        use epoll;
        worker_connections  20480;
        multi_accept on;
        accept_mutex on;
    }

    stream {
        include sites-enabled/*.stream;
    }

    http {
        include       mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr|$remote_user|[$time_local]|"$request"|'
                          '$status|$body_bytes_sent|$http_host|"$http_referer"|'
                          '"$http_user_agent"|$http_x_forwarded_for|$upstream_cache_status|'
                          '"$upstream_http_content_type"|$request_time|$upstream_response_time|$bytes_sent|$request_length|'
                          '"$upstream_addr"|$uuid|$span_id';

        access_log /data/iuap/logs/nginx/access.log  main;
        error_log /data/iuap/logs/nginx/error.log notice;

        sendfile        on;
        keepalive_timeout  65;

        charset utf-8;
        server_tokens off;
        server_names_hash_bucket_size 128;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 800m;
        map_hash_bucket_size 256;
        tcp_nopush on;

        underscores_in_headers on;
        client_body_buffer_size 512k;
        proxy_headers_hash_max_size 51200;
        proxy_headers_hash_bucket_size 6400;
        proxy_connect_timeout 5;
        proxy_read_timeout 7200;
        proxy_send_timeout 5;
        proxy_buffer_size 16k;
        proxy_buffers 4 64k;
        proxy_busy_buffers_size 128k;
        proxy_temp_file_write_size 128k;
        proxy_temp_path /data/iuap/middleware/nginx/proxy_temp;
        proxy_cache_path /data/iuap/middleware/nginx/proxy_cache levels=1:2 keys_zone=content:20m inactive=1d max_size=100m;
        proxy_cache_path /data/iuap/middleware/nginx/proxy_cache_image levels=1:2 keys_zone=content_image:20m inactive=1d max_size=100m;
        proxy_cache_bypass $http_secret_header;
        proxy_ignore_client_abort on;

        vhost_traffic_status_zone;
        vhost_traffic_status_filter_by_host on;

        gzip on;
        gzip_min_length 1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.0;
        gzip_comp_level 2;
        gzip_types text/plain application/x-javascript application/javascript text/css;
        gzip_vary on;

        lua_package_path "/data/iuap/middleware/nginx/lualib/?.lua;;";
        lua_package_cpath "/usr/local/luajit2-2.1/share/lua/5.1/?.so;;";

        # include conf.d/*.conf;
        include sites-enabled/*.conf;

        server {
            listen     4040 default;
            access_log off;

            location /status {
                vhost_traffic_status_display;
                vhost_traffic_status_display_format html;
                allow 127.0.0.1;
                allow 172.20.45.87;
                allow 172.23.196.0;
                allow 172.17.0.1;
                deny all;
            }

            set_by_lua $uuid '
                if ngx.var.http_X_traceId == nil then
                    return string.sub(ngx.var.request_id,17,-1)
                else
                    return ngx.var.http_X_traceId
                end
            ';

            set_by_lua $span_id '
                if ngx.var.http_X_spanId == nil then
                    return ngx.var.uuid
                else
                    return ngx.var.http_X_spanId
                end
            ';
        }
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2022-01-10T07:47:30Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:kibana.yml: {}
        f:nginx.conf: {}
    manager: kubectl-create
    operation: Update
    time: "2022-01-10T07:47:30Z"
  name: cm-configfiles
  namespace: default
  resourceVersion: "11025156"
  selfLink: /api/v1/namespaces/default/configmaps/cm-configfiles
  uid: e5eaf831-a72c-45aa-92b0-6b7b1ec70863

删除该configmap,指定key的名字

[root@nccztsjb-node-11 ~]# kubectl delete cm cm-configfiles
configmap "cm-configfiles" deleted
[root@nccztsjb-node-11 ~]# kubectl create configmap cm-configfiles --from-file=a.conf=nginx.conf --from-file=b.conf=kibana.yml 
configmap/cm-configfiles created

此时指定了key的名称,不是默认的配置文件的名字

查看创建好的configmap

[root@nccztsjb-node-11 ~]# kubectl get cm cm-configfiles -o yaml
apiVersion: v1
data:
  a.conf: |
    user nginx;
    worker_processes  auto;
    pid /run/nginx.pid;

    events {
        use epoll;
        worker_connections  20480;
        multi_accept on;
        accept_mutex on;
    }

    stream {
        include sites-enabled/*.stream;
    }

    http {
        include       mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr|$remote_user|[$time_local]|"$request"|'
                          '$status|$body_bytes_sent|$http_host|"$http_referer"|'
                          '"$http_user_agent"|$http_x_forwarded_for|$upstream_cache_status|'
                          '"$upstream_http_content_type"|$request_time|$upstream_response_time|$bytes_sent|$request_length|'
                          '"$upstream_addr"|$uuid|$span_id';

        access_log /data/iuap/logs/nginx/access.log  main;
        error_log /data/iuap/logs/nginx/error.log notice;

        sendfile        on;
        keepalive_timeout  65;

        charset utf-8;
        server_tokens off;
        server_names_hash_bucket_size 128;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 800m;
        map_hash_bucket_size 256;
        tcp_nopush on;

        underscores_in_headers on;
        client_body_buffer_size 512k;
        proxy_headers_hash_max_size 51200;
        proxy_headers_hash_bucket_size 6400;
        proxy_connect_timeout 5;
        proxy_read_timeout 7200;
        proxy_send_timeout 5;
        proxy_buffer_size 16k;
        proxy_buffers 4 64k;
        proxy_busy_buffers_size 128k;
        proxy_temp_file_write_size 128k;
        proxy_temp_path /data/iuap/middleware/nginx/proxy_temp;
        proxy_cache_path /data/iuap/middleware/nginx/proxy_cache levels=1:2 keys_zone=content:20m inactive=1d max_size=100m;
        proxy_cache_path /data/iuap/middleware/nginx/proxy_cache_image levels=1:2 keys_zone=content_image:20m inactive=1d max_size=100m;
        proxy_cache_bypass $http_secret_header;
        proxy_ignore_client_abort on;

        vhost_traffic_status_zone;
        vhost_traffic_status_filter_by_host on;

        gzip on;
        gzip_min_length 1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.0;
        gzip_comp_level 2;
        gzip_types text/plain application/x-javascript application/javascript text/css;
        gzip_vary on;

        lua_package_path "/data/iuap/middleware/nginx/lualib/?.lua;;";
        lua_package_cpath "/usr/local/luajit2-2.1/share/lua/5.1/?.so;;";

        # include conf.d/*.conf;
        include sites-enabled/*.conf;

        server {
            listen     4040 default;
            access_log off;

            location /status {
                vhost_traffic_status_display;
                vhost_traffic_status_display_format html;
                allow 127.0.0.1;
                allow 172.20.45.87;
                allow 172.23.196.0;
                allow 172.17.0.1;
                deny all;
            }

            set_by_lua $uuid '
                if ngx.var.http_X_traceId == nil then
                    return string.sub(ngx.var.request_id,17,-1)
                else
                    return ngx.var.http_X_traceId
                end
            ';

            set_by_lua $span_id '
                if ngx.var.http_X_spanId == nil then
                    return ngx.var.uuid
                else
                    return ngx.var.http_X_spanId
                end
            ';
        }
    }
  b.conf: |
    # Kibana is served by a back end server. This setting specifies the port to use.
    server.port: 25021

    # Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
    # The default is 'localhost', which usually means remote machines will not be able to connect.
    # To allow connections from remote users, set this parameter to a non-loopback address.
    server.host: "0.0.0.0"

    # Enables you to specify a path to mount Kibana at if you are running behind a proxy.
    # Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
    # from requests it receives, and to prevent a deprecation warning at startup.
    # This setting cannot end in a slash.
    server.basePath: "/kibana"

    # Specifies whether Kibana should rewrite requests that are prefixed with
    # `server.basePath` or require that they are rewritten by your reverse proxy.
    # This setting was effectively always `false` before Kibana 6.3 and will
    # default to `true` starting in Kibana 7.0.
    server.rewriteBasePath: true

    # The maximum payload size in bytes for incoming server requests.
    #server.maxPayloadBytes: 1048576

    # The Kibana server's name.  This is used for display purposes.
    #server.name: "your-hostname"
    server.name: "Kibana-25021"

    # The URLs of the Elasticsearch instances to use for all your queries.
    elasticsearch.hosts: ["172.20.45.156:34994"]

    # When this setting's value is true Kibana uses the hostname specified in the server.host
    # setting. When the value of this setting is false, Kibana uses the hostname of the host
    # that connects to this Kibana instance.
    #elasticsearch.preserveHost: true

    # Kibana uses an index in Elasticsearch to store saved searches, visualizations and
    # dashboards. Kibana creates a new index if the index doesn't already exist.
    #kibana.index: ".kibana"

    # The default application to load.
    #kibana.defaultAppId: "home"

    # If your Elasticsearch is protected with basic authentication, these settings provide
    # the username and password that the Kibana server uses to perform maintenance on the Kibana
    # index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
    # is proxied through the Kibana server.
    elasticsearch.username: "elastic"
    elasticsearch.password: "Yonyou123"

    # Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
    # These settings enable SSL for outgoing requests from the Kibana server to the browser.
    #server.ssl.enabled: false
    #server.ssl.certificate: /path/to/your/server.crt
    #server.ssl.key: /path/to/your/server.key

    # Optional settings that provide the paths to the PEM-format SSL certificate and key files.
    # These files are used to verify the identity of Kibana to Elasticsearch and are required when
    # xpack.security.http.ssl.client_authentication in Elasticsearch is set to required.
    #elasticsearch.ssl.certificate: /path/to/your/client.crt
    #elasticsearch.ssl.key: /path/to/your/client.key

    # Optional setting that enables you to specify a path to the PEM file for the certificate
    # authority for your Elasticsearch instance.
    #elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]

    # To disregard the validity of SSL certificates, change this setting's value to 'none'.
    #elasticsearch.ssl.verificationMode: full

    # Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of
    # the elasticsearch.requestTimeout setting.
    #elasticsearch.pingTimeout: 1500

    # Time in milliseconds to wait for responses from the back end or Elasticsearch. This value
    # must be a positive integer.
    #elasticsearch.requestTimeout: 30000

    # List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
    # headers, set this value to [] (an empty list).
    #elasticsearch.requestHeadersWhitelist: [ authorization ]

    # Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten
    # by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration.
    #elasticsearch.customHeaders: {}

    # Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
    #elasticsearch.shardTimeout: 30000

    # Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying.
    #elasticsearch.startupTimeout: 5000

    # Logs queries sent to Elasticsearch. Requires logging.verbose set to true.
    #elasticsearch.logQueries: false

    # Specifies the path where Kibana creates the process ID file.
    #pid.file: /var/run/kibana.pid

    # Enables you specify a file where Kibana stores log output.
    #logging.dest: stdout

    # Set the value of this setting to true to suppress all logging output.
    #logging.silent: false

    # Set the value of this setting to true to suppress all logging output other than error messages.
    #logging.quiet: false

    # Set the value of this setting to true to log all events, including system usage information
    # and all requests.
    #logging.verbose: false

    # Set the interval in milliseconds to sample system and process performance
    # metrics. Minimum is 100ms. Defaults to 5000.
    #ops.interval: 5000

    # Specifies locale to be used for all localizable strings, dates and number formats.
    # Supported languages are the following: English - en , by default , Chinese - zh-CN .
    #i18n.locale: "en"
kind: ConfigMap
metadata:
  creationTimestamp: "2022-01-10T07:56:34Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:a.conf: {}
        f:b.conf: {}
    manager: kubectl-create
    operation: Update
    time: "2022-01-10T07:56:34Z"
  name: cm-configfiles
  namespace: default
  resourceVersion: "11027034"
  selfLink: /api/v1/namespaces/default/configmaps/cm-configfiles
  uid: fac97ad8-961c-4707-9278-7891a8519b65

此时key的名字已经变为a.conf和b.conf

(2)通过--from-literal参数从文本中创建

[root@nccztsjb-node-11 ~]# kubectl create cm cm-literal --from-literal=key1=value1 --from-literal=key2=value2
configmap/cm-literal created

查看创建的configmap

[root@nccztsjb-node-11 ~]# kubectl get cm cm-literal -o yaml
apiVersion: v1
data:
  key1: value1
  key2: value2
kind: ConfigMap
metadata:
  creationTimestamp: "2022-01-10T08:02:34Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:key1: {}
        f:key2: {}
    manager: kubectl-create
    operation: Update
    time: "2022-01-10T08:02:34Z"
  name: cm-literal
  namespace: default
  resourceVersion: "11028274"
  selfLink: /api/v1/namespaces/default/configmaps/cm-literal
  uid: 7bfb4107-5466-4d65-bcdc-3ebcbb49dbd7

2、容器应用对configmap的使用方法

容器应用在使用configmap时有以下的2种方法:

  • 通过环境变量获取configmap的内容
  • 通过volume挂载的方式将configmap中的内容挂载为容器内部的文件或目录

2.1、通过环境变量的方式使用configmap

将前面创建的configmap cm-vars中的内容以env的方式设置为容器内部的环境变量,在pod的yaml配置文件中进行定义

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-pod
spec:
  containers:
  - name: cm-test
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    env:
      - name: APPLOGDEVEL
        valueFrom:
          configMapKeyRef:
            name: cm-vars
            key: apploglevel
      - name: APPDATADIR
        valueFrom:
          configMapKeyRef:
            name: cm-vars
            key: appdatadir
  restartPolicy: Never          
EOF

进行pod的创建

查看pod和pod内的环境变量:

[root@nccztsjb-node-11 ~]# kubectl get pod cm-test-pod
NAME          READY   STATUS    RESTARTS   AGE
cm-test-pod   1/1     Running   0          87s
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-pod -- bash -c "env | grep APP"
APPLOGDEVEL=info
APPDATADIR=/var/data
[root@nccztsjb-node-11 ~]#

变量已经在容器中进行了映射。

通过pod中envFrom定义,将configmap中所有的key-value生成为容器的环境变量:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-pod
spec:
  containers:
  - name: cm-test
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    envFrom:
    - configMapRef:
        name: cm-vars
  restartPolicy: Never          
EOF
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-pod -- bash -c "env |grep app"
apploglevel=info
appdatadir=/var/data
[root@nccztsjb-node-11 ~]# 

容器运行后,自动将configmap中的key-value声明为pod中的环境变量。

2.2、通过volume的方式使用configmap

将之前创建的cm-configfiles这个configmap以volume的方式挂载到pod中,并且映射为配置文件

在pod的配置文件中进行定义

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-app
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /configfiles
  volumes:
  - name: conf
    configMap:
      name: cm-configfiles
      items: 
      - key: nginx.conf
        path: nginx.conf  #挂载在容器后叫什么文件名
      - key: kibana.yml   
        path: kibana.yml
  restartPolicy: Never          
EOF

创建pod,查看pod中的配置文件

[root@nccztsjb-node-11 ~]# kubectl get pod cm-test-app
NAME          READY   STATUS    RESTARTS   AGE
cm-test-app   1/1     Running   0          44s
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-app -- bash -c "ls /configfiles"
kibana.yml  nginx.conf
[root@nccztsjb-node-11 ~]# 

发现configmap中的key已经被挂载到容器中,并且是以文件的形式存在的。

修改path 值,看效果

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-app
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /configfiles
  volumes:
  - name: conf
    configMap:
      name: cm-configfiles
      items: 
      - key: nginx.conf
        path: nginx2.conf  #挂载在容器后叫什么文件名
      - key: kibana.yml   
        path: kibana2.yml
  restartPolicy: Never          
EOF
[root@nccztsjb-node-11 ~]# kubectl get pod cm-test-app
NAME          READY   STATUS    RESTARTS   AGE
cm-test-app   1/1     Running   0          4s
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-app -- bash -c "ls /configfiles"
kibana2.yml  nginx2.conf
[root@nccztsjb-node-11 ~]# 

发现挂载之后的名字就是path中声明的文件的名字。

默认将configmap中的所有key都挂载到容器中的pod定义(不使用items)

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-app
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /configfiles
  volumes:
  - name: conf
    configMap:
      name: cm-configfiles
  restartPolicy: Never          
EOF
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-app -- bash -c "ls /configfiles"
kibana.yml  nginx.conf
[root@nccztsjb-node-11 ~]# 

自动将configmap中的所有的key都挂载到了容器中。

文件名就是configmap中的key的名称。

注意:以上都是将configmap挂载为容器中的目录,然后将configmap中的文件进行映射。如果容器中有该目录,那么就会被configmap覆盖。

2.3、将configmap的内容挂载为容器中的文件(文件覆盖)

比如,nginx容器中有/etc/nginx目录,如果直接将configmap挂载/etc/nginx,那么就会将容器中的/etc/nginx中原来的内容给覆盖,为了避免覆盖,并且将configmap中的文件正确的覆盖容器中的文件,比如nginx.conf需要使用volume-configmap的subpath参数

(1)创建以nginx.conf文件内容为主的configmap

[root@nccztsjb-node-11 ~]# kubectl create cm nginxconf --from-file=nginx.conf 
configmap/nginxconf created

(2)创建pod使用该configmap中的nginx.conf文件

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-nginx
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /etc/nginx/nginx.conf  # 容器中要覆盖的文件的名字,绝对路径
      subPath: nginx.conf               # 挂载到容器中的文件的名字
  volumes:
  - name: conf
    configMap:
      name: nginxconf
      items: 
      - key: nginx.conf
        path: nginx.conf
  restartPolicy: Never          
EOF

注意:这个时候,mountPath就要为挂载文件的全路径,然后subpath就是挂载之后文件的名字。subPath的名字必须和volumes中的path匹配。

备注:

  • mountPath: /etc/nginx/nginx.conf是挂载到容器中的具体的文件的名字
  • subPath: nginx.conf是volumes中的path,如果在volume中有这个path就挂载为文件,如果没有就是一个空目录

查看容器中的配置文件是否变化

[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-nginx -- bash
[cm-test-nginx root:~]# cd /etc
[cm-test-nginx root:/etc]# cd nginx/
[cm-test-nginx root:/etc/nginx]# ls
conf.d                fastcgi_params          koi-win             modules             scgi_params          uwsgi_params.default
fastcgi.conf          fastcgi_params.default  mime.types          nginx.conf          scgi_params.default  win-utf
fastcgi.conf.default  koi-utf                 mime.types.default  nginx.conf.default  uwsgi_params
[cm-test-nginx root:/etc/nginx]# cat nginx.conf
user  nginx;
worker_processes  auto;  #此处为修改的内容

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
[cm-test-nginx root:/etc/nginx]#

即nginx.conf文件已经发生变化,并且/etc/nginx目录中原来的内容还存在。

这样就是实现了通过configmap对容器中的配置文件进行覆盖的目的。

(3)更改mountPath的内容看效果

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-nginx
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /etc/nginx/nginx222.conf  # 容器中要覆盖的文件的名字,绝对路径
      subPath: nginx.conf               # 挂载到容器中的文件的名字
  volumes:
  - name: conf
    configMap:
      name: nginxconf
      items: 
      - key: nginx.conf
        path: nginx.conf
  restartPolicy: Never          
EOF
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-nginx -- bash
[cm-test-nginx root:~]# cd /etc
[cm-test-nginx root:/etc]# ls
TZ                    environment  inittab      modprobe.d      opt         protocols    shells            terminfo
alpine-release        fish         inputrc      modules         os-release  resolv.conf  ssh               timezone
apk                   fstab        issue        modules-load.d  pam.d       securetty    ssl               udhcpd.conf
ca-certificates       group        krb5.conf    motd            passwd      security     supervisor.d      vim
ca-certificates.conf  group-       ld.so.cache  mtab            passwd-     services     supervisor.user   wgetrc
conf.d                hostname     localtime    network         periodic    sftp.d       supervisord.conf
crontabs              hosts        login.defs   nginx           profile     shadow       sysctl.conf
default               init.d       logrotate.d  nsswitch.conf   profile.d   shadow-      sysctl.d
[cm-test-nginx root:/etc]# cd nginx/
[cm-test-nginx root:/etc/nginx]# ls
conf.d                fastcgi_params          koi-win             modules             nginx222.conf        uwsgi_params
fastcgi.conf          fastcgi_params.default  mime.types          nginx.conf          scgi_params          uwsgi_params.default
fastcgi.conf.default  koi-utf                 mime.types.default  nginx.conf.default  scgi_params.default  win-utf
[cm-test-nginx root:/etc/nginx]# cat nginx222.conf 
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
[cm-test-nginx root:/etc/nginx]# 

此时,容器中就挂载为nginx222.conf这个文件。

moutpath不变,更改subPath的值

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-nginx
spec:
  containers:
  - name: cm-app
    image: 172.20.45.174:81/base/nginx:1.15-alpine
    volumeMounts:
    - name: conf
      mountPath: /etc/nginx/nginx222.conf  # 容器中要覆盖的文件的名字,绝对路径
      subPath: nginx2conf               # 挂载到容器中的文件的名字
  volumes:
  - name: conf
    configMap:
      name: nginxconf
      items: 
      - key: nginx.conf
        path: nginx.conf
  restartPolicy: Never          
EOF
[root@nccztsjb-node-11 ~]# kubectl exec -it cm-test-nginx -- bash
[cm-test-nginx root:~]# cd /etc/nginx/
[cm-test-nginx root:/etc/nginx]# ls
conf.d                fastcgi_params          koi-win             modules             nginx222.conf        uwsgi_params
fastcgi.conf          fastcgi_params.default  mime.types          nginx.conf          scgi_params          uwsgi_params.default
fastcgi.conf.default  koi-utf                 mime.types.default  nginx.conf.default  scgi_params.default  win-utf
[cm-test-nginx root:/etc/nginx]# ls -ld nginx222.conf/
drwxrwxrwx 2 root root 4096 Jan 11 10:43 nginx222.conf/
[cm-test-nginx root:/etc/nginx]# ls -l nginx222.conf/
total 0
[cm-test-nginx root:/etc/nginx]# 

发现容器中就是挂载了一个目录nginx222.conf(mountpath中指定的名字),并且目录中没有任何的文件,即subpath无法和volumes中的path匹配时,挂载的就是一个目录和默认的volume是一样的。

所以,subPath存在且和volumes.path匹配,就是挂载文件,否则就是目录。

3、总结

对于configmap的创建,方式如下:

  • 命令行
    • --from-file
    • --from-literal
  • yaml定义文件

pod使用configmap的方式

  • 环境变量
  • volume挂载为容器内的配置文件

覆盖容器中的文件:使用subPath选项。

posted @ 2022-01-11 10:47  Zhai_David  阅读(1155)  评论(0编辑  收藏  举报