本文目录导读:

- 场景一:在 Kubernetes 中运行 Python 应用 ✅ 使用 ConfigMap
- 场景二:非 K8s 环境(本地开发、普通服务器、Docker 非 K8s) ❌ 不使用 ConfigMap
- 最佳实践建议
这是一个很关键的区分点。ConfigMap 是 Kubernetes 的概念,不是 Python 原生或通用的配置管理工具。
- 如果你的 Python 应用运行在 Kubernetes(K8s)集群中:是的,强烈推荐用 ConfigMap(或 Secret 用于敏感数据) 来管理配置。
- 如果你的 Python 应用是本地运行、普通服务器部署或非 K8s 环境:不使用 ConfigMap,而是使用 Python 原生的配置管理库(如
python-dotenv、configparser、pydantic-settings、环境变量等)。
在 Kubernetes 中运行 Python 应用 ✅ 使用 ConfigMap
当你的 Python 应用(Flask、Django、FastAPI 服务)作为 Pod 部署在 K8s 上时,ConfigMap 是管理非敏感配置(如数据库地址、日志级别、功能开关)的最佳实践之一。
如何使用?
创建 ConfigMap(可以通过 YAML 或命令行)
# config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: python-app-config
data:
DATABASE_URL: "postgresql://user:pass@db-host:5432/mydb"
LOG_LEVEL: "INFO"
FEATURE_NEW_UI: "true"
app_config.yaml: |
server:
host: "0.0.0.0"
port: 8080
cache:
ttl: 3600
在 Deployment 中挂载 ConfigMap 到 Pod
有两种主流方式:
- 方式 A:作为环境变量(适合简单键值对)
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: python-app
image: my-python-app:latest
envFrom:
- configMapRef:
name: python-app-config # 所有 key-value 变成环境变量
- 方式 B:作为文件挂载(适合复杂配置文件)
spec:
containers:
- name: python-app
volumeMounts:
- name: config-volume
mountPath: /app/config # 挂载目录
volumes:
- name: config-volume
configMap:
name: python-app-config
在 Python 代码中读取
import os
import yaml
# 方式 A:环境变量
db_url = os.getenv("DATABASE_URL")
log_level = os.getenv("LOG_LEVEL")
# 方式 B:读取文件(挂载的 ConfigMap 文件)
with open("/app/config/app_config.yaml", "r") as f:
config = yaml.safe_load(f)
host = config["server"]["host"]
port = config["server"]["port"]
对于敏感信息(密码、Token、API Key),请使用 Secret(与 ConfigMap 类似,但内容会被 Base64 编码,且 K8s 对它有额外的安全控制)。
非 K8s 环境(本地开发、普通服务器、Docker 非 K8s) ❌ 不使用 ConfigMap
ConfigMap 是 K8s 的 API 资源,脱离了 K8s 集群就无法使用,Python 社区有自己成熟的配置管理方案:
推荐工具组合(按优先级排列)
pydantic-settings(现代、类型安全、推荐)
# config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str = "sqlite:///default.db"
log_level: str = "DEBUG"
feature_new_ui: bool = False
class Config:
env_file = ".env" # 自动加载 .env 文件
settings = Settings()
print(settings.database_url) # 优先从环境变量读取,.env,最后默认值
优点:
- 强类型校验(自动转换
"true"到True) - 支持环境变量、
.env文件、YAML、JSON 等多种来源 - 兼容 K8s 环境变量挂载方式(迁移到 K8s 时不需要改代码)
python-dotenv + os.getenv(轻量级)
# 加载 .env 文件
from dotenv import load_dotenv
load_dotenv()
import os
DATABASE_URL = os.getenv("DATABASE_URL")
配置文件解析(传统方式)
# config.ini [DEFAULT] log_level = INFO [production] database_url = postgresql://prod:... domain = example.com
import configparser
config = configparser.ConfigParser()
config.read("config.ini")
# 读取
log_level = config["DEFAULT"]["log_level"]
db_url = config.get("production", "database_url", fallback="sqlite:///")
| 特性 | 使用 ConfigMap (K8s 环境) | 不使用 ConfigMap (通用 Python) |
|---|---|---|
| 运行环境 | 仅限 Kubernetes 集群 | 任何环境:本地、服务器、Docker、K8s 等 |
| 配置来源 | K8s API 对象 (YAML/CLI) | 环境变量、.env 文件、配置文件、命令行参数 |
| 变更生效方式 | Pod 重启或滚动更新 | 重启进程或热加载(需自行实现) |
| 敏感数据处理 | 用 Secret(建议) | 用环境变量或加密文件 |
| 类型校验 | 无(字符串形式存储) | 有(pydantic 等库) |
| 推荐工具 | 无(直接环境变量或挂载文件) | pydantic-settings、python-dotenv |
最佳实践建议
- 无论是否用 K8s,都优先使用环境变量:这是 12-Factor App 的标准做法,让代码与配置解耦。
- 在 K8s 中:ConfigMap 是你的配置中心,但最终以环境变量或文件形式注入到 Pod。
- 代码层面统一抽象:
- 使用
pydantic-settings定义配置模型 - 开发时读取
.env文件 - 部署到 K8s 时,ConfigMap 中的键值对映射为环境变量,
pydantic-settings会自动读取
- 使用
这样,你的 Python 应用既可以独立运行(读 .env),又可以无缝迁移到 K8s(读 ConfigMap 注入的环境变量),不需要修改任何代码。
# 一份代码,到处运行
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_prefix="MYAPP_")
settings = Settings()
# K8s 中:ConfigMap 注入 MYAPP_DATABASE_URL 环境变量
# 本地:.env 文件定义 MYAPP_DATABASE_URL