目录

什么是ConfigMap

ConfigMap能够解决哪些问题

ConfigMap应用场景

ConfigMap局限性

ConfigMap的创建方法

命令行直接创建

通过文件创建

指定目录创建

通过yaml文件创建

ConfigMap应用

通过环境变量引入

使用configMapKeyRef

使用envfrom

通过Volume挂载使用

ConfigMap热更新


什么是ConfigMap

        Configmap 是 k8s 中的资源对象,用于保存非机密性的配置的,数据可以用 key/value键值对的形式保存,也可通过文件的形式保存。

ConfigMap能够解决哪些问题

        我们在部署服务的时候,每个服务都有自己的配置文件,如果一台服务器上部署多个服务:nginx、tomcat、apache 等,那么这些配置都存在这个节点上,假如一台服务器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署多个服务:nginx、tomcat、apache,新增加的服务器上还是要管理这些服务的配置,如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改,这种方式肯定满足不了线上大批量的配置变更要求。 所以,k8s 中引入了 Configmap资源对象,可以当成 volume 挂载到 pod 中,实现统一的配置管理。

        Configmap 是 k8s 中的资源, 相当于配置文件,可以有一个或者多个 Configmap

        Configmap 可以做成 Volume,k8s pod 启动之后,通过 volume 形式映射到容器内部指定目录上

        容器中应用程序按照原有方式读取容器特定目录上的配置文件

        在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。

ConfigMap应用场景

        使用 k8s 部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap 可以将配置信息和 docker 镜像解耦,以便实现镜像的可移植性和可复用性,因为一个 configMap 其实就是一系列配置信息的集合,可直接注入到 Pod 中给容器使用。configmap 注入方式有两种,一种将 configMap 做为存储卷,一种是将configMap 通过 env 中 configMapKeyRef 注入到容器中。

        使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配置的话,那么更新配置就很麻烦,使用 configmap 可以友好的进行配置共享。

ConfigMap局限性

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

ConfigMap的创建方法

命令行直接创建

# 创建一个叫tomcat-config的configmap
# 通过--from-literal 指定参数
[root@master ~]# kubectl create configmap tomcat-config --from-literal=tomcat_port=8080 --from-literal=server_name=myapp.tomcat.com
configmap/tomcat-config created

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

Data
====
server_name:
----
myapp.tomcat.com
tomcat_port:
----
8080

BinaryData
====

Events:  <none>

通过文件创建

# 准备配置文件
cat > nginx.conf << EOF
server {
    server_name www.nginx.com;
    listen 80;
    root /usr/share/nginx/html;
}
EOF

# 创建一个叫www-nginx的configmap
# --from-file指定从文件中读取,设置www的内容为nginx.conf里面的内容
[root@master ~]# kubectl create configmap www-nginx --from-file=www=nginx.conf 
configmap/www-nginx created
[root@master ~]# kubectl describe configmap www-nginx
Name:         www-nginx
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
www:
----
server {
    server_name www.nginx.com;
    listen 80;
    root /usr/share/nginx/html;
}


BinaryData
====

Events:  <none>

指定目录创建

# 准备一个目录,以及目录里面的配置文件
mkdir test-a
cat > test-a/my-server.cnf << EOF
server-id=1
EOF
cat > test-a/my-slave.cnf << EOF
server-id=2
EOF

# 创建一个叫mysql-config的configmap
# --from-file从指定的目录里面加载配置文件
[root@master ~]# kubectl create configmap mysql-config --from-file=test-a/
configmap/mysql-config created
[root@master ~]# kubectl describe configmap mysql-config
Name:         mysql-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
my-server.cnf:
----
server-id=1

my-slave.cnf:
----
server-id=2


BinaryData
====

Events:  <none>

通过yaml文件创建

# 定义一个叫mysql的configmap
[root@master ~]# cat mysql_configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    server-id=1
    log-bin
    log_bin_trust_function_creators=1
  slave.cnf: |
    [mysqld]
    server-id=2
    log-bin
    log_bin_trust_function_creators=1
[root@master ~]# kubectl apply -f mysql_configmap.yaml 
configmap/mysql created

# 查看mysql这个configmap的内容
[root@master ~]# kubectl describe configmap mysql
Name:         mysql
Namespace:    default
Labels:       app=mysql
Annotations:  <none>

Data
====
slave.cnf:
----
[mysqld]
server-id=2
log-bin
log_bin_trust_function_creators=1

master.cnf:
----
[mysqld]
server-id=1
log-bin
log_bin_trust_function_creators=1


BinaryData
====

Events:  <none>

ConfigMap应用

通过环境变量引入

使用configMapKeyRef

        该yaml文件创建一个叫mysql的configmap,同时也创建了一个pod来使用configmap。

        这里面使用env环境变量的方式进行引入,name指定了key,valueFrom表示数据的来源,这里面使用configMapKeyRef这种方式,该配置需要指定name以及key两个参数,name就写configmap的名字,key就写configmap里面的key。

[root@master ~]# cat configmap_cmkr.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    server-id=1
    log-bin
    log_bin_trust_function_creators=1
  slave.cnf: |
    [mysqld]
    server-id=2
    log-bin
    log_bin_trust_function_creators=1
    
---
apiVersion: v1 
kind: Pod 
metadata: 
  name: mysql-pod 
spec: 
  containers: 
  - name: mysql 
    image: busybox 
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ] 
    env:
    - name: mysql_master
      valueFrom:
        configMapKeyRef: 
          name: mysql
          key: "master.cnf"
    - name: mysql_slave
      valueFrom:
        configMapKeyRef: 
          name: mysql
          key: "slave.cnf"
[root@master ~]# kubectl apply -f configmap_cmkr.yaml 
configmap/mysql created
pod/mysql-pod created

# 可以登录到pod里面使用echo把变量打印出来
[root@master ~]# kubectl exec -it mysql-pod -- sh
/ # echo $mysql_master
[mysqld] server-id=1 log-bin log_bin_trust_function_creators=1
/ # echo $mysql_slave
[mysqld] server-id=2 log-bin log_bin_trust_function_creators=1

# 也是直接使用env查看
[root@master ~]# kubectl exec -it mysql-pod -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=mysql-pod
TERM=xterm
mysql_slave=[mysqld]
server-id=2
log-bin
log_bin_trust_function_creators=1

mysql_master=[mysqld]
server-id=1
log-bin
log_bin_trust_function_creators=1

KUBERNETES_PORT=tcp://10.1.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.1.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.1.0.1
KUBERNETES_SERVICE_HOST=10.1.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
HOME=/root

使用envfrom

该yaml文件创建一个叫mysql的configmap,同时也创建了一个pod来使用configmap。

[root@master ~]# cat configmap_ef.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master_cnf: |
    [mysqld]
    server-id=1
    log-bin
    log_bin_trust_function_creators=1
  slave_cnf: |
    [mysqld]
    server-id=2
    log-bin
    log_bin_trust_function_creators=1
    
---
apiVersion: v1 
kind: Pod 
metadata: 
  name: mysql-pod 
spec: 
  containers: 
  - name: mysql 
    image: busybox 
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ] 
    envFrom:
    - configMapRef:
        name: mysql   # 指定 configmap 的名字

[root@master ~]# kubectl apply -f configmap_ef.yaml 
configmap/mysql created
pod/mysql-pod created

# 查看pod里面configmap已经生效
[root@master ~]# kubectl exec -it mysql-pod -- sh
/ # echo $master_cnf
[mysqld] server-id=1 log-bin log_bin_trust_function_creators=1
/ # echo $slave_cnf
[mysqld] server-id=2 log-bin log_bin_trust_function_creators=1

通过Volume挂载使用

        可以把ConfigMap做成Volume挂载到Pod里面,该yaml文件创建了一个叫mysql的ConfigMap以及一个Pod。该Pod使用volumes挂载ConfigMap

[root@master ~]# cat configmap_v.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    server-id=1
    log-bin
    log_bin_trust_function_creators=1
  slave.cnf: |
    [mysqld]
    server-id=2
    log-bin
    log_bin_trust_function_creators=1
    
---
apiVersion: v1 
kind: Pod 
metadata: 
  name: mysql-pod 
spec: 
  containers: 
  - name: mysql 
    image: busybox 
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ] 
    volumeMounts:
    - name: mysql-config
      mountPath: /opt
  volumes:
  - name: mysql-config
    configMap:
      name: mysql
[root@master ~]# kubectl apply -f configmap_v.yaml 
configmap/mysql created
pod/mysql-pod created

[root@master ~]# kubectl exec -it mysql-pod -- ls /opt
master.cnf  slave.cnf
[root@master ~]# kubectl exec -it mysql-pod -- cat /opt/master.cnf
[mysqld]
server-id=1
log-bin
log_bin_trust_function_creators=1
[root@master ~]# kubectl exec -it mysql-pod -- cat /opt/slave.cnf
[mysqld]
server-id=2
log-bin
log_bin_trust_function_creators=1
[root@master ~]#

ConfigMap热更新

        在Kubernetes(K8S)中,ConfigMap是一种用于存储非机密配置数据的资源对象。ConfigMap可以包含键值对、INI格式的文件、JSON格式的文件等。ConfigMap的热更新指的是在应用程序运行时对ConfigMap进行修改,而无需重启应用程序即可应用这些变更。

ConfigMap的热更新对于动态配置和应用程序的灵活性非常重要,具体作用如下:

动态配置更新: 通过使用ConfigMap,您可以将应用程序的配置与应用程序本身分离。当配置更改时,可以直接更新ConfigMap而不需要重新构建或重启应用程序。这允许您实现动态配置更新,即在不停止服务的情况下应用新的配置。

无需重新部署: 通过热更新ConfigMap,您可以避免重新部署整个应用程序。这对于在生产环境中保持高可用性和最小化服务中断非常有用。应用程序可以检测到ConfigMap的更改并相应地调整其行为。

灵活性和快速响应: 通过将配置信息存储在ConfigMap中并实现热更新,您可以更灵活地调整应用程序的行为,而无需等待完整的重新部署周期。这有助于快速响应变化和调整应用程序的配置。

集中管理配置: ConfigMap允许您集中管理应用程序的配置信息,而不必将其硬编码到应用程序代码中。这使得配置更易于维护和管理,同时提供了一个单一的入口点来修改配置。

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

使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。

[root@master ~]# kubectl exec -it mysql-pod -- cat /opt/master.cnf
[mysqld]
server-id=1
log-bin
log_bin_trust_function_creators=1

# 使用edit修改mysql这个ConfigMap的内容
[root@master ~]# kubectl edit cm mysql 
configmap/mysql edited

# 大约10秒左右配置就应用上了
[root@master ~]# kubectl exec -it mysql-pod -- cat /opt/master.cnf
[mysqld]
server-id=10
log-bin
log_bin_trust_function_creators=1

Logo

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

更多推荐