Loading

ConfigMap-k8s

ConfigMap 提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,也可以用来保存整个配置文件,比如我们可以用来配置一个redis服务的访问地址,也可以用来保存整个redis的配置文件

创建

ConfigMap 资源对象使用key-value形式的键值对来配置数据,这些数据可以在Pod里面使用,ConfigMap和我们后面要讲到的Secrets比较类似,一个比较大的区别是ConfigMap可以比较方便的处理一些非敏感的数据,比如密码之类的还是需要使用Secrets来进行管理

kind: ConfigMap
apiVersion: v1
metadata:
  name: cm-demo
  namespace: default
data:
  data.1: hello
  data.2: world
  config: |
    property.1=value-1
    property.2=value-2
    property.3=value-3
    
其中配置数据在data属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件
kubectl create -f xx.yaml来创建上面的ConfigMap对象
使用kubectl create configmap -h  查看关于创建ConfigMap的帮助信息

创建方式

创建ConfigMap的方式有4种:

1,通过直接在命令行中指定configmap参数创建,即--from-literal
2,通过指定文件创建,即将一个配置文件创建为一个ConfigMap--from-file=<文件>
3,通过指定目录创建,即将一个目录下的所有配置文件创建为一个ConfigMap,--from-file=<目录>
4,通过yaml文件来创建,另一种是通过kubectl直接在命令行下创建。
5,事先写好标准的configmap的yaml文件,然后kubectl create -f 创建

1,命令行创建


#注意:ConfigMap中的键名必须是一个合法的DNS域,仅包含数字字母、破折号、下画线以及圆点,首位的圆点符号是可选的。

kubectl create configmap test-config1 --from-literal=db.host=10.5.10.116 --from-literal=db.port='3306'

kubectl   get configmap  #查看创建的configmap

$ kubectl  get configmap test-config1 -o yaml   ##查看输出
apiVersion: v1
data:
  db.host: 10.5.10.116
  db.port: "3306"
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-12T01:10:10Z"
  name: test-config1
  namespace: default
  resourceVersion: "27115"
  selfLink: /api/v1/namespaces/default/configmaps/test-config1
  uid: 1c05bfd4-1c42-4469-b18d-06d40e62b8e9

2,指定文件创建

#文件
cat  tt.configmap 
property.1 = value-1
property.2 = value-2
property.3 = value-3

[mysqld]
port = 3309
socket = /home/ddjd/mysql.sock
pid-file= /sksk/slls/mysql.pid


kubectl create configmap test-config3  --from-file=./tt.configmap  ##创建时指定了名称
kubectl get  configmap   test-config3  -o yaml  ##查看,时间戳不一致(???)
kubectl   delete  configmap test-config3        ##删除

3,指定目录创建

ls  config/
ee.configmap  tt.configmap

kubectl create configmap test-config3 --from-file=./config ##创建

kubectl  get   configmap  test-config3   -o yaml 
apiVersion: v1
data:
  ee.configmap: |
    property.4 = value-1
    property.5 = value-2
    property.6 = value-3

    [mysqld]
    tt = xxkxk
    socket1 = /home/ddjd/mysql.sock
    pid-file1 = /sksk/slls/mysql.pid
  tt.configmap: |
    property.1 = value-1
    property.2 = value-2
    property.3 = value-3

    [mysqld]
    port = 3309
    socket = /home/ddjd/mysql.sock
    pid-file= /sksk/slls/mysql.pid
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-12T01:31:54Z"
  name: test-config3
  namespace: default
  resourceVersion: "28844"
  selfLink: /api/v1/namespaces/default/configmaps/test-config3
  uid: 3d63d4f2-d33d-4239-a05c-5d4effefdd36


指定目录创建时configmap内容中的各个文件会创建一个key/value对,key是文件名,value是文件内容。

如果config目录下还有子目录,创建configmap 时会忽略该子目录

yaml文件创建

 cat  test-config4.yaml
apiVersion: v1
kind: ConfigMap 
metadata: 
  name: test-config4
  namespace: default
data:
  cache_host: memcached-gcxt
  cache_port: "11211"
  cache_prefix: gcxt
  my.cnf: |
    [mysqld]
    log_bin = mysql-bin
    hahaha = heheh

kubectl create -f test-config4.yaml

configmap 的使用

使用ConfigMap有三种方式:

第一种是通过环境变量的方式,直接传递给pod
使用configmap中指定的key
使用configmap中所有的key
第二种是通过在pod的命令行下运行的方式(启动命令中)
第三种是作为volume的方式挂载到pod内

注意:
ConfigMap必须在Pod使用它之前创建
使用envFrom时,将会自动忽略无效的键
Pod只能使用同一个命名空间的ConfigMap

1,环境变量使用

使用valueFrom、configMapKeyRef、name、key指定要用的key:

#创建配置文件

  kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
  kubectl create configmap env-config --from-literal=log_level=INFO

使用配置文件

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never

查看pod内环境变量

kubectl  create  -f tt.yaml 

redhat@k8s-master:~/test$ kubectl  logs  test-pod 
SPECIAL_TYPE_KEY=charm
SPECIAL_LEVEL_KEY=very
log_level=INFO

总结:

envFrom: 是变量原样输出
env: 是重新定义了变量的名称,使用了某个 configmap里的某个key的value

2,用作命令行参数

将ConfigMap用作命令行参数时,需要先把ConfigMap的数据保存在环境变量中,然后通过$(VAR_NAME)的方式引用环境变量

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image:  busybox
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
  restartPolicy: Never

执行后查看

kubectl    logs  test-pod    
very charm

3,使用volume将ConfigMap作为文件或目录直接挂载

将创建的ConfigMap直接挂载至Pod的/etc/config目录下,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容 (大概会覆盖该目录下的所有文件)

#confgimap  
kubectl get   configmap  special-config  -o yaml
apiVersion: v1
data:
  special.how: very
  special.type: charm
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-12T02:07:36Z"
  name: special-config
  namespace: default
  resourceVersion: "31683"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: 28891c5f-f4e9-4666-9e2f-1682768c3479

#测试使用
 cat  tt.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "cat /etc/config/special.how"] 
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

##输出打印
kubectl  logs test-pod 
very

因为comfigmap 中的每个key 都会作为一个文件,内容为value ,所以可以将内容扩展为多行进行使用


# kubectl edit  configmap  special-config 
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  special.how: |
    xxx = sgkdjgk.pid 
    yy = dgkjak.jfkdj 
    djkjg = dgkdjgk
  special.type: charm
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-12T02:07:36Z"
  name: special-config
  namespace: default
  resourceVersion: "34115"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: 28891c5f-f4e9-4666-9e2f-1682768c3479

# kubectl get   configmap  special-config  -o yaml
apiVersion: v1
data:
  special.how: "xxx = sgkdjgk.pid \nyy = dgkjak.jfkdj\ndjkjg = dgkdjgk\n"
  special.type: charm
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-12T02:07:36Z"
  name: special-config
  namespace: default
  resourceVersion: "34115"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: 28891c5f-f4e9-4666-9e2f-1682768c3479


#使用挂载方式
cat  tt.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "cat /etc/config/special.how"] 
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

#执行后打印kubectl logs  test-pod 
xxx = sgkdjgk.pid 
yy = dgkjak.jfkdj
djkjg = dgkdjgk


##挂载到容器的key 为链接文件

假如不想以key名作为配置文件名可以引入items 字段,在其中逐个指定要用相对路径path替换的key:

    volumes:
      - name: config-volume4
        configMap:
          name: test-config4
          items:
          - key: my.cnf
            path: mysql-key
          - key: cache_host
            path: cache-host

##挂载到容器的key 为链接文件

备注:
删除configmap后原pod不受影响;然后再删除pod后,重启的pod的events会报找不到cofigmap的volume;
pod起来后再通过kubectl edit configmap …修改configmap,过一会pod内部的配置也会刷新。
在容器内部修改挂进去的配置文件后,过一会内容会再次被刷新为原始configmap内容

将创建的ConfigMap中special.how这个key挂载到/etc/config目录下的一个相对路径/keys/special.level。如果存在同名文件,直接覆盖。其他的key不挂载

cat  tt.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "cat /etc/config/keys/special.level"] 
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.how
          path: keys/special.level
  restartPolicy: Never

总结:
容器的挂载只决定路径,卷的定义里指定具体 某个key 即文件的具体挂载路径

在一般情况下 configmap 挂载文件时,会先覆盖掉挂载目录,然后再将congfigmap中的内容作为文件挂载进行。如不对原来的文件夹下的文件覆盖
只是将 configmap 中的每个key,按照文件的方式挂载到目录下, 使用 subpath 参数

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      command: ["/bin/sh","-c","sleep 36000"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/nginx/special.how
        subPath: special.how
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.how
          path: special.how
  restartPolicy: Never

一个configMap里文件挂载到容器的不同路径案例:

[root@k8s-m1 templates]# cat testnode.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: testmap
data:
  test.file: |
    user  www;
    worker_processes auto;
    worker_cpu_affinity auto;
    worker_rlimit_nofile 327680;
    events {
    worker_connections  65535;
    use epoll;
    }   
    http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format main '$remote_addr\t$msec\t$server_protocol';
    access_log  /data/logs/nginx/access.log  main;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    
    server {
        listen 80 default backlog=65535;
        server_name localhost;
 
        access_log  /data/logs/nginx/livesports.access.log  main;
        root /data/ifengsite/htdocs/livesports/02src/live/wwwroot;
        index index.html index.htm index.php;
 
        location ~* \.php$ {    
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include fastcgi.conf;
        }
    }
    }
  test.file2: |
    this is the 2nd strings
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-test
spec:
  containers:
  - name: test
    image: busybox
    tty: true
    command: ["sh"]
    volumeMounts:
    - name: testdir
      mountPath: /etc/nginx.conf
      subPath: nginx.conf
    - name: testdir
      mountPath: /etc/test.map2
      subPath: test.map2
  volumes:
  - name: testdir
    configMap:
      name: testmap
      items:
      - key: test.file
        path: nginx.conf
      - key: test.file2
        path: test.map2

##进入pod查看内目录结构

注意:挂载到指定目录时需要指定路径,路径名为configmap的给定的key ,这里为special.how,如果不指定则容器无法正常生成。
备注:
删除configmap后原pod不受影响;然后再删除pod后,重启的pod的events会报找不到cofigmap的volume。
pod起来后再通过kubectl edit configmap …修改configmap,pod内部的配置也会自动刷新。
在容器内部修改挂进去的配置文件后,内容可以持久保存,除非杀掉再重启pod才会刷回原始configmap的内容。
subPath必须要与configmap中的key同名。
mountPath如/tmp/prefix:
<1>当/tmp/prefix不存在时(备注:此时/tmp/prefix和/tmp/prefix/无异),会自动创建prefix文件并把value写进去;
<2>当/tmp/prefix存在且是个文件时,里面内容会被configmap覆盖;
<3>当/tmp/prefix存在且是文件夹时,无论写/tmp/prefix还是/tmp/prefix/都会报错

configmap的热更新

更新 ConfigMap 后
使用该 ConfigMap 挂载的 Env 不会同步更新
使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新
ENV 是在容器启动的时候注入的,启动之后 kubernetes 就不会再改变环境变量的值,且同一个 namespace 中的 pod 的环境变量是不断累加的,参考 Kubernetes中的服务发现与docker容器间的环境变量传递源码探究。为了更新容器中使用 ConfigMap 挂载的配置,可以通过滚动更新 pod 的方式来强制重新挂载 ConfigMap,也可以在更新了 ConfigMap 后,先将副本数设置为 0,然后再扩容.

configmap 问题

1,子目录挂载

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: app
      imagePullPolicy: Never
      volumeMounts:
      - name: appconfig
        mountPath: //xxxx/application.yml  ##此处有改动
        subPath: application.yml
  volumes:
    - name: appconfig
      configMap:
        name: insight-application
        items:
          - key: app-application.yml
            path: application.yml
  restartPolicy: Never

#注意:
挂载时卷的items path路径需要和容器中volumeMounts 的mountPath和subPath 保持一致。

测试yaml

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      command: ["/bin/sh","-c","sleep 36000"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/nginx/
        subPath: special.how
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.how
          path: special.how
  restartPolicy: Never

posted @ 2019-11-12 11:08  Lust4Life  阅读(978)  评论(0编辑  收藏  举报