一、什么是ConfigMap

       ConfigMap翻译过来即为“配置字典”,在实际的生产环境中,应用程序配置经常需要且又较为复杂,参数、config文件、变量等如果直接打包到镜像中,将会降低镜像的可移植性,因此期望有一种方式可以将配置从应用程序中解耦出来,ConfigMap正是在此背景下诞生的,它用于保存配置数据的键值(key-value)对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap 跟 secret 很类似,但它可以更方便地处理不包含敏感信息的字符串。

二、适用场景?

适用于存储不包含敏感信息的变量、属性或文件。

比如在一个集群中,可将应用程序所需的参数、变量、配置文件存放到ConfigMap中,在开发、测试和生产环境将同1个ConfigMap(前提是同1个namespace)挂载到Pod中,这样既可以实现配置和容器镜像的分离,也可方便的实现统一管理,比如可以利用其热更新的机制,修改完成后会同步到挂载了此ConfigMap的所有Pod中。

三、ConfigMap的创建

1、文件目录创建

支持以目录的方式创建ConfigMap,其中文件名将作为key,文件内容作为value,有几个文件将会存在几个键值对,如下图,先创建1个目录,此目录下存在两个文件

[root@k8s-master confdirtest]# ls
conftest1.txt conftest.txt
[root@k8s-master consecret]# kubectl create configmap con-dir-test --from-file=confdirtest/
configmap/con-dir-test created

其格式为kubectl creat configmap "configmap的名字" --from-file="目录"/,这种适用于将某个目录下的所有文件作为key,文件内容作为value进行创建。

[root@k8s-master consecret]# kubectl get cm | grep con-dir-test
con-dir-test 20s
[root@k8s-master consecret]# kubectl describe cm con-dir-test
Name: con-dir-test
Namespace: default
Labels: <none>
Annotations: <none> Data
====
conftest.txt:
----
name=this is test #文件conftest.txt的内容 conftest1.txt:
----
name=this is test1 #文件conftest1.txt的内容 Events: <none>

2、文件方式创建

     --from-file的方式除了用于目录的方式之外,同样还适用于指定文件的方式进行创建,其中文件名称将作为key名称,文件内容作为value,如下所示,先建立一个配置文件testconf.cfg

[root@k8s-master consecret]# cat testconf.cfg
listenport=
name=testconf
serverip=10.0.0.1

接下里将其生成1个configmap文件,如下所示,其格式为:kubectl create configmap "configmap名称" --from-file=“文件名”

[root@k8s-master consecret]# kubectl create configmap conf-file-test --from-file=testconf.cfg
configmap/conf-file-test created
[root@k8s-master consecret]# kubectl describe cm conf-file-test
Name: conf-file-test
Namespace: default
Labels: <none>
Annotations: <none> Data
====
testconf.cfg:
----
listenport=
name=testconf
serverip=10.0.0.1 Events: <none>

此方式适用于将某个或多个配置文件生成同一个configmap文件的场景

3、直接创建key-value 

 可直接指定需要data的key-value键值对进行创建,如下所示,使用"--from-literal"选项可在命令行直接创建configmap对象,若是创建多个,可重复多次进行创建,但是注意其key的名称不可重复,这种方式适用于直接指定key-value的方式进行创建。

[root@k8s-master consecret]# kubectl create configmap con-key-value --from-literal=key1=name1
configmap/con-key-value created
[root@k8s-master consecret]# kubectl describe cm con-key-value
Name: con-key-value
Namespace: default
Labels: <none>
Annotations: <none> Data
====
key1:
----
name1
Events: <none>
[root@k8s-master consecret]# kubectl create configmap con-key-value-test --from-literal=class.= --from-literal=class.=
configmap/con-key-value-test created
[root@k8s-master consecret]# kubectl describe cm con-key-value-test
Name: con-key-value-test
Namespace: default
Labels: <none>
Annotations: <none> Data
====
class.:
---- class.:
---- Events: <none>

4、导入环境变量创建

可将环境变量以--from-env-file的方式进行创建,其格式为:kubectl crete configmap "configmap的名称" --from-env=file=环境变量文件.env

[root@k8s-master consecret]# echo -e "testenv1=1\testenv2=2" | tee configtest.env
testenv1= estenv2=
[root@k8s-master consecret]# kubectl create configmap conf-env-test --from-env-file=configtest.env
configmap/conf-env-test created
[root@k8s-master consecret]# kubectl describe cm conf-env-test
Name: conf-env-test
Namespace: default
Labels: <none>
Annotations: <none> Data
====
testenv1:
----
estenv2=
Events: <none>

四、ConfigMap的使用

1、热更新(目录形式挂载)

首先先成功创建一个ConfigMap

[root@k8s-master consecret]# cat conf-delete-test.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: zltest-conf-delete
namespace: default
data:
zltest.show: delete-test
[root@k8s-master consecret]# kubectl delete deployment dep-deleye-conf-test
deployment.apps "dep-deleye-conf-test" deleted
[root@k8s-master consecret]# kubectl create -f conf-delete-test.yaml
configmap/zltest-conf-delete created
[root@k8s-master consecret]# kubectl get cm | grep zltest-conf-delete
zltest-conf-delete 44s

将其以卷目录形式挂载到Pod容器中,创建一个deployment

[root@k8s-master zhanglei]# cat dep-delete-con.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep-deleye-conf-test
namespace: default
labels:
app: nginx-delete-conf-test
spec:
replicas:
selector:
matchLabels:
app: nginx-deployment-delete
template:
metadata:
labels:
app: nginx-deployment-delete
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: testconf
containerPort:
volumeMounts:
- name: nginxconf
mountPath: /data/deletetest
volumes:
- name: nginxconf
configMap:
name: zltest-conf-delete
[root@k8s-master zhanglei]# kubectl create -f dep-delete-con.yaml
deployment.apps/dep-deleye-conf-test created
[root@k8s-master zhanglei]# kubectl get deployment |grep dep-deleye-conf-test
dep-deleye-conf-test / 56s

执行以上的步骤后,名为zltest-conf-delete的ConfigMap已被成功挂载到Pod的容器中,如果在运行的过程中,修改下ConfigMap的文件,会出现怎样的情况呢?先edit下ConfigMap,增加一个键值对

[root@k8s-master zhanglei]# kubectl describe cm zltest-conf-delete
Name: zltest-conf-delete
Namespace: default
Labels: <none>
Annotations: <none> Data
====
zltest.show:
----
delete-test
Events: <none>
[root@k8s-master consecret]# kubectl edit cm zltest-conf-delete 

# 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:
zltest.show: delete-test
addkey: addvalue # 新增的键值对
kind: ConfigMap
metadata:
creationTimestamp: "2020-07-23T11:29:11Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:zltest.show: {}
manager: kubectl
operation: Update
time: "2020-07-23T11:29:11Z"
name: zltest-conf-delete
namespace: default

[root@k8s-master consecret]# kubectl edit cm zltest-conf-delete
configmap/zltest-conf-delete edited

验证下新增的键值对是否会同步热更新到Pod的容器中,通过exec的方式登录到容器中进行查看,新添加的键值对以同步更新到Pod的容器中,

不需要以容器进行额外的操作,这是卷目录的形式挂载的热更新,但是若是通过环境变量env或者通过文件的形式挂载到容器中,是不会支持热更新的,这里需要注意下。

[root@k8s-master consecret]# kubectl exec -it dep-deleye-conf-test-869747b77f-67w9h -- bash
root@dep-deleye-conf-test-869747b77f-67w9h:/# cd data
root@dep-deleye-conf-test-869747b77f-67w9h:/data# ls
deletetest
root@dep-deleye-conf-test-869747b77f-67w9h:/data# cd deletetest/
root@dep-deleye-conf-test-869747b77f-67w9h:/data/deletetest# ls
addkey zltest.show

如果删除已将挂载到Pod中的容器的ConfigMap会出现怎样的情况呢,先删除ConfigMap,然后再次登录到容器中进行验证

[root@k8s-master consecret]# kubectl delete cm zltest-conf-delete
configmap "zltest-conf-delete" deleted
[root@k8s-master consecret]# kubectl exec -it dep-deleye-conf-test-869747b77f-67w9h -- bash
root@dep-deleye-conf-test-869747b77f-67w9h:/data/deletetest# ls
addkey zltest.show

若未对Pod进行删除的操作,删除ConfigMap成功,但是挂载到容器的目录依然会存在,并不会一起被删除,此时若删除Pod,副本控制器会重新拉

起1个Pod,会创建成功吗?接下来验证下

[root@k8s-master consecret]# kubectl get pod | grep dep-deleye-conf-test
dep-deleye-conf-test-869747b77f-kgzqt / Running 134m
dep-deleye-conf-test-869747b77f-mf6vc / ContainerCreating 2m13s

重新拉起Pod一直会是ContainerCreating状态,详细查看下原因

[root@k8s-master consecret]# kubectl describe pod dep-deleye-conf-test-869747b77f-mf6vc
Name: dep-deleye-conf-test-869747b77f-mf6vc
Namespace: default
Priority:
Node: k8s-master/192.168.126.129
Start Time: Thu, Jul :: +
Labels: app=nginx-deployment-delete
pod-template-hash=869747b77f
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: ReplicaSet/dep-deleye-conf-test-869747b77f
Containers:
nginx:
Container ID:
Image: nginx:latest
Image ID:
Port: /TCP
Host Port: /TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count:
Environment: <none>
Mounts:
/data/deletetest from nginxconf (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-74s86 (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
nginxconf:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: zltest-conf-delete
Optional: false
default-token-74s86:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-74s86
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/dep-deleye-conf-test-869747b77f-mf6vc to k8s-master
Warning FailedMount 11s (x8 over 75s) kubelet, k8s-master MountVolume.SetUp failed for volume "nginxconf" : configmap "zltest-conf-delete" not found

可以看到是FailedMount,volume异常了,K8S中删除的时候是不会判断这个依赖关系的,因此在生产的实际使用中,这点还是需要注意。

2、通过环境变量引入

除了通过volume的方式挂载到容器中使用之外,还可将configmap作为环境变量的方式引入到容器中,这里以con-key-value-test作为例子

[root@k8s-master consecret]# kubectl get cm |grep con-key-value-test
con-key-value-test 34m
[root@k8s-master zhanglei]# cat dep-conf-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-conf-env-test
namespace: default
labels:
app: nginx-deployment
spec:
replicas:
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx
image: nginx:latest
# command: [ "/bin/bash","-c","env" ]
ports:
- containerPort:
env:
- name: test-env1-conf # 环境变量名称1
valueFrom:
configMapKeyRef:
name: con-key-value-test
key: class.1 # 指定key名称即可
- name: test-env2-conf # 环境变量名称2
valueFrom:
configMapKeyRef:
name: con-key-value-test # 引入configmap
key: class.
[root@k8s-master zhanglei]# kubectl create -f dep-conf-test.yaml
deployment.apps/nginx-conf-env-test created
[root@k8s-master zhanglei]# kubectl get pod |grep env-test
nginx-conf-env-test-56f5c9b88-xt86x / Running 34s

可以看到Pod处于running的状态,登入到容器验证下以存在环境变量,如下所示,验证成功,值得注意的是,这种方式相当于新生成的环境变量指向configmap中的key所对应的value

root@nginx-conf-env-test-56f5c9b88-xt86x:/# ls
bin docker-entrypoint.d home media proc sbin tmp
boot docker-entrypoint.sh lib mnt root srv usr
dev etc lib64 opt run sys var
root@nginx-conf-env-test-56f5c9b88-xt86x:/# env
test-env2-conf=502 # 环境变量=原class.1的value
test-env1-conf=

五、总结

configmap是K8s中重要的配置管理方式,本文介绍了configmap的概念、使用场景、多种创建的方式、最后介绍了如何进行使用。

作者简介:云计算容器\Docker\K8s\Serverless方向产品经理,学点技术,为更好地设计产品。

【原创】Kuberneters-ConfigMap的实践的更多相关文章

  1. 【原创 Hadoop&Spark 动手实践 12】Spark MLLib 基础、应用与信用卡欺诈检测系统动手实践

    [原创 Hadoop&Spark 动手实践 12]Spark MLLib 基础.应用与信用卡欺诈检测系统动手实践

  2. 【原创 Hadoop&Spark 动手实践 13】Spark综合案例:简易电影推荐系统

    [原创 Hadoop&Spark 动手实践 13]Spark综合案例:简易电影推荐系统

  3. 【原创 Hadoop&Spark 动手实践 8】Spark 应用经验、调优与动手实践

    [原创 Hadoop&Spark 动手实践 7]Spark 应用经验.调优与动手实践 目标: 1. 了解Spark 应用经验与调优的理论与方法,如果遇到Spark调优的事情,有理论思考框架. ...

  4. 【原创 Hadoop&Spark 动手实践 9】Spark SQL 程序设计基础与动手实践(上)

    [原创 Hadoop&Spark 动手实践 9]SparkSQL程序设计基础与动手实践(上) 目标: 1. 理解Spark SQL最基础的原理 2. 可以使用Spark SQL完成一些简单的数 ...

  5. 【原创 Hadoop&Spark 动手实践 10】Spark SQL 程序设计基础与动手实践(下)

    [原创 Hadoop&Spark 动手实践 10]Spark SQL 程序设计基础与动手实践(下) 目标: 1. 深入理解Spark SQL 程序设计的原理 2. 通过简单的命令来验证Spar ...

  6. 【原创 Hadoop&Spark 动手实践 11】Spark Streaming 应用与动手实践

    [原创 Hadoop&Spark 动手实践 11]Spark Streaming 应用与动手实践 目标: 1. 掌握Spark Streaming的基本原理 2. 完成Spark Stream ...

  7. 【原创 Hadoop&Spark 动手实践 6】Spark 编程实例与案例演示

     [原创 Hadoop&Spark 动手实践 6]Spark 编程实例与案例演示 Spark 编程实例和简易电影分析系统的编写 目标: 1. 掌握理论:了解Spark编程的理论基础 2. 搭建 ...

  8. 【原创 Hadoop&Spark 动手实践 7】Spark 计算引擎剖析与动手实践

    [原创 Hadoop&Spark 动手实践 7]Spark计算引擎剖析与动手实践 目标: 1. 理解Spark计算引擎的理论知识 2. 动手实践更深入的理解Spark计算引擎的细节 3. 通过 ...

  9. 原创:路由配置实践 两个局域网主机的互连 VM linux

    又开始齐天大圣讲课的时间了 我相信网络是每个运维人员和开发人员必不可少要接触的   今天我们要讲的是在VM虚拟机中 我们三台虚拟机划分两个局域网 实现不同局域网的互联 也就是下面图中的AC通过B主机的 ...

  10. 【原创 Hadoop&Spark 动手实践 5】Spark 基础入门,集群搭建以及Spark Shell

    Spark 基础入门,集群搭建以及Spark Shell 主要借助Spark基础的PPT,再加上实际的动手操作来加强概念的理解和实践. Spark 安装部署 理论已经了解的差不多了,接下来是实际动手实 ...

随机推荐

  1. PHP quoted_printable_encode() 函数

    定义和用法 quoted_printable_encode() 函数把 8 位字符串转换为 quoted-printable 字符串. 提示:经过 quoted-printable 编码后的数据与通过 ...

  2. PDO::rollBack

    PDO::rollBack — 回滚一个事务(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 bool PDO::rollBack ( void )高佣联 ...

  3. 问题记录,php webserver端跨子域setcookie后浏览器不存

    如题. path已设置成/,domain也已指定成父级域名,数据包response中可见Set-Cookie header为期望的cookie数据,但浏览器就是不接收.存储该cookie, 浏览器端也 ...

  4. C++的常用输入及其优化以及注意事项

    $\mathcal{P.S:}$ 对于输入方式及其优化有了解的大佬可直接阅读$\mathcal{Part}$ $\mathcal{2}$ 特别鸣谢:@归斋目录: $\mathcal{Part}$ $\ ...

  5. 一、elasticsearch部署

    Elasticsearch官网: https://www.elastic.co/products/elasticsearch 一.Linux单节点部署 1. 解压elasticsearch-5.6.1 ...

  6. Qt数据库 QSqlTableModel实例操作(转)

    本文介绍的是Qt数据库 QSqlTableModel实例操作,详细操作请先来看内容.与上篇内容衔接着,不顾本文也有关于上篇内容的链接. Qt数据库 QSqlTableModel实例操作是本文所介绍的内 ...

  7. 每日一道 LeetCode (8):删除排序数组中的重复项和移除元素

    每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...

  8. 19、Java 序列化

    1.序列化的概念,意义以及使用场景 序列化: 将对象写入到IO流中,也就是把Java对象转换为字节序列的过程 反序列化: 从IO流中恢复对象*,也就是把字节序列恢复为Java对象的过程 意义: 序列化 ...

  9. C# Thread.Join的报错情形——论执行完的线程能够成功执行Join吗

    结论: 能, 执行完的线程调用Join不会抛出错误. Thread.Join()是什么? Join()函数用于阻塞地等待线程结束, 其行为是在线程A中调用了线程B的Join()后, 线程A将一直阻塞在 ...

  10. 安装Scrapy过程中遇到的几个问题总结

    安装Scrapy 1.https://www.lfd.uci.edu/~gohlke/pythonlibs/下载 Twisted 安装 Twisted-19.10.0-cp37-cp37m-win_a ...