--- url: /sre/devops/environment.md --- # 环境变量与配置管理,一篇文章搞懂 ## 前言 随着项目越来越大、依赖越来越多,配置管理将显得越来越重要。 服务应用的哪些应该是配置?哪些写死到代码中? 哪些配置打包到 Dockerfile 镜像中,哪些在容器启动时动态加载? 多环境dev、test、prod下环境变量如何管理? 环境变量的优先级?当环境变量发生变化时,如何做到最小化修改? 为了回答上述问题,我学习相关知识并记录到了本文中。 ## 配置与环境变量 **配置**是一个广义的概念,指的是**一切影响应用程序行为、但又不属于其核心逻辑代码的数据或设置**。它回答了这些问题: * 数据库在哪台机器上? * 日志级别该多详细? * 功能A对用户开放吗? * 缓存多久失效? 让同一份应用程序**代码**,能在不同的环境(开发、测试、生产)、不同需求下,表现出不同的行为,而**无需重新编写和编译代码**。存在形式有多种:配置文件、数据库/配置中心、启动参数、**环境变量**等。 在容器化技术普遍流行的现代开发中,环境变量非常受宠,其与“不可变基础设施”理念契合:可以构建一个纯净的、不包含任何环境信息的 Docker 镜像。在启动容器时,通过环境变量将“它是生产环境”、“它的数据库连接串是XXX”这些信息“注入”进去。镜像不变,环境可变。 配置文件 什么是环境变量,什么是配置? 什么是配置,哪些写死的静态代码,哪些是作为配置?静态配置与动态配置? ## 云原生核心原则 12-Factor 原则说的那样:**把配置彻底从代码里剥离出来。** 在现代云原生开发中,遵循 12-Factor App 原则将配置与代码严格分离是构建可扩展、安全应用的基础。本文将探讨环境变量的核心原则、加载优先级以及在 Python 项目中的具体实践。 **核心原则** * 不提交敏感配置:.env 文件严禁提交至版本控制系统(Git)。必须在 .gitignore 中忽略,防止 API 密钥、数据库密码泄露。 * 配置与镜像分离:不要将 .env 打包进 Docker 镜像。镜像应保持环境无关性,通过运行时的容器编排工具注入变量。 * Fail-Fast(快速失败):程序启动时必须校验核心配置,若缺失或格式错误应立即报错退出,避免程序在不稳定的配置下运行。 ## 环境变量加载优先级 为了兼顾开发便利性和生产安全性,建议采用以下加载顺序(由低到高,高优先级覆盖低优先级): 代码默认值:在配置类中定义的硬编码默认值(仅限非敏感项)。 .env 文件:本地开发环境的配置文件。 Shell 环境变量:如执行 export APP\_PORT=8080。 Docker Compose:environment 块定义的变量。 集群管理工具:Kubernetes Secrets 或 ConfigMaps。 3. Python 实践示例 在 Python 中,pydantic-settings 是目前管理配置的事实标准,它提供了自动类型转换、验证和敏感信息保护功能。 3.1 统一配置类 使用 Pydantic 定义配置模型,可以自动从环境变量中读取同名变量。 ## 配置管理工具与编程实践 ## 参考