1. 程式人生 > 其它 >k8s中configmap的作用及使用方式

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選項。

如有任何疑問,歡迎討論! QQ:563727470 QQ群:304622338 用高質量的輸出,解答你的煩惱。 高質量問答網站:PKAB https://www.sqslt.cn