13、ConfigMap密文配置资源
mhr18 2024-11-30 12:56 19 浏览 0 评论
ConfigMap
环境变量方式配置
volume方式配置
配置中心概念
ConfigMap
Kubernetes是一个容器编排平台,虽然它又额外加了一层外层Pod,并以容器的方式来运行应用程序的特定,在Docker时代所面临的配置容器化应用的问题,在Kubernetes时代依然存在,如果想配置应用程序,我们想用到的途径和方式无非是两种;
第一如果程序的镜像是云原生的,或者借助于entrypoint脚本能够通过传递环境变量接受参数,完成配置这是一种比较轻量化的配置方式,在启动容器时传递几个环境变量,分别代表着几个重要的配置参数,从而完成应用程序配置;
第二以Nginx为例,启动Nginx需要加载我们自定义的配置文件模块,我们还可以使用存储卷的方式进行配置文件的传递,将外部的配置文件加载到容器内部
这两种配置方式有缺陷,如果使用环境变量配置的话,环境变量是在容器启动时被装入的,然后进行替换,一旦替换就没法更改了,如果想修改某一个参数的值,只能重新启动容器,如果使用存储卷的方式去做,存储卷中的内容也是在进程启动时被装入的,后面就算修改了存储卷的配置,也还是需要手动触发进程reload加载新的配置;
如果说我们在一个Pod控制器下,控制有五个Pod,这个五个Pod配置信息应该都是一样的,意味着这五个Pod他们会共享同一个存储卷,如果修改了存储卷的当中的内容,很显然,这个五个Pod都能加载到新的内容,但是这五个Pod都得进程重载,这就很麻烦了,尤其在以后使用Hpa控制器的时候,它会根据用户的访问量来自定伸缩Pod副本,那这个时候就完全不知道该重载哪些Pod,所以在这种情况之下,一样会面临复杂的配置问题,这个时候最好能够提供一种机制,让我们可以改完配置信息以后能自动被相关的Pod重载,而且能够一对多,只需要改一遍,所有加载这个配置文件的Pod都能够被自动进行重载;
在kubernetes之上用于实现配置自动重载的功能的组件,他们分别是ConfigMap、Secret,他们都是用于把配置文件配置为Kubernetes资源,其中ConfigMap用于提供非敏感配置,而Secret用户配置敏感配置信息(密码、密钥等)进行编码存放,他们内部存储的都是键值对,而这种键值,键可以是我们的配置参数,值可以做得很复杂,比如我们可以把一个配置文件的文件名当作键,整个文件的配置当作值;
这样子也就意味着我们常见的配置文件,都可以直接被实例化为ConfigMap中的键值对象,所以一个ConfigMap就是一个键值存储系统,我们一旦定义好ConfigMap需要在我们的Kubernetes中的Pod调用有两种方式;
第一,我们可以在Kubernetes容器中,把每一个Key的Value映射为这个容器内部环境变量的值,比如我们在一个Pod中有一个环境变量名是MYSQL_USER它的值可以来自于一个ConfigMap的键的值,我们向MYSQL_USER值不是直接赋值而是给它赋值一个ConfigMap中的键,从而他能够实现键的替换,然后也就能够被我们的应用程序引用到;
Kubernetes的ConfigMap和Pod都是标准的Kubernetes资源,因此在这种情况下有一个名称空间,我们做了有一个ConfigMap,在这个ConfigMap种我们定义了两个数据项第一叫redis_host值为172.16.1.1,第二叫redis_port值为6379,随后我们配置一个Pod,这个Pod是一个filebeat,这个Pod能够通过一个环境变量来引用redis主机和端口的配置,对应环境变量名是的host和prot,那么我们就可以这样定义Pod,“host:redis-cfg.redis_host,port:redis_port”,以后我们想要修改配置只需要配置ConfigMap即可,但是这种引用有一个缺陷,就是只要你把Pod启动起来就不会再重新获取值了,也就意味着后面我们修改了ConfigMap里面的数据也不会被Pod加载到,这个时候 还是需要重建来进行加载新配置,这是环境变量的缺陷;
还有一种方式,ConfigMap资源可以直接被Pod当作容器使用,比如配置一个Nginx,Nginx是可以在/etc/nginx/conf.d目录中去装载我们Nginx配置文件的,因此我们仍然定义一个ConfigMap资源,这个ConfigMap叫做nginx-cfg,它有一个键叫做server1.conf他里面还有一个键值比如server_name值为172.16.1.1,随后我们在定义Pod时候先定义一个存储卷,这个存储卷的类型是ConfigMap,它是ConfigMap中的存储卷,而这个卷也不是某个存储设备的存储空间,而就是引用了ConfigMap中的资源,我们可以通过存储卷的方式引用一个ConfigMap资源,而后在Nginx容器当中就可以把这个存储卷挂在到/etc/nginx/conf.d目录下,一旦我们挂在完成之后,它能够自动把这个server1.conf键映射成文件名,并且把server1.conf键的值映射为文件的内容,所以直接变成容器内部的/etc/nginx/conf.d下面的server.conf文件,更方便的是,这种引用方式,如果我们修改了ConfigMap里面的配置,过一个随机时长,可能几秒内,会自动同步到所有引用这个ConfigMap存储卷的Pod,而且一旦只要容器应用支持还重载,那么 同步完成之后它会自动重载容器应用,使得新配置生效,但是如果通过重载应用无法生效, 那就得需要重建Pod使配置生效,Secret也是一样,只不过数据做了一层base64加密;
环境变量方式配置
使用ConfigMap的方式配置,我们后面可以通过entrypoint脚本来进行配置替换,但是这种方式有一种缺陷,就是热修改配置的时候,Pod里面的应用不会重新加载配置;
# 创建一个名称空间
[root@node1 ~]# kubectl create ns config
# 创建一个configmap
[root@node1 ~]# kubectl create configmap -n config filebeat-cfg --from-literal=redis_host="redis.default.svc.cluster.local" --from-literal=redis_port="6379"
# 查看创建的configmap
[root@node1 ~]# kubectl get configmaps -n config filebeat-cfg -o yaml apiVersion: v1
data:
redis_host: redis.default.svc.cluster.local # 配置都存储在data对象下面
redis_port: "6379"
kind: ConfigMap
metadata:
creationTimestamp: "2019-11-29T07:20:47Z"
name: filebeat-cfg
namespace: config
resourceVersion: "34819"
selfLink: /api/v1/namespaces/config/configmaps/filebeat-cfg
uid: 592a60fc-9188-4782-b9af-dceac9766418
# 编写Pod配置
[root@node1 ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-test
namespace: config
spec:
restartPolicy: Always
containers:
- name: vol-pod
image: busybox:latest
command:
- /bin/httpd
- -f
env:
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: filebeat-cfg
key: redis_host
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: filebeat-cfg
key: redis_port
# 查看环境变量是否加载成功
[root@node1 config]# kubectl exec -it -n config config-test printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-test
TERM=xterm
REDIS_HOST=redis.default.svc.cluster.local
REDIS_PORT=6379 # 可以看到环境变量已经加载进来了
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
HOME=/root
# 测试修改configmap里面的值
[root@node1 config]# kubectl edit configmaps -n config filebeat-cfg
# 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:
redis_host: redis.default.svc.cluster.local
redis_port: "6380" # 修改为6380
kind: ConfigMap
metadata:
creationTimestamp: "2019-11-29T07:59:00Z"
name: filebeat-cfg
namespace: config
resourceVersion: "38149"
selfLink: /api/v1/namespaces/config/configmaps/filebeat-cfg
uid: aa81b1c9-a29a-4c73-b480-8146273d3c17
# 重新查看容器会发现环境变量没有重新加载
[root@node1 config]# kubectl exec -it -n config config-test printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-test
TERM=xterm
REDIS_HOST=redis.default.svc.cluster.local
REDIS_PORT=6379 # 没有变动
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
HOME=/root
# 手动删除Pod并重建查看是否是新的环境变量
[root@node1 config]# kubectl delete -f test.yaml
pod "config-test" deleted
[root@node1 config]# kubectl apply -f test.yaml
pod/config-test created
[root@node1 config]# kubectl exec -it -n config config-test printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=config-test
TERM=xterm
REDIS_HOST=redis.default.svc.cluster.local
REDIS_PORT=6380 # 配置已经变动
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
HOME=/root
volume方式配置
volume方式配置就是直接通过挂载configmap的方式将配置写入到Pod容器指定的路径下面,这种方式会自动加载新配置,但是有的程序是不支持reload的,以Nginx为例;
# 创建Nginx配置
[root@node1 nginx]# cat server1.conf server2.conf
server {
server_name 0.0.0.0;
listen 80;
location / {
root /data/wwwroot/server1;
}
}
server {
server_name 0.0.0.0;
listen 8080;
location / {
root /data/wwwroot/server2;
}
}
# 将nginx配置创建为ConfigMap资源
[root@node1 nginx]# kubectl create ns config-volume
[root@node1 nginx]# kubectl create configmap nginx-conf --from-file=server1=server1.conf --from-file=server2=server2.conf -n config-volume
configmap/nginx-conf created
[root@node1 nginx]# kubectl get configmaps -n config-volume -o yaml
apiVersion: v1
items:
- apiVersion: v1
data:
server1: "server {\n\tserver_name 0.0.0.0;\n\tlisten\t\t80;\n\tlocation / {\n\t\troot
/data/wwwroot/server1;\n\t}\n}\n"
server2: "server {\n\tserver_name 0.0.0.0;\n\tlisten\t\t8080;\n\tlocation / {\n\t\troot
/data/wwwroot/server2;\n\t}\n}\n"
kind: ConfigMap
metadata:
creationTimestamp: "2019-11-29T13:52:41Z"
name: nginx-conf
namespace: config-volume
resourceVersion: "6558"
selfLink: /api/v1/namespaces/config-volume/configmaps/nginx-conf
uid: 9e0ff284-70ae-4911-a975-7990b91a7373
kind: List
metadata:
resourceVersion: ""
selfLink: ""
# 配置Pod
[root@node1 nginx]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-volume-pod
namespace: config-volume
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
volumeMounts:
- name: conf # 要挂载volumes的名字
mountPath: /etc/nginx/conf.d # 挂载的目的目录
volumes:
- name: conf # 该volumes的名字
configMap:
name: nginx-conf # 要使用configMap的名字
items:
- key: server1 # 要使用指定configMap里面的键名
path: s1.conf # 挂载之后的文件名
- key: server2 # 要使用指定configMap里面的键名
path: s2.conf # 挂载之后的文件名
# 查看配置是否生效
[root@node1 nginx]# kubectl exec -it -n config-volume config-volume-pod /bin/sh
/ # ls /etc/nginx/conf.d/ # 两个配置文件已经加入进来
s1.conf s2.conf
/ # cat /etc/nginx/conf.d/* # 配置和我们定义的一致
server {
server_name 0.0.0.0;
listen 80;
location / {
root /data/wwwroot/server1;
}
}
server {
server_name 0.0.0.0;
listen 8080;
location / {
root /data/wwwroot/server2;
}
}
/ # netstat -ntlp # 端口也启动起来了
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1/nginx: master pro
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
/ #
# 测试修改配置
[root@node2 ~]# kubectl edit -n config-volume configmaps nginx-conf
configmap/nginx-conf edited
# 80变更为81,8080变更为8081
[root@node2 ~]# kubectl edit -n config-volume configmaps nginx-conf
# 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:
server1: "server {\n\tserver_name 0.0.0.0;\n\tlisten\t\t81;\n\tlocation / {\n\t\troot
/data/wwwroot/server1;\n\t}\n}\n"
server2: "server {\n\tserver_name 0.0.0.0;\n\tlisten\t\t8081;\n\tlocation / {\n\t\troot
/data/wwwroot/server2;\n\t}\n}\n"
kind: ConfigMap
metadata:
creationTimestamp: "2019-11-29T13:52:41Z"
name: nginx-conf
namespace: config-volume
resourceVersion: "8765"
selfLink: /api/v1/namespaces/config-volume/configmaps/nginx-conf
uid: 9e0ff284-70ae-4911-a975-7990b91a7373
# 数秒后会发现Nginx配置文件已变更,但是nginx未重载,可以借助其他插件实现
[root@node1 nginx]# kubectl exec -it -n config-volume config-volume-pod cat /etc/nginx/conf.d/s1.conf
server {
server_name 0.0.0.0;
listen 81;
location / {
root /data/wwwroot/server1;
}
}
配置中心概念
Kubernetes用来配置分布式或者负载均衡集群化的配置中心,比如如果在nginx后面维护有20个tomcat,需要改修tomcat配置文件的一些配置信息,比如在修改tomcat连接redis的账号密码,那如何让20个tomcat都应用到新配置,此前的做法就是使用ansible,然后分批推,推的时候还需要以灰度的方式进行,如果一下全部推送那在某一时刻服务都无法访问了,所以即使借助了ansible来编排,也得一个一个来,但这种才20个,但是如果有30个或者更多这就比较麻烦了,所以很多规模非常大的网站都不会通过这种方式来配置应用程序,而是让应用程序所有配置都不通过本地配置文件加载,而是通过联系一个配置中心的服务去加载配置,所以称之为配置中心;
启动多个应用程序时,抛弃了传统从本地文件加载配置的方法,而是通过一个中心服务器来加载配置,这个服务叫做配置中心,随后我们在这个配置中心修改了配置以后,会通知给每一个进程,让进程自动进行重载,就能完成所有的进程进行重载,还可以以灰度的方式通知,那么他们就可以以灰度的方式去更新自己的配置信息;
国内有两个项目,为非容器化应用程序提供配置中心,协程的Apollo、百度的Distconf,所以在非容器化模式中,也可以使用配置中心,要使用配置中心还需要我们的程序支持从配置中心加载配置才行;
相关推荐
- 【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报
-
近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...
- 医院信息系统突发应急演练记录(医院信息化应急演练)
-
信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...
- 一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序
-
简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...
- docker搭建系统环境(docker搭建centos)
-
Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...
- 基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)
-
SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...
- Java21杀手级新特性!3行代码性能翻倍
-
导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...
- 一文读懂JDK21的虚拟线程(java虚拟线程)
-
概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...
- 效率!MacOS下超级好用的Linux虚拟工具:Lima
-
对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...
- 所谓SaaS(所谓三维目标一般都应包括)
-
2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...
- ORA-00600 「25027」 「x」报错(报错0xc0000001)
-
问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...
- 安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 编译安卓源码(编译安卓源码 电脑配置)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“
-
2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...
- Syslog 日志分析与异常检测技巧(syslog发送日志配置)
-
系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...
- 从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)
-
数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)