k8s配置ConfigMap

1 ConfigMap基本概念

1.1 什么是ConfigMap

ConfigMap是一种API对象,用来将非机密性的数据保存到键值对中。使用时,Pod可以将其用作环境变量、命令行参数或者存储卷中的配置文件。

ConfigMap将你的环境配置信息和容器镜像解耦,便于应用配置的修改。

1.2 ConfigMap应用场景

  1. 使用 k8s 部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap可以将配置信息和docker镜像解耦,以便实现镜像的可移植性和可复用性,因为一个configMap其实就是一系列配置信息的集合,可直接注入到Pod中给容器使用。configmap注入方式有两种,一种将configMap做为存储卷,一种是将configMap通过env中configMapKeyRef 注入到容器中。
  2. 使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配置的话,那么更新配置就很麻烦,使用configmap可以友好的进行配置共享。

k8s配置ConfigMap_redis

1.3 局限性

ConfigMap并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用Secret, 或者使用其他第三方工具来保证你的数据的私密性,而不是用ConfigMap。

ConfigMap在设计上不是用来保存大量数据的。在ConfigMap中保存的数据不可超过1 MiB。如果你需要保存超出此尺寸限制的数据,你可能希望考虑挂载存储卷 或者使用独立的数据库或者文件服务。

2 创建ConfigMap

2.1 基于命令创建CM

1、查看帮助命令

kubectl create configmap --help

k8s配置ConfigMap_Pod_02

2、使用kubectl create configmap命令使用--from-literal选项给出键值对来创建configmap

kubectl create cm nginx-config --from-literal=nginx.host='0.0.0.0' --from-literal=nginx.port='9999'

3、查看ConfigMap资源

k8s配置ConfigMap_redis_03

2.2 基于文件创建CM

通过指定文件创建一个configmap,--from-file=<文件>,默认文件名为key,文件内容为value。

1、创建配置文件

vim nginx.conf 
server {
  server_name www.nginx.com;
  listen 80;
  location / {
    root /usr/share/nginx/html;
    index index.html;
  }
  include /etc/nginx/conf.d/*.cfg;
}

#用于开启Nginx状态模块配置
vim nginx_status.cfg
location /nginx_status {
  stub_status;
  access_log off;
}

2、创建ConfigMap

kubectl create cm nginx-cm-file \

--from-file=nginx.conf \

--from-file=nginx_status=nginx_status.cfg

3、查看ConfigMap资源

k8s配置ConfigMap_nginx_04

2.3 基于目录创建CM

对于配置文件较多且无需自定义键名的场景,直接使用--from-file选项附加一个目录路径就能将该目录下的所有文件创建于同一个ConfigMap资源中,各文件名就是键名称。

1、创建ConfigMap

kubectl create cm nginx-cm-folder --from-file=/root/ConfigMap

2、查看ConfigMap资源

k8s配置ConfigMap_nginx_05

2.4 配置清单创建CM

apiVersion: v1
kind: ConfigMap
metadata:
  name:
  namespace:
data:
  # 类属性键;每一个键都映射到一个简单的值
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"
  # 类文件键
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
  nginx.conf: |
    server {
      server_name www.nginx.com;
      listen 80;
      location / {
        root /usr/share/nginx/html;
        index index.html;
      }
      include /etc/nginx/conf.d/*.cfg;
    }

3 Pod引用ConfigMap

3.1 通过环境变量引用CM键值

3.1.1 env引用变量示例

Pod清单中除了使用value字段直接给定变量之外,还支持valueFrom字段嵌套configMapKeyRef来引用ConfigMap对象的键值。

env:
- name: #要赋值的环境变量名称
  valueFrom: #定义变量的引用
    configMapKeyRef: #变量来自于ConfigMap对象
      name: #ConfigMap对象的名称(因为有很多configmap,需要指定具体的名称)
      key: #configmap的键名称

这种方式赋值环境变量与直接赋值环境变量方式并无区别,它们都可以用于容器的启动脚本或直接传递给容器应用等。

3.1.2 env引用变量实践

1、创建ConfigMap资源

vim nginx-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-cm
  namespace: default
data:
  nginx.host: "0.0.0.0"
  nginx.port: "8848"

k8s配置ConfigMap_Pod_06

2、创建Pod资源清单,通过env方式引用变量

vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    - "printenv"
    env:
    - name: NGINX_HOST
      valueFrom:
        configMapKeyRef:
          name: nginx-cm
          key: nginx.host
    - name: NGINX_PORT
      valueFrom:
        configMapKeyRef:
          name: nginx-cm
          key: nginx.port

被引用的ConfigMap资源必须事先存在,否则无法再Pod对象中引用ConfigMap资源,另外ConfigMap属于名称空间级别的资源,它必须与引用它的Pod资源在同一名称空间。

3、查看输出

k8s配置ConfigMap_nginx_07

3.2 通过卷挂载方式引用CM

使用环境变量方式导入ConfigMap对象中来源较长的文件内容,会导致占据过多的内存空间。而且以环境变量方式使用的ConfigMap数据不会被自动更新。更新这些数据需要重新启动Pod。

对于给容器提供配置文件类数据,直接通过挂载的方式进行引用,会是一种更好的选择。

要在一个Pod的存储卷中使用ConfigMap:

  1. 创建一个ConfigMap对象或者使用现有的ConfigMap对象。多个Pod可以引用同一个ConfigMap。
  2. 修改Pod定义,在spec.volumes[]下添加一个卷。 为该卷设置任意名称,之后将spec.volumes[].configMap.name字段设置为对你的ConfigMap对象的引用。
  3. 为每个需要该ConfigMap的容器添加一个.spec.containers[].volumeMounts[]。设置.spec.containers[].volumeMounts[].readOnly=true并将.spec.containers[].volumeMounts[].mountPath设置为一个未使用的目录名,ConfigMap内容将出现在该目录中。
  4. 更改你的镜像或者命令行,以便程序能够从该目录中查找文件。ConfigMap 中的每个data键会变成mountPath下面的一个文件名。

3.2.1 引用整个存储卷

1、配置pod资源清单

vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    - "ls -la /tmp/nginx"
    volumeMounts:
    - name: nginx-cm
      mountPath: /tmp/nginx
      readOnly: true
  volumes:
  - name: nginx-cm
    configMap:
      name: nginx-cm

2、查看输出

k8s配置ConfigMap_nginx_08

3.2.2 引用存储卷部分键值

有些应用场景,仅期望向容器中挂载指定的键,而不是所有的键。

1、配置pod资源清单

vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    - "ls -la /tmp/nginx"
    volumeMounts:
    - name: nginx-cm
      mountPath: /tmp/nginx
      readOnly: true
  volumes:
  - name: nginx-cm
    configMap:
      name: nginx-cm
      items:
      - key: nginx.host
        path: nginx.host.txt
        mode: 0600

2、查看输出

k8s配置ConfigMap_redis_09

3.2.3 引用存储卷单个键值

前两种方式,无论是装在ConfigMap对象中的所有文件还是部分文件,挂载点目录下原有的文件都会被隐藏。

对于期望将ConfigMap对象提供的配置文件补充在挂载点目录下的需求来说,这种方法难以实现,可以通过容器的volumeMounts字段subpath来解决。

1、配置Pod资源清单

vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-cm
      mountPath: /etc/nginx/conf.d/nginx.host.txt #挂载地址必须是具体的文件名,不能是目录
      subPath: nginx.host #ConfigMap的key
  volumes:
  - name: nginx-cm
    configMap:
      name: nginx-cm

2、查看结果

k8s配置ConfigMap_nginx_10

使用ConfigMap作为subPath卷挂载的容器将不会收到 ConfigMap 的更新。

3.2.4 ConfigMap热更新

当卷中使用的ConfigMap被更新时,所投射的键最终也会被更新。kubelet 组件会在每次周期性同步时检查所挂载的ConfigMap是否为最新。

Kubelet在每次定期同步时都会检查所挂载的ConfigMap是否是最新的。 然而,它使用其基于TTL机制的本地缓存来获取ConfigMap的当前值。因此,从ConfigMap更新到新键映射到Pod的总延迟可能与kubelet同步周期(默认为1分钟)+kubelet中ConfigMap缓存的TTL(默认为1分钟)一样长。 你可以通过更新Pod的一个注解来触发立即刷新。

1、编写Pod资源清单

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    env:
    - name: NGINX_HOST
      valueFrom:
        configMapKeyRef:
          name: nginx-cm
          key: nginx.host
    volumeMounts:
    - name: nginx-cm-v
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: nginx-cm-v
    configMap:
      name: nginx-cm

2、查看数据

k8s配置ConfigMap_redis_11

3、更改ConfigMap

kubectl edit cm nginx-cm

将nginx.host值更改

nginx.host: 1.1.1.1

4、查看数据

k8s配置ConfigMap_Pod_12

使用该ConfigMap挂载的Env不会同步更新

使用该ConfigMap挂载的Volume中的数据需要一段时间才能同步更新

4 Redis结合ConfigMap实践

4.1创建ConfigMap

1、资源清单

vim redis-cm.yaml
apiVersion:v1
kind:ConfigMap
metadata:
  name:redis-cm
  namespace:default
data:
  redis-config:|
    bind 0.0.0.0
    port 6666

k8s配置ConfigMap_nginx_13

4.2创建Redis-Pod

创建资源清单

apiVersion:v1
kind:Pod
metadata:
  name:redis
  namespace:default
spec:
  containers:
  - name:redis
    image:redis:latest
    imagePullPolicy:IfNotPresent
    command:
    - "redis-server"
    - "/redis/redis.conf"
    volumeMounts:
    - name:redis-cm-v
      mountPath:/redis/redis.conf
      subPath:redis-config
  volumes:
  - name:redis-cm-v
    configMap:
      name:redis-cm

4.3 查看结果

k8s配置ConfigMap_Pod_14

上一篇:【Java性能调优指南】Garbage First垃圾收集器10


下一篇:C 语言二维数组与二级指针的深度剖析