ConfigMap用法详解

文章目录

  • ConfigMap概念
  • 创建ConfigMap
    • 1. 通过YAML配置文件方式创建
    • 2. 通过kubectl命令行方式创建
  • 使用ConfigMap
    • 1. 通过环境变量方式使用ConfigMap
    • 2. 通过VolumeMount使用ConfigMap
  • 使用ConfigMap的限制条件

ConfigMap概念

在生产环境中经常会遇到需要修改配置文件的情况,传统的修改方式不仅会影响到服务的正常运行,而且操作步骤也很繁琐。为了解决这个问题,kubernetes项目从1.2版本引入了ConfigMap功能,用于将应用的配置信息与程序的分离。这种方式不仅可以实现应用程序被的复用,而且还可以通过不同的配置实现更灵活的功能。在创建容器时,用户可以将应用程序打包为容器镜像后,通过环境变量或者外接挂载文件的方式进行配置注入。
ConfigMap是以key:value的形式保存配置项,既可以用于表示一个变量的值(例如config=info),也可以用于表示一个完整配置文件的内容(例如server.xml=…)。ConfigMap在容器使用的典型用法如下。

 将配置项设置为容器内的环境变量。
 将启动参数设置为环境变量。
 以Volume的形式挂载到容器内部的文件或目录。

创建ConfigMap

系统中可以通过YAML配置文件或者直接使用kubectl create configmap命令行的方式来创建ConfigMap,下面将详细介绍这两种方式的操作流程。

1. 通过YAML配置文件方式创建

创建YAML文件appvar.yaml,其中描述将应用所需的变量定义为ConfigMap的用法(注意加粗部分),key为配置文件的别名,value表示是配置文件的全部文本内容。

[root@master ~]# vim appvar.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: appvar
data:
  apploglevel: info
  appdatadir: /var/data

执行kubectl create命令创建ConfigMap,并使用相关命令查看创建好的Config,命令操作如下所示。
使用YAML文件创建ConfigMap。

[root@master ~]# kubectl create -f appvar.yml 
configmap/appvar created
 [root@master ~]# kubectl get configmap
NAME         DATA   AGE
appvar  2      17s

使用describe命令查看ConfigMap详细信息。

[root@master ~]# kubectl describe configmap appvar
Name:         appvar
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
appdatadir:
----
/var/data
apploglevel:
----
info
Events:  <none>
以YAMl格式查看ConfigMap。

[root@master ~]# kubectl get configmap appvar -o yaml
apiVersion: v1
data:
  appdatadir: /var/data
  apploglevel: info
kind: ConfigMap
metadata:
  creationTimestamp: "2019-10-24T05:28:24Z"
  name: appvar
  namespace: default
  resourceVersion: "1179869"
  selfLink: /api/v1/namespaces/default/configmaps/appvar
  uid: 19d2ddf0-f61f-11e9-9023-000c29fb2a34
  
从上面命令的执行结果可以看出变量被成功创建。

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

在kubectl create configmap命令种使用参数–from-file或–from-literal指定文件、目录或者文本,也可以创建一个或者多个ConfigMap参数。
(1)指定文件,语句格式如下:

Kubectl create connfigmap NAME --from-file=[key= ] source --from-file=[key= ] source

(2)指定目录,语句格式如下:
需要注意,目录中的每个配置文件名都被会被设置为key,文件中的内容将被设置为value,语法为:

Kubectl create connfigmap NAME --from-file=config-files-dir

(3)指定文本,语句格式如下:
此方式将直接指定key:value,语法为:

Kubectl create connfigmap NAME --from-literal=key1=value1  --from-literal=key2=value2

读者可以结合以下实例,更好的理解ConfigMap语句的用法。
在当前目录下创建ConfigMap文件server.xml,使用改文件创建一个ConfigMap。具体操作如下所示。

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

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

Data
====
server.xml:
----
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-server.xml
  namespace: default
data:

Events:  <none>

在configs目录下包含两个配置文件server.xml和log.xml,使用该目录创建一个包含这两个文件内容的ConfigMap,指令操作如下所示。

[root@master ~]# kubectl create configmap cm-dir --from-file=configs
configmap/cm-dir created

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

Data
====
log.xml:
----
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-log.xml
  namespace: default
data:

server.xml:
----
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-server.xml
  namespace: default
data:

Events:  <none>

在命令行中使用–from-literal参数进行创建ConfigMap的相关操作指令如下所示。

[root@master ~]# kubectl create configmap cm-text --from-literal=var=/tmp/config --from-literal=log=info
configmap/cm-text created

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

Data
====
var:
----
/tmp/config
log:
----
info
Events:  <none>

使用ConfigMap

在Kubernetes中创建好ConfigMap后,容器可以通过以下两种方法使用ConfigMap中的参数内容。
(1)通过环境变量的方式获取ConfigMap中的内容。
(2)通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录。
下面将对这两种使用方式进行详细的介绍。

1. 通过环境变量方式使用ConfigMap

以创建的ConfigMap“appvar.yaml”为例:

[root@master ~]# vim appvar.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: appvar
data:
  apploglevel: info
  appdatadir: /var/data

创建Pod,以便于使用ConfitgMap中的内容,指令操作如下所示。

apiVersion: v1
kind: Pod
metadata:
  name: pod-test
spec:
  containers:
  - name: test
    image: busybox
    command: [ "/bin/sh", "-c", "env | grep APP" ]
    env:
    - name: APPLOG                             //定义环境变量APPLOG
      valueFrom: 
        configMapkeyRef:
          name: appvar                          //指定config
          key: apploglevel                     //指定config中的key
    - name: APPDIR                             //定义环境变量APPDIR
      valueFrom:
        configMapkeyRef:
          name: appvar
          key: appdatadir
  restartPolicy: Never

在上面Pod代码的定义中,将ConfigMap“appvar”中定义的内容以环境变量(APPLOGLEVEL和APPDATADIR)方式设置为容器内部的环境变量,在容器的启动命令中将会显示这两个环境变量的值(“env | grep APP”)。
使用kubectl create -f命令创建该Pod,由于是测试Pod,所以该Pod在执行完启动命令后将会退出,并且不会被系统自动重启(restartPolicy=Never)。

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

使用kubectl get pods命令查看创建的Pod,指令操作如下所示。

[root@master ~]# kubectl get pods 
NAME              READY   STATUS         RESTARTS   AGE
cm-test-pod       0/1     Completed      0          4d
dapi-test-pod     0/1     ErrImagePull   0          3d22h
pod-test          0/1     Completed      0          75s
volume-test-pod   0/1     Completed      0          3d21h

查看该Pod的日志,可以看到启动命令“env | grep APP”的执行结果如下所示。

[root@master ~]# kubectl logs pod-test
APPDIR=/var/data
APPLOG=info

根据以上代码的执行结果,可以看出容器内部的环境变量使用ConfigMap cm-appvar中的值进行了正确设置。
Kubernetes在1.6版本引入新字段envFrom,可以实现在Pod环境中将ConfigMap中所有定义的key=value自动生成为环境变量,代码格式如下所示。

apiVersion: v1
kind: Pod
metadata:
  name: pod-test
spec:
  containers:
    - name: test
      image: busybox
      command: [ "/bin/sh", "-c", "env|grep APP" ]
      envfrom:
      - configMapRef:
        name: cm-appvar
  restartPolicy: Never

主要注意的是,环境变量的名称受POSIX命名规范约束,不能以数字开头。如果配置中包含非法字符,系统将会跳过该条环境变量的创建,并记录一个Event用来提醒用户环境变量无法生成,但并不阻止Pod的启动。

2. 通过VolumeMount使用ConfigMap

为了可以使读者更好的对比学习,这里同样使用“cm-apache.yaml”文件。

[root@master ~]# vim cm-apache.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-apache
data:
  html: hello world
  path: /var/www/html

创建YAML文件“pod-volume-test.yaml”,并在配置中加入Volume信息,代码如下所示。

apiVersion: v1
kind: Pod
metadata:
  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

创建该Pod,指令如下所示。

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

查看创建好的Pod是否正常运行,指令如下所示。

[root@master ~]# kubectl get pods
NAME              READY   STATUS             RESTARTS   AGE
cm-test-pod       0/1     Completed          0          4d2h
dapi-test-pod     0/1     ImagePullBackOff   0          4d
pod-test          0/1     Completed          0          116m
pod-volume-test   1/1     Running            0          36s
volume-test-pod   0/1     Completed          0          3d23h
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

使用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命令)应用所用的实际配置目录下。

你可能感兴趣的:(Kubernetes)