🏆 configmap

🌟 configmap介绍

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

ConfigMap可以将环境配置文件信息和容器镜像进行解耦、便于应用配置的修改

但是它不提供加密功能。如果你要存储的数据要加密得使用 Secret,或者使用其他第三方工具。

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

ConfigMap 是一个 API 对象, 让你可以存储其他对象所需要使用的配置。 和其他 Kubernetes 对象都有一个 spec 不同的是,ConfigMap 使用 databinaryData 字段。这些字段能够接收键-值对作为其取值。data 和 binaryData 字段都是可选的。data 字段设计用来保存 UTF-8 字节序列,而 binaryData 则 被设计用来保存二进制数据作为 base64 编码的字串。

⚠️ 注意事项:

  1. ConfigMap 的名字必须是一个合法的 DNS 子域名。
  2. 不能超过253个字符
  3. 只能包含小写字母、数字,以及'-' 和 '.'
  4. 须以字母数字开头
  5. 须以字母数字结尾

databinaryData 字段下面的每个键的名称都必须由字母数字字符或者 -、_ 或 . 组成。在 data 下保存的键名不可以与在 binaryData 下 出现的键名有重叠。

从 v1.19 开始,你可以添加一个immutable 字段到 ConfigMap 定义中,创建 不可变更的 ConfigMap。

🌟 实操

你可以使用四种方式来使用 ConfigMap 配置 Pod 中的容器:

      1. 在容器命令和参数内
      1. 容器的环境变量
      1. 在只读卷里面添加一个文件,让应用来读取
      1. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

这些不同的方法适用于不同的数据使用方式。 对前三个方法,kubelet 使用 ConfigMap 中的数据在 Pod 中启动容器。 第四种方法意味着你必须编写代码才能读取 ConfigMap 和它的数据。然而, 由于你是 直接使用 Kubernetes API,因此只要 ConfigMap 发生更改,你的 应用就能够通过订阅来获取更新,并且在这样的情况发生的时候做出反应。 通过直接进入 Kubernetes API,这个技术也可以让你能够获取到不同的名字空间 里的 ConfigMap

1️⃣使用文件/目录创建

[root@master configmap]# cat /opt/configtest/likes 
like.color=bule
like.fruits=apple
[root@master configmap]# cat /opt/configtest/dislikes 
ke.color=none
dislike.fruits=none
##基于文件
[root@master configmap]# kubectl create configmap config-test1 --from-file=/opt/configtest/likes 
configmap/config-test1 created
[root@master configmap]# kubectl create configmap config-test2 --from-file=/opt/configtest/dislikes 
configmap/config-test2 created
##基于目录
 [root@master configmap]# kubectl create configmap config-test3 --from-file=/opt/configtest/
configmap/config-test3 created

--from-file就是在指定目录/文件来创建,键的名字就是文件名,值就是文件的内容

[root@master configmap]# kubectl get configmap
NAME           DATA   AGE
config-test1   1      2m59s
config-test2   1      108s
config-test3   2      2s

2️⃣ 使用ConfigMaps来配置容器内设置-pod和configmap要在同一命名空间

查看config-map的键值对
kubectl get configmap [config name] -o yaml/json

3️⃣ 使用命令创建

[root@master ~]# kubectl create configmap config-test-commd --from-literal=likes=you --from-literal=dislike=you
configmap/config-test-commd created
[root@master ~]# kubectl get configmap
NAME                DATA   AGE
config-test-commd   2      11s
config-test1        1      17m
config-test2        1      16m
config-test3        2      14m

4️⃣ 创建一个configmap来代替环境变量

[root@master configmap]# cat configmap-test.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-test
data:
  num: "3" ##简单的键:值 类型
  key: "1234"
  likes: | ##类文件键
    like.color=bule
    like.fruits=apple
  dislikes: |
    dislike.color=none
    dislike.fruits=none
  
[root@master ~]# kubectl create -f configmap/configmap-test.yaml 
configmap/config-test created  

5️⃣ 创建pod

[root@master ~]# cat configmap/pod-config.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: conifg-test-pod
spec:
  containers:
  - name: test1
    image: centos
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","env"] ##输出环境变量
    env: ##设置pod的环境变量
    - name: LIKES  #环境变量的名字
      valueFrom: ##环境变量来自哪里
        configMapKeyRef: 
          name: config-test  ##这个值来自configmap中的config-test
          key: likes ###需要取值的键
    - name: DISLIKES
      valueFrom:
        configMapKeyRef:
          name: config-test
          key: dislikes
  restartPolicy: Never ##永不重启
[root@master ~]# kubectl create -f configmap/pod-config.yaml 
pod/conifg-test-pod created   

6️⃣ 查看状态

[root@master ~]# kubectl get pod ##已经时完成状态
NAME              READY   STATUS      RESTARTS   AGE
conifg-test-pod   0/1     Completed   0          5m27s

7️⃣查看日志

 [root@master ~]# kubectl log conifg-test-pod
log is DEPRECATED and will be removed in a future version. Use logs instead.
HOSTNAME=conifg-test-pod
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
PWD=/
HOME=/root
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_PORT=443
LIKES=like.color=bule
like.fruits=apple

KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
SHLVL=1
KUBERNETES_SERVICE_PORT=443
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_SERVICE_HOST=10.96.0.1
DISLIKES=dislike.color=none
dislike.fruits=none

_=/usr/bin/env

8️⃣使用configmap设置命令参数

apiVersion: v1
kind: Pod
metadata:
  name: conifg-test-pod2
spec:
  containers:
  - name: test1
    image: centos
    imagePullPolicy: IfNotPresent
    command: ["echo","$(LIKES)"]
    env:
    - name: LIKES
      valueFrom:
        configMapKeyRef:
          name: config-test
          key: likes
    - name: DISLIKES
      valueFrom:
        configMapKeyRef:
          name: config-test
          key: dislikes
  restartPolicy: Never  

🔟查看

[root@master ~]# kubectl log conifg-test-pod2
log is DEPRECATED and will be removed in a future version. Use logs instead.
like.color=bule
like.fruits=apple
  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 下面的一个文件名。
[root@master ~]# cat configmap/volume-config-test.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: volume-test-pod
spec:
  volumes:  ##创建卷
  - name: config ##卷的名字
    configMap: 
      name: config-test ##把config-test的key:vlaue映射为文件
  containers:
  - name: volume-config-pod
    image: centos
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","sleep 700;"]
    volumeMounts: ##挂载卷
    - name: config  ##这里要和的卷的名字一样
      mountPath: "/opt/config" ##挂载路径
      readOnly: true

如果你完全忽略 items 数组,则 ConfigMap 中的每个键都会变成一个与 该键同名的文件

如果假如items就可以指定哪个键在volumes生成文件

进入容器查看

[root@volume-test-pod config]# ls
dislikes  key  likes  num
[root@volume-test-pod config]# cat dislikes 
dislike.color=none
dislike.fruits=none
[root@volume-test-pod config]# cat key 
1234[root@volume-test-pod config]# cat likes 
like.color=bule
like.fruits=apple
[root@volume-test-pod config]# ls 
dislikes  key  likes  num
[root@volume-test-pod config]# cat dislikes 
dislike.color=none
dislike.fruits=none
[root@volume-test-pod config]# cat key 
1234[root@volume-test-pod config]# cat likes 
like.color=bule
like.fruits=apple
[root@volume-test-pod config]# cat num 
3[root@volume-test-pod config]# 

🌟 被挂载的 ConfigMap 内容会被自动更新

当卷中使用的 ConfigMap 被更新时,所投射的键最终也会被更新。 kubelet 组件会在每次周期性同步时检查所挂载的 ConfigMap 是否为最新。 不过,kubelet 使用的是其本地的高速缓存来获得 ConfigMap 的当前值。 高速缓存的类型可以通过 KubeletConfiguration 结构 的 ConfigMapAndSecretChangeDetectionStrategy 字段来配置。

ConfigMap 既可以通过 watch 操作实现内容传播(默认形式),也可实现基于 TTL 的缓存,还可以直接经过所有请求重定向到 API 服务器。 因此,从 ConfigMap 被更新的那一刻算起,到新的主键被投射到 Pod 中去,这一 时间跨度可能与 kubelet 的同步周期加上高速缓存的传播延迟相等。 这里的传播延迟取决于所选的高速缓存类型 (分别对应 watch 操作的传播延迟、高速缓存的 TTL 时长或者 0)。

以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要重新启动 Pod。

修改configmap-把dislike.color=none** 改为dislike.color=pink**

[root@master ~]# kubectl edit configmap config-test
configmap/config-test edited

#进入容器查看
[root@volume-test-pod /]# cat /opt/config/dislikes 
dislike.color=pink
dislike.fruits=none

🌟 不可变更的 ConfigMap

FEATURE STATE: Kubernetes v1.21 [stable]

Kubernetes 特性 不可变更的 SecretConfigMap 提供了一种将各个 SecretConfigMap 设置为不可变更的选项。对于大量使用 ConfigMap 的 集群(至少有数万个各不相同的 ConfigMapPod 挂载)而言,禁止更改 ConfigMap 的数据有以下好处:

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

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

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

image-20240826163521595

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