百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

13、ConfigMap密文配置资源

mhr18 2024-11-30 12:56 15 浏览 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,所以在非容器化模式中,也可以使用配置中心,要使用配置中心还需要我们的程序支持从配置中心加载配置才行;

相关推荐

京东大佬问我,每天新增100w订单数据的分库分表方案

京东大佬问我,每天新增100w订单数据的分库分表方案嗯,用户问的是高并发订单系统的分库分表方案,每天新增100万订单。首先,我得理解需求。每天100万订单,那每秒大概是多少呢?算一下,100万除以86...

MySQL 内存使用构成解析与优化实践

在为HULK平台的MySQL提供运维服务过程中,我们常常接到用户反馈:“MySQL内存使用率过高”。尤其在业务高峰期,监控中内存占用持续增长,即便数据库运行正常,仍让人怀疑是否存在异常,甚至...

阿里云国际站:怎样计算内存优化型需求?

本文由【云老大】TG@yunlaoda360撰写一、内存优化型实例的核心价值内存优化型ECS实例专为数据密集型场景设计,具有以下核心优势:高内存配比:内存与CPU比例可达1:8(如ecs.re6....

MySQL大数据量处理常用解决方案

1、读写分离读写分离,将数据库的读写操作分开,比如让性能比较好的服务器去做写操作,性能一般的服务器做读操作。写入或更新操作频繁可以借助MQ,进行顺序写入或更新。2、分库分表分库分表是最常规有效的一种大...

1024程序员节 花了三个小时调试 集合近50种常用小工具 开源项目

开篇1024是程序员节了,本来我说看个开源项目花半个小时调试之前看的一个不错的开源项目,一个日常开发常常使用的工具集,结果花了我三个小时,开源作者的开源项目中缺少一些文件,我一个个在网上找的,好多坑...

免费全开源,功能强大的多连接数据库管理工具!-DbGate

DBGate是一个强大且易于使用的开源数据库管理工具,它提供了一个统一的Web界面,让你能够轻松地访问和管理多种类型的数据库。无论你是开发者、数据分析师还是DBA,DBGate都能帮助你提升工作效率...

10个最佳的开源免费的酒店系统,接私活创业拿来改改
  • 10个最佳的开源免费的酒店系统,接私活创业拿来改改
  • 10个最佳的开源免费的酒店系统,接私活创业拿来改改
  • 10个最佳的开源免费的酒店系统,接私活创业拿来改改
  • 10个最佳的开源免费的酒店系统,接私活创业拿来改改
使用operator部署Prometheus

一、介绍Operator是CoreOS公司开发,用于扩展kubernetesAPI或特定应用程序的控制器,它用来创建、配置、管理复杂的有状态应用,例如数据库,监控系统。其中Prometheus-Op...

java学习总结

SpringBoot简介https://spring.io/guideshttp://www.spring4all.com/article/246http://www.spring4all.com/a...

Swoole难上手?从EasySwoole开始

前言有些童鞋感觉对Swoole不从下手,也不知在什么业务上使用它,看它这么火却学不会也是挺让人捉急的一件事情。Swoole:面向生产环境的PHP异步网络通信引擎啥是异步网络通信?10年架构师领你架...

一款商用品质的开源商城系统(Yii2+Vue2.0+uniapp)

一、项目简介这是一套很成熟的开源商城系统【开店星】,之前推过一次,后台感兴趣的还不少,今天再来详细介绍一下:基于Yii2+Vue2.0+uniapp框架研发,代码质量堪称商用品质,下载安装无门槛,UI...

Yii2中对Composer的使用

如何理解Composer?若使用Composer我们应该先知道这是一个什么东西,主要干什么用的,我们可以把Composer理解为PHP包的管理工具,管理我们用到的Yii2相关的插件。安装Compose...

SpringBoot实现OA自动化办公管理系统源码+代码讲解+开发文档

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的自动化OA办公管理系统,主要实现了日常办公的考勤签到等一些办公基本操作流程的全部功能,系统分普通员工、部门经理、管理员等...

7层架构解密:从UI到基础设施,打造真正可扩展的系统

"我们系统用户量暴增后完全崩溃了!"这是多少工程师的噩梦?选择正确的数据库只是冰山一角,真正的系统扩展性是一场全栈战役。客户端层:用户体验的第一道防线当用户点击你的应用时,0.1秒...

Win11系统下使用Django+Celery异步任务队列以及定时(周期)任务

首先明确一点,celery4.1+的官方文档已经详细说明,该版本之后不需要引入依赖django-celery这个库了,直接用celery本身就可以了,就在去年年初的一篇文章python3.7....

取消回复欢迎 发表评论: