Kubernetes-configmap资源详解

一、configmap概述

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

主要作用:让镜像和配置文件进行解耦,以便实现镜像的可移植性和可复用性适用于同时部署多个相同的服务

解释:

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

流程:

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

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

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

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

Configmap 应用场景

1、使用k8s部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap可以将配置信息和docker镜像解耦,以便实现镜像的可移植性和可复用性,因为一个configmap是一系列配置信息的集合,可直接注入到pod中给容器使用。

configmap注入方式有两种:

1、将configmap作为存储卷
2、将configmap通过env中configmapkeyref注入到容器中

2、使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务单独一份配置,那更新配置会比较麻烦,使用configmap可以友好的共享配置。

使用configmap的限制条件

1、configmap需要在pod创建之前创建

2、只有当configmap和pod处于同一个命名空间,才可以被pod引用;

3、当pod挂载configmap绑定目录时,目录下的目录不会被挂载在pod内,只有目录下的文件会挂载

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

        

二、configmap创建方法

按大类可分为两种方式,细分共有五种方式:

(一)kubectl create configmap创建

  • (1)通过命令行参数字面直接创建

  • (2)通过指定文件创建

  • (3)通过指定目录创建

(二)yaml文件创建

1、命令行参数字面直接创建

kubectl create configmap NAME [--from-literal=key1=value1] [--dry-run=server|client|none] [options]
​
#NAME: ConfigMap 的名称。
#--from-literal=key1=value1: 直接从命令行指定键值对。
#--dry-run=server|client|none: 模拟创建 ConfigMap 的操作,server 表示在服务器端模拟,client 表示在客户端模拟,none 表示不模拟。
#[options]: 其他可选参数,例如 --namespace 指定命名空间等。
​
创建可以同时输入多个参数即可以多个--from-literal=key1=value1
这种方式比较"适用于临时测试使用",而且不适合配置很多的情况。

2、指定文件创建

kubectl create configmap NAME [--from-file=[key=]source]  [--dry-run=server|client|none] [options]
#--from-file=[key=]source: 从文件创建 ConfigMap。可以指定文件的键名(key),如果不指定,则文件名将作为键名。
创建可以同时输入多个文件

3、指定目录创建

kubectl create configmap NAME --from-file=目录路径  [--dry-run=server|client|none] [options]
指定目录创建和指定文件创建差不多,只是--from-file后面的参数"是目录不是文件",注意指定目录时,--from-file不需要指定key值,目录名会自动为key值

4、yaml文件创建

kubectl apply -f yaml文件
书写略...

三、Pod使用 Configmap

在pod中使用configmap有以下四种方式:

(一)通过环境变量引入

  • (1)在容器命令和参数里(valueFrom一一映射)

  • (2)容器的环境变量(envFrom全部映射)

(二)加载文件

  • (1)把 configmap 做成 volume,挂载到 pod (通过volume加载

  • (2)编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap(通过subPath加载

通过环境变量引入,只是启动命令添加环境变量,是要把ConfigMap映射为容器的环境变量。

编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap,要访问API,可以使用相关的库

1、valueFrom-单个映射

通过valuefrom来配置环境变量,确保在 Pod 的 YAML 文件中,您引用的 ConfigMap 名称和键与您在 ConfigMap 中定义的完全一致。。valueFrom:表示引用cm的一个key

1、创建一个存储mysql配置的文件
#vim mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql #环境变量的名称
  labels:
    app: mysql
data:
  logs: "1"
  lower: "1"  
2、将文件导入到configmap中,即环境变量
kubectl apply -f mysql-configmap.yaml
3、创建 pod,引用 Configmap 中的内容
#vim mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  containers:
  - name: mysql 
    image: busybox #拉取镜像
    imagePullPolicy: ifNotPresent #拉取策略
    command: [ "bin/sh", "-c", "sleep 3000" ]
    env: #这里开始引入环境变量
    - name: logs #自定义名称,用来作为引用的环境变量的name
      valuefrom: #valueFrom:表示引用cm的一个key
        configMapKeyRef:
          name: mysql #指定 configmap 的名字
          key: logs #指定 configmap 中的 key
    - name: lower
      valuefrom: #valueFrom:表示引用cm的一个key
        configMapKeyRef:
          name: mysql
          key: lower
  restartPolicy: Never
  3、导入pod,并开始引用环境变量
  kubectl apply -f mysql-pod.yaml
  4、查看资源清单,要进入容器中。
# kubectl exec -it mysql-pod -- /bin/sh
env 查看资源清单

2、envfrom-全部映射

通过环境变量引入

envfrom:引入cm当中的所有的key为环境变量

1、导入一个存储mysql配置的文件 即设置环境变量
2、创建 pod,引用 Configmap 中的内容
#vim  mysql-pod-envfrom
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod-envfrom
spec:
  containers:
    - name: busybox
      image: busybox
      imagePullPolicy: IfNotPresent #拉取策略
      command: [ "bin/sh", "-c", "sleep 3000" ]
      envFrom: #这里为全部映射
      - configMapRef:
          name: mysql #这里为引用的环境变量的名称
  restartPolicy: Never #重启策略
  3、导入pod,并开始引用环境变量
  kubectl apply -f mysql-pod-envfrom.yaml
  4、查看资源清单,要进入容器中。
# kubectl exec -it mysql-pod-envfrom   sh

3、把 configmap 做成 volume,挂载到 pod

通过volume的方式把ConfigMap加载进Pod

#通过volume加载文件
apiVersion: v1
kind: Pod
metadata:
  name: busy-mount-volume
spec:
  volumes: #Pod定义中的一个部分,用于声明要挂载的卷。
    - name: passwd #挂载到容器中的卷,自定义名称
      configMap: #指定该卷是从一个ConfigMap中创建的
        name: busy-mount-passwd #指定挂载卷中数据源自configmap中的哪个环境变量
  containers:
    - name: busybox1
      image: busybox
      imagePullPolicy: IfNotPresent
      command: [ "/bin/sh", "-c", "sleep 3000" ]
      volumeMounts: #指定了要在容器中挂载的卷
        - name: passwd #指定了要挂载的卷的名称为 passwd
          mountPath: /root/k8s #指定挂载的路径
  restartPolicy: Never
#注意:volumes和volumeMounts中的name定义的卷名称一致
​
如果只想要ConfigMap某个定义的环境变量中的部分内容,并自定义文件名,可通过"items"来配置
...
 volumes:
    - name: config-volume
      configMap:
        name: pkslow-yaml
        items:
          - key: application.yaml #注意这个名称对应pkslow-yaml这个环境变量中的某个值
            path: app.yaml
          - key: application-uat.yaml
            path: uat.yaml
...
#items:
选择特定键: 这个部分允许您选择 ConfigMap 中的特定键,并将它们映射到容器内的文件名。
这里有两个条目:
第一个条目:
#application.yaml 被映射为 app.yaml。
key: application.yaml: 指定 ConfigMap 中的键名。
path: app.yaml: 指定在容器中挂载的文件名。
第二个条目:
#application-uat.yaml 被映射为 uat.yaml。
key: application-uat.yaml: 另一个键名。
path: uat.yaml: 在容器中挂载的文件名。

4、通过subPath加载

通过配置subPath字段,把文件一个一个加载到Pod中去。

将卷中的特定文件或目录挂载到容器中的指定路径,而不是将整个卷挂载到容器中。这种方式在处理多个文件时非常有用。

示例:

假设您有一个 ConfigMap(指在configmap中某一个文件中有定义多个键值对),其中包含多个配置文件,您可以使用 subPath 将每个文件单独挂载到容器中。

apiVersion: v1 #指定使用的 Kubernetes API 版本
kind: Pod #kind: 表示资源类型
metadata: #metadata: 包含关于 Pod 的元数据,比如名称之类的
  name: busy-pod-subpath
spec: #定义 Pod 的具体配置。
  volumes: #定义 Pod 中使用的卷
    - name: passwd #自定义卷的名称,卷的名称
      configMap: #指定该卷的类型为 ConfigMap。
        name: busy-mount-passwd #指定使用的 ConfigMap 名称
  containers: #定义 Pod 中的容器列表
    - name: busybox #容器的名称
      image: busybox #使用的容器镜像
      imagePullPolicy: IfNotPresent #指定镜像拉取策略
      command: [ "/bin/sh", "-c", "sleep 3000" ] #容器启动时执行的命令
      volumeMounts: #定义容器中的卷挂载
        - name: passwd #指定挂载的卷名称
          mountPath: /data/passwd.yaml #指定在容器中的挂载路径
          subPath: passwd #指定要挂载的 ConfigMap 中的具体键
        - name: passwd
          mountPath: /data/mysql
          subPath: mysql #指定要挂载的 ConfigMap 中的具体键
  restartPolicy: Never #指定Pod的重启策略,Never,表示如果容器停止运行,将不会被重启。
  
这个 Pod 配置的目的是创建一个包含两个文件挂载的容器。文件内容来自于 busy-mount-passwd ConfigMap 中的 passwd 和 mysql 键。容器将会运行 busybox 镜像,保持 3000 秒的休眠状态。Pod 的重启策略设置为不重启容器。

注意事项

  1. 文件覆盖: 挂载卷会覆盖容器内挂载路径下的任何现有文件或目录。

  2. ConfigMap 更新: 如果更新了 ConfigMap,挂载该 ConfigMap 的 Pod 将会自动获取这些更新,但通常需要重启 Pod 才能使更改生效。

解决覆盖的问题

修改configmap后容器中对应的file会自动更新,如果以subpath方式挂载文件,文件内容不会自动更新

即挂载卷的时候尽量使用subpath,减少文件被覆盖的几率。

...
   volumeMounts:
       - mountPath: /etc/nginx/nginx.conf
         name: volume-7zdx7
         subPath: nginx.conf
dnsPolicy: ClusterFirst #dnsPolicy: 指定 Pod 的 DNS 策略,这里是 ClusterFirst,表示 Pod 将优先使用集群 DNS 服务。
restartPolicy: Always #restartPolicy: 指定 Pod 的重启策略,这里是 Always,表示无论容器是如何退出的,Kubernetes 都会尝试重新启动它。
schedulerName: default-scheduler #schedulerName: 指定调度器的名称,这里是 default-scheduler,表示使用 Kubernetes 的默认调度器来调度该 Pod。
securityContext: {} #securityContext: 定义 Pod 的安全上下文,这里是一个空对象 {},表示没有特别的安全设置。
terminationGracePeriodSeconds: 30 #terminationGracePeriodSeconds: 指定 Pod 终止时的宽限期(以秒为单位),这里是 30 秒,表示在发送终止信号后,容器有 30 秒的时间来清理和关闭。
​
volumes:
  - name: volume-7zdx7 
    configMap: 
      defaultMode: 420 #defaultMode: 指定挂载文件的默认权限,这里是 420(八进制),表示文件权限为 644(用户可读写,组和其他用户可读)。
      name: nginx1
  
 ...
Configmap 热更新

仅限于卷的形式,如果是环境变量的形式则不更新!!!

即修改configmap中文件的内容,然后重新执行一下。即可

[root@k8s-master01 ~]# kubectl edit configmap mysql
#将log:1 变成 log:2
apiVersion:v1
data:
log:"2"
lower:"1"
重新执行一次资源清单文件
[root@k8s-master01 test1]# kubectl apply -f mysql-pod-volume.yaml
pod/mysql-pod-volume configured
[root@k8s-master01 ~]# kubectl exec -it mysql-pod-volume -- /bin/sh
/ # cat /tmp/config/log
2/ #
#一次构建镜像,通过配置管理中心configmap 实现了 多场景运行

四、不可变的ConfigMap

可以禁止修改ConfigMap

  • 保护应用,使之免受意外(不想要的)更新所带来的负面影响。

  • 通过大幅降低对 kube-apiserver 的压力提升集群性能,这是因为系统会关闭 对已标记为不可变更的 ConfigMap 的监视操作。

此功能特性由 ImmutableEphemeralVolumes 特性门控 来控制。你可以通过将 immutable 字段设置为 true 创建不可变更的 ConfigMap。

apiVersion: v1
kind: ConfigMap
metadata:
  ...
data:
  ...
immutable: true

一旦某 ConfigMap 被标记为不可变更,则 无法逆转这一变化,也无法更改 databinaryData 字段的内容。你只能删除并重建 ConfigMap。 因为现有的 Pod 会维护一个对已删除的 ConfigMap 的挂载点,建议重新创建 这些 Pods。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值