应用部署的一个最佳实践是将应用所需的配置信息与程序分离,这样可以是应用程序被更好地复用,通过不同的配置也能实现更灵活的功能。将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,但在大规模容器集群的环境中,对多个容器进行不同的配置将变得非常复杂,在k8s 1.2版本开始提供了一种统一的应用配置方案-----ConfigMap。
下面讲解ConfigMap的概念和用法:

一. ConfigMap概述
ConfigMap 供容器使用的用法如下:
(1)生成容器内的环境变量。
(2)设置容器启动命令的启动参数(需设置为环境变量)。
(3)以Volume 的形式挂载为容器内部的文件或目录。

二.创建ConfigMap资源对象

1.通过YAML 文件方式创建

文件: cm-appvars.yaml

apiVersion: v1
kind: ConfigMap
metadata: 
  name: cm-appvars
data: 
  apploglevel: info
  appdatadir: /var/data
  
#运行kubectl create命令创建该ConfigMap:
[root@k8s-master ~]# kubectl create -f cm-appvars.yaml 
configmap/cm-appvars created
#查看创建好的ConfigMap:
[root@k8s-master ~]# kubectl get configmap
NAME               DATA   AGE
cm-appvars         2      15s
kube-root-ca.crt   1      26d

[root@k8s-master ~]# kubectl describe configmap cm-appvars
Name:         cm-appvars
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
appdatadir:
----
/var/data
apploglevel:
----
info

BinaryData
====

Events:  <none>

[root@k8s-master ~]# kubectl get configmap cm-appvars -o yaml
apiVersion: v1
data:
  appdatadir: /var/data
  apploglevel: info
kind: ConfigMap
metadata:
  creationTimestamp: "2022-02-17T13:24:27Z"
  name: cm-appvars
  namespace: default
  resourceVersion: "117934"
  uid: 7686c97d-219b-479b-9cee-1a8eb15ccde7

2.通过kubectl 命令行方式创建

不使用YAML 文件,直接通过 kubectl create configmap 也可以创建ConfigMap,可以使用参数–from-file 或 --from-literal 指定内容,并且可以在一行中指定多个参数。
(1)通过–from-file 参数从文件进行创建,可以指定key 的名称,也可以在一个命令行创建包含多个key 的ConfigMap,语法如下:

 # kubectl create configmap NAME --from-file=[key=]source --from-file=[key=]source

(2)通过–from-file 参数在目录下进行创建,该目录下的每个配置文件名都被设置为key,文件的内容被设置为value,语法如下:

# kubectl create configmap NAME --from-file=config-files-dir

(3)使用–from-literal 时会从文本中进行创建,直接将指定的key#=value#创建为ConfigMap 的内容,语法如下:

# kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2

下面对这几种用法举例说明:
例如,在当前目录下含有配置文件server.xml,可以创建一个包含该文件内容的ConfigMap:

#当前目录下的server.xml 文件内容。我随意定义的
# 内容只有一个xml 头 
# 内容:<?xml version='1.0' encoding='utf-8'?>

[root@k8s-master k8s]# kubectl create configmap cm-server.xml --from-file=./server.yaml
configmap/cm-server.xml created

[root@k8s-master k8s]# kubectl  describe configmap cm-server.xml
Name:         cm-server.xml
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
server.yaml:
----
<?xml version='1.0' encoding='utf-8'?>



BinaryData
====

Events:  <none>

使用–from-literal 参数进行创建的示例如下:

[root@k8s-master k8s]# kubectl  create configmap cm-appenv --from-literal=loglevel=info --from-literal=appdatadir=/var/data
configmap/cm-appenv created

[root@k8s-master k8s]# kubectl describe configmap cm-appenv
Name:         cm-appenv
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
appdatadir:
----
/var/data
loglevel:
----
info

BinaryData
====

Events:  <none>

容器应用对ConfigMap 的使用有以下两种方法:
(1) 通过环境变量获取ConfigMap 中的内容。
(2)通过Volume 挂载的方式将ConfigMap 中的内容挂载为容器内部的文件或目录

三. 在Pod 中使用ConfigMap

1 . 通过环境变量方式使用ConfigMap
以前面创建的ConfigMap “cm-appvars” 为例:

apiVersion: v1
kind: ConfigMap
metadata: 
  name: cm-appvars
data: 
  apploglevel: info
  appdatadir: /var/data

在Pod “cm-test-pod” 的定义中,将ConfigMap “cm-appvars” 中的内容以环境变量(APPLOGLEVEL 和 APPDATADIR) 方式设置为容器内部的环境变量,容器的启动命令将显示着两个环境变量的值(“env | grep APP”):

apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-pod
spec: 
  containers: 
  - name: cm-test
    image: busbox
    command: ["/bin/sh","-c","env | grep APP"]
    env: 
    - name: APPLOGLEVEL  #定义环境变量的名称
      valueFrom:  #key "apploglevel" 对应的值
        configMapKeyRef: 
          name: cm-appvars #环境变量的值取自cm-appvars
          key: apploglevel #key 为apploglevel
    - name: APPDATADIR    #定义环境变量的名称
      valueFrom:  #key "appdatadir" 对应的值
        configMapKeyRef: 
          name: cm-appvars #环境变量的值取自cm-appvars
          key: appdatadir #key 为appdatadir
  restartPolicy: Never
      

运行kubectl create -f 命令创建该Pod,由于是测试Pod ,所以该Pod 在运行完启动命令后将会退出,并且不会被系统自动重启(restartPolicy=Never):

[root@k8s-master ~]# kubectl create -f cm-test-pod.yaml 
pod/cm-test-pod created

运行kubectl get pods

[root@k8s-master ~]# kubectl get pods 
NAME                                READY   STATUS      RESTARTS       AGE
cm-test-pod                         0/1     Completed   0              36s

查看该Pod 的日志,可以看到启动命令env | grep APP 的运行结果如下:

[root@k8s-master ~]# kubectl logs cm-test-pod
APPDATADIR=/var/data
APPLOGLEVEL=info

着说明容器内部的环境变量使用ConfigMap cm-appvars 中的值进行了正确的设置

k8s 从1.6 版本开始引入了一个新的字段 envFrom, 实现了在Pod 环境中将ConfigMap (可用于Secret 资源对象)中所有定义的key=value自动生成为环境变量:

apiVersion: v1
kind: Pod
metadata: 
  name: cm-test-pod
spec: 
  containers: 
  - name: cm-test
    image: busbox
    command: ["/bin/sh","-c","env"]
    envFrom: 
    - configMapRef: 
       name: cm-appvars #根据cm-appvars 中的key=value 自动生成环境变量
  restartPolicy: Never

通过这个定义,在容器内部将会生成如下环境变量:

 apploglevel=info
 appdatadir=/var/data

案例讲解到此,还有可通过volumMount 使用ConfigMap,此处不讲,有想了解的可以自行百度一下。

四. 使用ConfigMap 的限制条件

  1. ConfigMap 必须在Pod之前创建,Pod才能应用它。
  2. 如果Pod使用envFrom基于ConfigMap定义环境变量,则无效的环境变量名称(例如名称以数字开头)将被忽略,并在事件中被记录为InvalidVariableNames。
  3. ConfigMap 受命命名空间限制,只有处于相同的命名空间中的Pod才可以引用它。
  4. ConfigMap 无法用于静态Pod。
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐