多环境配置管理:环境变量、配置中心和文件挂载的适用场景
前段时间帮朋友收拾一个项目,开发、测试、生产三套配置,一开始全写在 application.yml 里,改一次环境就提交一次,最后 git 历史里全是“改数据库地址”“改 redis 地址”这种提交。后来他又听说配置中心高级,差点直接上 Nacos,我赶紧拦住:就三个服务、七八个配置项,真没必要。配置管理这事儿,不是越高级越好,关键是看你的配置有多少、变化有多快、是不是敏感。下面按我自己的使用习惯,聊聊环境变量、配置中心、文件挂载分别适合什么场景。
环境变量:少量、标量、跟部署走
环境变量最适合那种“镜像不变,部署时注入”的配置。比如数据库连接串、日志级别、外部 API 地址,这些量不大、结构简单、每个环境不一样的东西,用环境变量很舒服。Docker Compose 里写起来也直观:
services:
api:
image: my-api:1.2.3
environment:
DATABASE_URL: postgres://user:pass@db:5432/app
LOG_LEVEL: info
好处是容器友好,CI/CD 里直接注入,不用为了改一个地址重新打镜像。Kubernetes 里用 env 或 envFrom 也方便。但它的问题也很明显:一多就乱。十几个环境变量散在部署脚本里,谁覆盖谁都不清楚;JSON、多行文本、数组这种结构化配置塞进环境变量,基本是给自己找罪受;类型也弱,true 和 "true" 经常让人愣一下。还有一点,环境变量不是保险箱,docker inspect 就能看到,敏感信息别随便往里扔。我一般只把环境变量用在“少量标量差异”上,比如连接串、开关、级别,不会把整份 nginx 配置拆成环境变量。
文件挂载:结构化配置和证书的舒服区
只要配置开始有层级、有注释、有证书文件,我就倾向文件挂载。比如 nginx.conf、prometheus.yml、证书、私钥,这些玩意儿写成环境变量纯属折磨。Docker 里挂载一个只读文件很直接:
docker run -d \
-v $(pwd)/config/prod.yaml:/app/config.yaml:ro \
-v $(pwd)/certs:/app/certs:ro \
my-api:1.2.3
Kubernetes 里的 ConfigMap 和 Secret 挂载本质上也是这个思路。文件挂载的好处是可读、可版本化、支持复杂结构,改完文件重启或 reload 就行。缺点也有:挂载更新后应用不一定自动加载,很多服务得重启;路径和权限容易踩坑,尤其是 Secret 文件,权限最好收紧;配置文件跟部署环境耦合,路径写死以后换平台要改。我的经验是,完整配置文件、证书、密钥这类东西,优先挂载,别硬塞环境变量。敏感文件挂载也比明文环境变量稍微体面一点,当然前提是权限管好。
配置中心:服务多了、需要动态变更再上
配置中心适合什么?服务多、团队多、配置需要共享、需要动态刷新、需要审计和灰度开关的时候。比如微服务里几十个服务共用一些限流阈值、功能开关,改完希望不重启就生效,这时候 Nacos、Apollo、Consul、etcd 这类东西才有价值。它解决的是“集中管理”和“动态变更”,不是“配置没地方放”。
但配置中心是有成本的。你得部署、运维、做高可用,应用要引入客户端依赖,网络抖一下可能启动都受影响,还要考虑本地缓存和降级。我之前见过一个项目,为了两个功能开关搭了一套配置中心,结果配置中心自己成了单点,每次发版先祈祷它别挂。小项目、少量配置,真别折腾。配置中心更适合那种配置已经多到靠人脑记不住、靠文件同步容易出错的阶段。
我一般怎么组合
实际项目里很少只用一种。我一般这么分:非敏感的默认值放代码里的配置文件;环境差异用环境变量覆盖;证书、私钥、完整服务配置用文件挂载;需要跨服务共享、动态刷新的才放配置中心。优先级大致是配置中心 > 环境变量 > 文件默认值,但别搞太花,否则排查问题时一层套一层,自己都想骂人。
小项目用 .env 加 Compose 挂载就够;K8s 项目用 ConfigMap/Secret 挂载加少量 env;微服务多了再考虑配置中心。几个坑提前说下:环境变量别当保险箱;配置中心不是银弹;挂载文件改完记得确认应用是否 reload;配置项命名别一个环境一个样;默认值一定要有,不然少一个变量直接起不来。
说到底,配置管理不是越高级越好,而是让改配置的人知道去哪儿改、让排查问题的人知道当前生效的是哪一份。能跑、能查、能回滚,比啥都强。
评论
还没有评论。
发表评论
提交后评论将经过自动审核,审核通过后公开展示。