Kubernetes 的配置资源 ConfigMap(01部分)

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
注册配置 MSE Nacos/ZooKeeper,118元/月
性能测试 PTS,5000VUM额度
简介: Kubernetes 的配置资源 ConfigMap(01部分)


作者设置:由于当前各个常用镜像站无法正常代理下载镜像,这篇实验中所用到的镜像建议先从网络下载获取再导入到私仓使用,

或私信后台回复:9521 获取~ ~

目录描述

  • Kubernetes 常见的配置资源介绍
  • ConfigMap 介绍说明
  • ConfigMap 创建方式
  • ConfigMap 使用方式
  • ConfigMap实践案例

一.  Kubernetes 常见的配置资源介绍

1.1 配置介绍

生产中所有的应用程序中,都涉及到配置文件,而配置文件经常会有变更,比如: 数据库连接,代码版本号,证书更新等

典型场景:项目经历开发环境、测试环境、预发布环境、线上环境才能完成发布,而每个环境都有定义其独立的各种配置,这些配置手工操作很繁杂,有一些流行的开源项目,比如: Apollo,Nacos,Consul等可以实现配置管理, 还有大公司专门开发了专用配置管理中心,如百度的disconf等。

为容器化应用提供配置信息方法

  • 制作镜像时,提前将定义好的配置文件拷贝进镜像之中
  • 制作镜像时,内置环境变量,在启动容器时通过环境变量向容器传递配置数据
  • 启动容器时,基于存储卷向容器传递配置文件,但需要提前准备外部的存储

注意:对于运行容器中的配置改变,还需要通过应用程序重载相关配置才能生效

kubernetes作为分布式容器调度平台,同样会遇到同样配置变更的问题,这时不可能把资源删除后,重新修改然后再启动生成,这种方法就太繁琐。

kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMapSecretdownwardAPI。通过这些组件来实现向pod中的容器注入配置信息的机制。

1.2  配置组件简介

官方的配置组件简介说明https://kubernetes.io/zh-cn/docs/concepts/configuration/

https://kubernetes.io/zh-cn/docs/concepts/configuration/

1.2.1 Configmap

ConfigmapKubernetes集群中非常重要的一种配置管理资源对象。借助于ConfigMap APIpod中的容器注入配置信息的机制。

ConfigMap不仅仅可以保存环境变量或命令行参数等属性,也可以用来保存整个配置文件或者JSON格式的文件。

各种配置属性和数据以 k/v嵌套k/v 样式 存在到Configmap

注意:所有的配置信息都是以明文的方式来进行传递,实现资源配置的快速获取或者更新。

1.2.2 Secret

Kubernetes集群中,有一些配置属性信息非常敏感,这些信息在传递的过程中,不希望外界能够接触的。所以,Kubernetes提供了一种加密场景中的配置管理资源对象Secret

它在进行数据传输之前,会对数据进行编码,在数据获取时,会对数据进行解码,从而保证整个数据传输过程的安全。

注意:这些数据是根据不同的应用场景,采用不同的加密机制。

1.2.3 downwardAPI

downwardAPI 为运行在pod中的应用容器提供了一种反向引用。让容器中的应用程序了解所处podnode的一些基础属性信息。

从严格意义上来说,downwardAPI不是存储卷,它自身就存在。相较于configmapsecret等资源对象需要创建后才能使用,而downwardAPI引用的是Pod自身的运行环境,这些信息在Pod启动的时候就存在了

二、ConfigMap 介绍说明

Kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMap。通过ConfigMap来实现、借助于ConfigMap API向pod中容器中注入配置信息的机制。

可以把configmap理解为Linux系统中的/etc目录,专门用来存储配置文件的目录。

Kubernetes借助于ConfigMap对象实现了将配置信息从容器镜像中解耦,从而增强了工作负载的可移樟性、使其配置更易于更改和管理并避免了将配置数据硬编码到Pod配置清单中

注:ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件。

虽然configmap可以对各种应用程序提供定制配置服务,但是一般不用它来替代专门的配置文件,从Kubernetes v1.19版本开始,ConfigMapSecret支持使用immutable字段创建不可变实例。

Configmap 属于名称空间级别

基本属性:

root@master1ha1:~# kubectl explain cm
   binaryData #二进制数据
   data   #文本数据,支持变量和文件
   immutable <boolean>  #设为true,不能被修改只能删除,默认为nil可以随时被修改
#注意:基于data的方式传递信息的话,会在pod的容器内部生成一个单独的数据文件

数据的表现样式:

#简单数据:
属性名称key: 属性值value   #单行配置内容,一般保存变量,参数等
文件名:单行内容           #配置文件如果有一行,也使用此方式,key为文件名,value为文件内容
#多行文件数据格式1:     
文件名称1: |     #注意:| 是"多行键值"的标识符
 文件内容行1    #内容大小不能超过1M
 文件内容行2
 ......
文件名称2: |     #注意:| 是"多行键值"的标识符
 文件内容行1    #内容大小不能超过1M
 文件内容行2
 ......

对于configmap这种资源类型的创建,与Kubernetes的其他资源对象的创建方式一样,主要涉及到两种方式:

  • 命令行工具:配置中有大量简单的键值对时建议使用
  • 资源定义文件:配置为大量文本内容时建议使用,此方式需要事先准备在资源清单元文件中加入配置文件内容

注意:

  • 如果Pod是以subPath 的形式挂载ConfigMapSecret,那么Pod是不会感知到ConfigMapSecret的更新。
  • 如果Pod 的变量来自于ConfigMapSecret中定义的内容,那么ConfigMapSecret更新后,也不会更新Pod中的变量。

三、ConfigMap 创建和更新

3.1 命令行创建方式

3.1.1 命令行创建方式说明

命令参数

#查看创建命令帮助
root@master1ha1:~# kubectl create configmap -h
#参数详解:
--from-literal=key1=value1        #以命令行设置键值对的方式配置数据
--from-env-file=/PATH/TO/FILE       #以环境变量专用文件的方式配置数据
--from-file=[key=]/PATH/TO/FILE #以配置文件的方式创建配置数据,如不指定key,FILE名称
为key名
--from-file=/PATH/TO/DIR        #以配置文件所在目录的方式创建配置数据
--dry-run=client -o yaml            #测试运行并显示cm内容
#查看configmap
kubectl create configmap <cm_name> -n <namespace> [-o yaml] --dry-run=client
kubectl get configmap <cm_name> -n <namespace>
kubectl describe configmap <cm_name> -n <namespace>
#删除configmap
kubectl delete configmap <cm_name> [-n <namespace>]

3.1.2 命令行创建方式案例

范例:命令行创建基于key:value形式的CM

#在使用kubectl创建的时候,通过在命令行直接传递键值对创建
root@master1ha1:~# kubectl create configmap cm-test1 --from-literal=key1='value1' --from-literal=key2='value2'
configmap/cm-test1 created
root@master1ha1:~# kubectl get cm
NAME               DATA   AGE
cm-test1           2      11s
kube-root-ca.crt   1      25d
root@master1ha1:~# kubectl get cm cm-test1 -o yaml
apiVersion: v1
data:
  key1: value1
  key2: value2
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-22T11:48:27Z"
  name: cm-test1
  namespace: default
  resourceVersion: "139551"
  uid: fce0ffc0-2ad5-4b99-bdf5-a0f95882f19d
root@master1ha1:~# kubectl describe cm cm-test1 
Name:         cm-test1
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data
====
key1:
----
value1
key2:
----
value2
BinaryData
====
Events:  <none>
#删除CM
root@master1ha1:~# kubectl delete cm cm-test1 
configmap "cm-test1" deleted

范例: 命令行创建基于key/value形式的CM

#创建CM
root@master1ha1:~# kubectl create configmap pod-test-config --from-literal=host="127.0.0.1" --from-literal=port="8888"
configmap/pod-test-config created
#验证创建成功
root@master1ha1:~# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      34d
pod-test-config    2      18s
#显示CM内容
root@master1ha1:~# kubectl get cm pod-test-config -o yaml
apiVersion: v1
data:
  host: 127.0.0.1
  port: "8888"
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-31T09:56:35Z"
  name: pod-test-config
  namespace: default
  resourceVersion: "161838"
  uid: 7b49ae67-4d64-4f2d-8c47-882c314f5ec7
 
 #删除CM
root@master1ha1:~# kubectl delete cm pod-test-config 
configmap "pod-test-config" deleted

范例: 命令行创建基于环境变量文件的CM

#如果变量较多,使用上面方式一个个的设定环境变量太繁琐,可以全部添加到环境变量文件中然后基于它来创建CM。
#定制环境变量文件
root@master1ha1:~# cat > env
key1=value1
key2=value2
^C
root@master1ha1:~# cat env 
key1=value1
key2=value2
#注意:env文件中所有的配置项以 "属性名=属性值" 格式定制
#将所有环境变量添加到到configmap中
root@master1ha1:~# kubectl create configmap cm-test2 --from-env-file=env
configmap/cm-test2 created
root@master1ha1:~# kubectl get cm cm-test2 -o yaml
apiVersion: v1
data:
  key1: value1
  key2: value2
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-31T10:06:01Z"
  name: cm-test2
  namespace: default
  resourceVersion: "162597"
  uid: 6ae54301-d753-4949-9e06-bdfba7c87cf9
root@master1ha1:~# kubectl describe cm cm-test2 
Name:         cm-test2
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data
====
key1:
----
value1
key2:
----
value2
BinaryData
====
Events:  <none>
#删除CM
root@master1ha1:~# kubectl delete cm cm-test2 
configmap "cm-test2" deleted

范例:命令行创建基于配置文件的CM

#直接将多个配置文件创建为一个ConfigMap
root@master1ha1:~# cat conf.d/*
[app1]
config1
[app2]
config2
[app3]
config3
root@master1ha1:~# ls conf.d/
app1.conf  app2.conf  app3.conf
root@master1ha1:~# kubectl create configmap cm-test3 --from-file=./conf.d/app1.conf --from-file=./conf.d/app2.conf 
configmap/cm-test3 created
root@master1ha1:~# kubectl get cm cm-test3 -o yaml
apiVersion: v1
data:
  app1.conf: |
    [app1]
    config1
  app2.conf: |
    [app2]
    config2
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-31T10:16:21Z"
  name: cm-test3
  namespace: default
  resourceVersion: "163407"
  uid: bf4dc865-70ef-443a-883b-c1df3af54022
root@master1ha1:~# kubectl describe cm cm-test3 
Name:         cm-test3
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data
====
app1.conf:
----
[app1]
config1
app2.conf:
----
[app2]
config2
BinaryData
====
Events:  <none>
#删除CM
root@master1ha1:~# kubectl delete cm cm-test3 
configmap "cm-test3" deleted

范例: 命令行创建基于目录的CM

root@master1ha1:~# cat conf.d/*
[app1]
config1
[app2]
config2
[app3]
config3
root@master1ha1:~# ls conf.d/
app1.conf  app2.conf  app3.conf
#直接将一个目录下的所有配置文件创建为一个ConfigMap
root@master1ha1:~# kubectl create configmap cm-test4 --from-file=./conf.d/
configmap/cm-test4 created
#结果显示:多个文件之间,属性名是文件名,属性值是文件内容
root@master1ha1:~# kubectl get cm cm-test4 -o yaml
apiVersion: v1
data:
  app1.conf: |
    [app1]
    config1
  app2.conf: |
    [app2]
    config2
  app3.conf: |
    [app3]
    config3
kind: ConfigMap
metadata:
  creationTimestamp: "2024-07-31T10:19:42Z"
  name: cm-test4
  namespace: default
  resourceVersion: "163668"
  uid: a32a06f3-2b62-453b-9580-c62831bd97a3
#结果显示:多个文件之间,属性名是文件名,属性值是文件内容
root@master1ha1:~# kubectl describe cm cm-test4 
Name:         cm-test4
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data
====
app1.conf:
----
[app1]
config1
app2.conf:
----
[app2]
config2
app3.conf:
----
[app3]
config3
BinaryData
====
Events:  <none>
#删除CM
root@master1ha1:~# kubectl delete cm cm-test4 
configmap "cm-test4" deleted

3.2 资源清单文件创建方式

3.2.1 资源清单文件格式说明

资源清单文件命令格式

#清单文件格式
apiVersion: v1
kind: ConfigMap
metadata:
 name: cm_name
  namespace: default
data:
 key: value   #配置信息如果只有一行,也使用此方式,使用卷挂载时,key即为文件名,value为文件
内容
 文件名: |     #配置文件有多行使用此方式
 文件内容行1
 文件内容行2
 .....
#注意:CM的清单文件没有spec信息,而是data
#命令式: 
kubectl create -f /path/file
#声明式
kubectl apply -f /path/file

注意:此方式将配置文件内容写入清单文件,很不方便,推荐如下方式解决

  • 先在命令行执行时指定配置文件的方式创建 CM
  • 通过 kubectl get cm <CM_NAME> -o yaml 方式导出资源清单文件,
  • 调整yaml资源清单文件,后续可重复使用

3.2.2 资源清单文件创建方式案例

操作示范

#资源定义文件
root@master1ha1:~# vim storage-configmap-test.yaml
apiVersion: v1
kind: ConfigMap
metadata:
        name: config-test
data:
        author: ddddhh
        file.conf: |
                [class]
                linux
                go
                java
#注释:data:部分内容是真正的配置项,有两种格式:
#author: 是Key/value格式
#file.conf: | 是文件格式
#创建资源对象
root@master1ha1:~# kubectl apply -f storage-configmap-test.yaml 
configmap/config-test created
#查看
root@master1ha1:~# kubectl get cm
NAME               DATA   AGE
config-test        2      32s
kube-root-ca.crt   1      35d
root@master1ha1:~# kubectl describe cm config-test 
Name:         config-test
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data
====
author:
----
ddddhh
file.conf:
----
[class]
linux
go
java
BinaryData
====
Events:  <none>
#结果显示:里面定义了两种类型的配置属性:文件样式和数据样式,都是以kv样式展示,属性名key和属性值
value中间使用 "----" 来隔开
#可以在线修改
root@master1ha1:~# kubectl edit cm config-test 
# 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:
  author: ddddhh
  file.conf: |
    [class]
    linux
    go
    java
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"author":"ddddhh","file.conf":"[class]\nlinux\ngo\njava\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"config-test","namespace":"default"}}
  creationTimestamp: "2024-08-01T07:46:13Z"
  name: config-test
  namespace: default
  resourceVersion: "165890"
  uid: 7142f41e-6efc-47e0-ae65-d73907e5df4f
#删除
root@master1ha1:~# kubectl delete cm config-test 
configmap "config-test" deleted

操作示范:只读的configmap

root@master1ha1:~# vim storage-configmap-immutable-test.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
        name: cm-immutable-test
data:
        author: ddddhh
        file.conf: |
                [class]
                linux
                go
                java
immutable: true
root@master1ha1:~# kubectl apply -f  storage-configmap-immutable-test.yaml 
configmap/cm-immutable-test created
root@master1ha1:~# kubectl get cm 
NAME                DATA   AGE
cm-immutable-test   2      62s
kube-root-ca.crt    1      35d
#在线修改configmap提示出错
root@master1ha1:~# kubectl edit cm cm-immutable-test 
error: configmaps "cm-immutable-test" is invalid
A copy of your changes has been stored to "/tmp/kubectl-edit-3644066815.yaml"
error: Edit cancelled, no valid changes were saved.
#可以删除
root@master1ha1:~# kubectl delete cm cm-immutable-test 
configmap "cm-immutable-test" deleted
root@master1ha1:~# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      35d

3.2.3 在线更新 configmap

操作示范

#创建 configmap
root@master1ha1:~# kubectl create cm cm-nginx-conf --from-file=nginx.conf
#修改configmap方法1 (主用方式推荐)
#早期版本中nginx.conf内容如果不大,多行内容显示在一行,不方便修改,但如果过大,此方式只能显示大小,而非内容,所以不能修改,新版无此问题
root@master1ha1:~# kubectl edit cm cm-nginx-conf
#修改configmap方法2
#通过将在线配置导出到一个yaml格式中修改后再apply
root@master1ha1:~# kubectl get cm cm-nginx-conf -o yaml > cm-config-conf.yaml
root@master1ha1:~# vim cm-config-conf.yaml
root@master1ha1:~# kubectl apply -f cm-config-conf.yaml
#修改configmap方法3
#修改配置
root@master1ha1:~# vim nginx.conf
root@master1ha1:~# kubectl create cm cm-nginx-conf --from-file=nginx.conf --dry-run=client -o yaml |kubectl apply -f -

四、 ConfigMap 使用

使用ConfigMap主要有两种方式:

  • 通过环境变量的方式直接传递pod
  • 使用volume的方式挂载入到pod内的文件中

注意:

  • ConfigMap必须在Pod之前创建
  • ConfigMap在同一个namespace内的pod才能使用ConfigMap,即ConfigMap不能跨命名空间

调用。

  • ConfigMap通常存放的数据不要超过1M
  • CM 支持实时更新,在原来的pod里面直接看到效果

4.1 通过环境变量的方式直接传递 Pod

引用ConfigMap对象上特定的key,以valueFrom赋值给Pod上指定的环境变量。

也可在Pod上使用envFrom一次性导入ConfigMap对象上的所有的key-value,key(可以统一附加特定前缀)即为环境变量,value自动成为相应的变量值。

环境变量是容器启动时注入的,不会随CM更改而发生变化,即一次性加载configmap

通过环境变量脚本的方式,预处理这些配置信息。

注意:环境变量的名称如果要用横线的话,最好使用下划线 _环境变量格式

  1. 方式1:env 对指定的变量一个一个赋值
kubectl explain pod.spec.containers.env
 name  #手工定制环境变量时,设置环境变量的名称,必选字段
 value #手工定制环境变量时,直接设置环境变量的属性值,不通过CM获取配置,可选字段
 valueFrom  #手工定制环境变量时,设置环境变量的属性来源位置,可以支持从CM,Secret,downwordAPI获取
kubectl explain pod.spec.containers.env.valueFrom.configMapKeyRef
   name   #引用哪个configmap
   key    #引用哪个configmap中的key
   optional  #如果设置为false,标识该项是必选项,如果设置为true标识这个key是可选的。
#此方式实现过程
1)容器中自定义环境变量名
2)根据CM的名称和Key名,找到对应的value
3) 再将value赋值给容器的环境变量
  1. 方式2:envFrom 使用CM的所有变量实现对变量的批量赋值,此方式生产更为推荐
kubectl explain pod.spec.containers.envFrom
 configMapRef #ConfigMap对象中的特定Key
 secretKeyRef #Secret对象中的特定Key
 prefix #为ConfigMap中的每个属性都添加前缀标识
#此方实现过程
1)容器中自定义环境变量名,并且和CM的key同名
2)找到指定的CM中所有Key名,将值批量直接赋值给容器中相同名称的变量

4.2 使用volume的方式挂载入到pod内的文件中

在Pod上将 configMap对象引用为存储卷,而后整体由容器mount至某个目录下, key转为文件名,value即为相应的文件内容

在Pod上定义configMap卷时,仅引用其中的部分key,而后由容器mount至目录下

在容器上仅mount configMap卷上指定的key

容器中挂载的Volume数据可以根据时间戳机制,和ConfigMap 同步更新,即configmap变更后会自动加载

推荐滚动升级pod的方式来让ConfigMap内容变化生效

volume 格式

#指定卷信息,引用CM
kubectl explain pod.spec.volumes
 name: volume_name  #指定volume名
 configMap:
   name: CM_name    #指定CM的名称
   
#挂载卷到容器内的目录
kubectl explain pod.spec.containers.volumeMounts
 volumeMounts:
  - name: CM_name    #指定CM的名称
   mountPath; /path #容器内的挂载点

最后:

下章ConfigMap实践案例部分


最后~欢迎关注我! @Linux学习的那些事儿

我的个人资源整理,满满都是干货:可按需访问领取

200T免费资料,持续发布中...

如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
JSON Kubernetes API
深入理解Kubernetes配置:编写高效的YAML文件
深入理解Kubernetes配置:编写高效的YAML文件
|
3月前
|
Kubernetes 监控 调度
在K8S中,DaemonSet类型资源特性?
在K8S中,DaemonSet类型资源特性?
|
1月前
|
JSON 运维 Kubernetes
|
7天前
|
Kubernetes 监控 Java
如何在Kubernetes中配置镜像和容器的定期垃圾回收
如何在Kubernetes中配置镜像和容器的定期垃圾回收
|
1月前
|
存储 Kubernetes 开发工具
k8s学习--ConfigMap详细解释与应用
ConfigMap 是 Kubernetes 中用于管理非机密配置数据的 API 对象,可将应用配置与容器分离,便于动态管理和更新。它支持四种创建方式:命令行参数、多个文件、文件内的键值对以及 YAML 资源清单文件。ConfigMap 可通过环境变量或挂载为卷的方式传递给 Pod,并且当通过卷挂载时支持热更新。这使得配置管理更加灵活和安全,无需重新部署应用即可更新配置。
|
3月前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习笔记之ConfigMap和Secret
k8s学习笔记之ConfigMap和Secret
|
3月前
|
存储 Kubernetes 数据中心
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
在K8S中,同⼀个Pod内不同容器哪些资源是共用的,哪些资源是隔离的?
|
3月前
|
Kubernetes 网络性能优化 调度
在K8S中,Kubernets资源限制是如何配置的,是否根据Qos?
在K8S中,Kubernets资源限制是如何配置的,是否根据Qos?
|
3月前
|
Kubernetes 调度 Perl
在K8S中,Pod多副本配置了硬亲和性,会调度到同⼀个节点上吗?
在K8S中,Pod多副本配置了硬亲和性,会调度到同⼀个节点上吗?
|
3月前
|
边缘计算 人工智能 Kubernetes
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
边缘计算问题之理解 Kubernetes 节点资源的四层分配结构如何解决
31 1

相关产品

  • 容器服务Kubernetes版