深入探究 K8S ConfigMap 和 Secret
ConfigMap
1、什么是 ConfigMap?
ConfigMap 是用来存储配置文件的 Kubernetes 资源对象,配置对象存储在 Etcd 中,配置的形式可以是完整的配置文件、key/value 等形式。
2、ConfigMap 能带来什么好处?
传统的应用服务,每个服务都有自己的配置文件,各自配置文件存储在服务所在节点,对于单体应用,这种存储没有任何问题,但是随着用户数量的激增,一个节点不能满足线上用户使用,故服务可能从一个节点扩展到十个节点,这就导致,如果有一个配置出现变更,就需要对应修改十次配置文件。这种人肉处理,显然不能满足线上部署要求,故引入了各种类似于 ZooKeeper 中间件实现的配置中心,但配置中心属于 “侵入式” 设计,需要修改引入第三方类库,它要求每个业务都调用特定的配置接口,破坏了系统本身的完整性,而Kubernetes 利用了 Volume 功能,完整设计了一套配置中心,其核心对象就是ConfigMap,使用过程不用修改任何原有设计,即可无缝对 ConfigMap;为什么呢?
如图(1)所示,
1.ConfigMap 相当于放入原生应用的配置文件,可以是一个或者多个;
2.容器启动之后,到宿主机中拉取 ConfigMap 的内容,生成本地文件,通过 volume 形式映射到容器内部指定目录上;
3.容器中应用程序按照原有方式读取容器特定目录上的配置文件。
在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。
3、ConfigMap 三种创建方式
- 指定字面键值对进行创建,创建命令如下所示:
kubectl create configmap configmaptest --from-literal=foo=bar --from-literal=one=two
创建完成后通过如下方式查看:
# kubectl get configmap configmaptest -o yaml
apiVersion: v1
data:
foo: bar
one: two
kind: ConfigMap
metadata:
creationTimestamp: "2020-04-14T13:53:42Z"
name: configmaptest
namespace: default
resourceVersion: "613402"
selfLink: /api/v1/namespaces/default/configmaps/configmaptest
uid: 59b91eb4-7e57-11ea-83c7-509a4c36e19d
- 指定特定文件进行创建
kubectl create configmap config-files --from-file=/home/conf/db.properties
可以通过如下方式进行查看,(内容过长,影响阅读,省略 ConfigMap 元信息。)
# kubectl get configmap test-config -o yaml
apiVersion: v1
data:
db.properties: |
driverClassName=com.mysql.jdbc.Driver
......
- 指定特定文件夹进行创建
kubectl create configmap config-dir --from-file=/home/conf/config-test
通过如下方式进行查看
# kubectl get configmap config-test -o yaml
apiVersion: v1
data:
db.properties: |
# 数据源配置
driverClassName=com.mysql.jdbc.Driver
......
logback.xml: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"true\"
......
svc.properties: |
#server
protocol=tcp
.......
system.properties: |
time=100
.......
如上描述三种基本的 ConfigMap 创建方式,当然也可以使用合并不同选项进行创建配置文件,具体如下所示:
kubectl create configmap config-mix --from-file=/home/conf/biz/ --from-file=/home/conf/db.xml --from-literal=one=two
看到这么多,你可能会想到,--from-file
最后一级如果是文件夹会怎样呢?如你所想,文件夹其实不会被包含,只会查找最后一级目录下的文件。
4、ConfigMap 作为环境变量三种使用方式
- 单个引用
1.首先创建 ConfigMap
kubectl create configmap nginx-config --from-literal=code=25 --from-literal=foo=bar --from-literal=one=two
2.Deployment yaml中引用 ConfigMap 设置环境变量,如图(2)所示
键名是CODE-TIME,值是configmap中名为nginx-config的键是code的值
3.通过如下方式进行查看,环境变量是否生效,可以发现,容器环境中已经存在引用ConfigMap中的环境变量
# kubectl exec nginx-7c958f6448-z5q56 -it /bin/bash
[root@nginx-7c958f6448-z5q56 /]# env|grep CODE
CODE-TIME=25
- 多个引用
1.一次性传递所有ConfigMap条目作为环境变量,如图(3)所示
可以通过如下方式进行查看环境变量是否生效,如下所示每个环境变量都按照预设,添加了配置的前缀,有人可能要说,我的配置文件中原来是什么配置现在还保留什么配置,不需要添加预设前缀,那么请查看如图(4)通过把前缀设置为空串,即可保持原有配置方式。
# kubectl exec nginx-84ccdff98d-vgzcw -it /bin/bash
[root@nginx-84ccdff98d-vgzcw /]# env|grep CODE
CODE_foo=bar
CODE_code=25
CODE_one=two
- args 方式传递环境变量
容器启动时,传递该变量到服务,运行 shell 脚本,可能会用到,具体设置方式如图(5)所示:
以上解释了通过在 yaml 设置 env 引用 ConfigMap 中配置作为环境变量的使用,在使用过程中,我参考了 《Kubernetes In Action》这本书,发现此书中有一段是这样描述的,如图(6)所示:
其大概意思是,配置键中不能包含破折号,如果包含则不能设置到环境变量中,此书这部分是基于 Kubernetes 1.6 进行编撰,而我使用的是 kubernetes 1.14,不清楚是不是因为 Kubernetes 已经改进的原因,还是其他原因,我有两点不解的地方。破折号(——)大多都是指特别长的符号,在编码过程中很少有人使用这个,即使使用了,Kubernetes 根本无法保存成功。又何谈环境变量一说呢?会提示如图(7),图(8)所示错误:
如果破折号换成英文半角字符 - 中划线呢?如图(9)所示,是可以保存成功的。当然也可以用于环境变量中。
当然通过如上方式设置完成之后,就可以直接在容器内部使用环境变量读取已经设置的配置,但是使用环境变量的方式有一个致命的缺点是,当外部 ConfigMap 更新配置完成之后,容器内部环境变量并不会随之改变,这是因为 ENV 是容器启动时候注入的,启动之后 Kubernetes 就不会改变 ENV 的值,即配置不能同步更新,只能通过重启容器方式,配置才能生效。
5.挂载 volume
这种方式则是通过 volume 形式映射到容器内部指定目录上,容器内部进程直接读取该目录下特定文件,这种方式是我们常用的一种方式,具体使用时如下所示:
......
- containerPort: 80
volumeMounts:
- mountPath: /usr/local/nginx/conf/vhost/
name: http
- mountPath: /usr/local/nginx/html/foo
subPath: foo
name: nginx-html
volumes:
- name: http
configMap:
name: nginx-conf
- name: nginx-html
configMap:
name: configmaptest
items:
- key: foo
path: foo
......
volumeMounts 是容器内部指定挂载目录,volumes 是引用目录,即宿主机设置 ConfigMap 文件地址。
- 可以直接挂载一个目录到容器内部,当宿主机通过如下方式修改 configmap 那么容器内部配置将随之改变,一次性修改所有文件。但是使用这种方式有一个问题需要注意,如果挂载到容器内部的文件夹下存在其它文件,这种挂载方式将直接覆盖原有文件夹下的文件。
# kubectl edit configmap configmaptest
configmap/configmaptest edited
如果有特定需求,需要挂载某个特定文件,而不允许覆盖原有文件,可以挂载到指定文件,通过 subPath 配合指定文件。但是单个文件挂载这种方式不能实现热更新,即宿主机 ConfigMap 文件发生变化,容器内部不会自动重载。
至于 items 使用就比较简单了,如果一个 ConfigMap 中包含多个配置文件,但是只想暴露出来其中一部分,那么可以通过 items 方式进行指定。当然你也可以对文件设置读写权限。
Secret
Secret 使用类似于 ConfigMap,支持两种形式的使用:
- 将 Secret 作为环境变量暴露给容器进程使用。
- 将 Secret 通过volume 数据卷提供给容器进程使用。
看到这里你可能要说了,什么都一样,为啥还要 Secret,一个 ConfigMap 解决问题不就完事了,其实不然,Secret 顾名思义,是用于存储加密数据的,老版本 Kubernetes 只支持 base64 加密,学过计算机的都知道 base64 那就不是什么加密,只是对字符串进行了 encode 编码,通过 decode 直接可以解出明文。但后来新版本的 Kubernetes 已经实现了真正意义上的加解密,所以 Secret 存在是有一定意义的,使用方式跟 ConfigMap 类似,但是命令确不一样。
1.创建 Secret 输入如下:
kubectl create secret generic nginx-ssl --from-file=ca.key --from-file=ca.cert
2.查看 Secret 输入如下所示:
# kubectl get secret
NAME TYPE DATA AGE
default-token-7h5z9 kubernetes.io/service-account-token 3 6d13h
nginx-ssl Opaque 2 21h
# kubectl get secret nginx-ssl -o yaml
apiVersion: v1
data:
ca.crt: QmFnIEF0dHJpYnV0ZXMKICAgIGZy.......................
ca.key: QmFnIEF0dHJpYnV0ZXMKICAgIGZy......................
kind: Secret
.....................
3.Pod 引用方式
.....................
- containerPort: 80
volumeMounts:
- mountPath: /home/nginx/nginx/conf/cert/
name: nginx-ssl
volumes:
- name: nginx-ssl
secret:
secretName: nginx-ssl
.....................
应用程序怎么做到不重启情况下读取最新配置
上面已经提及使用环境变量和单文件挂载形式,无法实现热更新,但是通过 数据卷形式可以实现宿主机和 Pod 内部读取配置的实时更新,但是有一点需要注意的是 ConfigMap 更新,数据卷也更新了,如果你的应用进程不进行配置重载,即实时读取配置数据,同样还是使用的老配置。这个问题可以通过把 Pod 的副本数减少到 0 进行重建 Pod 解决。这种方式虽然能够解决服务重新加载问题,但是也会带来问题。因为可能会导致同一套服务,配置不一致的问题,因此,如果业务对实时性要求高,建议改成服务实时加载配置。
总结一下,Kubernetes 只是把配置实时同步到数据卷配置文件中,至于加载时机,还要看自己的应用程序。
举个例子,nginx 配置存储在 Kubernetes ConfigMap 里面,公钥信息存储在 Secret 中,nginx 充当服务里面的反向代理,因为端口资源规划问题,需要修改 nginx 配置文件中端口,修改完成后,Pod 中的数据卷配置信息发生变化,但 nginx 并不会重载已经修改的配置信息。通过如下命令行修改,修改完成后,发现 Pod 中 nginx 配置生效。
kubectl exec nginx -c nginx -- /usr/local/nginx/sbin/nginx -s reload
深入探究 K8S ConfigMap 和 Secret的更多相关文章
- k8s之configmap和secret
1.configmap configmap和secret是两种特殊的存储卷,它们不是给pod提供存储空间用的,而是给管理员或者用户提供了从外部向pod内部注入信息的方式. configmap:把配置文 ...
- 容器编排系统K8s之ConfigMap、Secret资源
前文我们了解了k8s上的pv/pvc/sc资源的使用和相关说明,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14188621.html:今天我们主要来聊一下 ...
- k8s env、configmap、secret外部数据加载配置
K8s提供了多种外部数据注入容器的方式,今天我们主要学习环境变量.ConfigMap以及Secret的使用和配置. 环境变量 在docker项目中,对一个容器添加环境变量可以在容器创建时通过-e EN ...
- kubernetes系列12—二个特色的存储卷configmap和secret
本文收录在容器技术学习系列文章总目录 1.configmap 1.1 认识configmap ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件.ConfigMa ...
- kubernetes ConfigMap和Secret:配置应用程序
7.1.配置容器化应用程序 7.2.向容器传递命令行参数 7.2.1.待Docker中定义命令与参数 1.了解ENTRYPOINT与CMD ENTRYPOINT定义容器启动时被调用的可以执行程序 CM ...
- K8s configMap原理介绍
给容器内应用程序传递参数的实现方式: 1. 将配置文件直接打包到镜像中,但这种方式不推荐使用,因为修改配置不够灵活. 2. 通过定义Pod清单时,指定自定义命令行参数,即设定 args:[" ...
- Kubernetes 学习13 kubernetes pv pvc configmap 和secret
一.概述 1.我们在pvc申请的时候未必就有现成的pv能正好符合这个pvc在申请中指定的条件,毕竟上一次的成功是我们有意设定了有一些满足有一些不满足的前提下我们成功创建了一个pvc并且被pod绑定所使 ...
- 九,configMap及secret的基本使用
目录 制定容器配置的方式 configMap(存储数据为明文,敏感数据慎用) 创建configMap的几种方式 命令行创建和测试configMap实例 创建一个Pod 挂载测试 通过指定文件创建con ...
- K8S ConfigMap使用
k8s系列文章: 什么是K8S configmap是k8s的一个配置管理组件,可以将配置以key-value的形式传递,通常用来保存不需要加密的配置信息,加密信息则需用到Secret,主要用来应对以下 ...
随机推荐
- Graph-Based Social Relation Reasoning
title: Graph-Based Social Relation Reasoning, 2020 task: we propose a simpler, faster, and more accu ...
- Windows对拍系统
有个东西可以帮助对拍,告诉你两个程序的输出哪不一样(但是无法得知错误位置,聊胜于无吧) 一.打开计算机 二.在上方输入$cmd$,摁下回车 三.弹出对话窗如下,输入$fc +$空格,输入两个需要比较 ...
- c语言编译器介绍
目录 一.IDE(集成开发环境) 1.windows 编译器 2.Mac中使用 二.环境安装 1.windows安装gcc A.进入安装所在目录,找到MinGW. B.找到我的电脑,右键选择属性. C ...
- BZOJ1874 「一本通 6.7 练习 1」【一本通提高博弈论】取石子游戏
「一本通 6.7 练习 1」取石子游戏 题目描述 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游 ...
- NoSQL,关系型数据库,行列数据库对比、类比
数据库对比.类比 关系型数据库.NoSQL 关系型数据库 表与表之间有关系.表存储一些格式化的数据结构,每个元组字段的组成都一样,这样便于表之间的联结操作.不过也限制了其性能瓶颈. 更支持SQL,支持 ...
- 常用的函数式接口_Prodicate接口_默认方法or&negate和常用的函数式接口_Predicate接口练习_集合信息筛选
常用的函数式接口_Prodicate接口_默认方法or&negate OR package com.yang.Test.PredicateStudy; import java.util.fun ...
- fiddler抓包手机请求(转)
http://ju.outofmemory.cn/entry/22854 从事前端开发的同学一定对Fiddler不陌生,它是一个非常强大的http(s)协议分析工具,如果你不知道它是什么,可以自行go ...
- python对象的独有功能与面向对象的特征
目录 对象的独有功能 动静态方法 面向对象的特征 面向对象的的三大特征 继承的本质 不继承的名字查找顺序 单继承的名字查找顺序 多继承的名字查找顺序 经典类与新式类 派生方法 对象的独有功能 1.定义 ...
- 循环结构——while、do-while、for循环
1.while循环 语法格式: while(条件判断){ 循环体 } 解释: (1)关键字while后的小括号中的内容时循环条件. (2)循环条件是一个布尔表达式,它的值为布尔类型 "真&q ...
- [WPF]使用DispatcherUnhandledException捕捉未经处理的异常
使用DispatcherUnhandledException捕捉未经处理的异常 using System.Windows; namespace Test02 { /// <summary> ...