欢迎光临
我们一直在努力

告别硬编码,用 ConfigMap 管理 Kubernetes 中的配置文件

概述

通常一个微服务,里面会有一堆配置:

  • 数据库地址
  • 日志级别
  • 第三方 API 密钥(先忽略安全问题)
  • 功能开关

一开始,你把它们写在代码里,或者打包进镜像。 但很快发现:

  • 想改个超时时间?得重新构建镜像、重新部署!
  • 测试环境和生产环境配置混在一起
  • 配置散落在各个服务中,难以统一管理

这就像每次换 Wi-Fi 密码,都要重装手机系统——太荒谬了!

在 Kubernetes 中,这个问题有优雅的解法:ConfigMap

什么是 ConfigMap

ConfigMap 是 Kubernetes 的一种资源对象,用于:

  • 存储非敏感的配置数据(如字符串、配置文件)
  • 将配置与容器镜像解耦
  • 支持动态更新(部分场景)

配置不是代码的一部分,而是运行时注入的参数

ConfigMap 中的数据可以以两种方式注入到 Pod:

  • 环境变量(Environment Variables)
  • 挂载为文件(Volume Mount)
  • 为什么不用直接写在 YAML 里

    如果直接在 Deployment 里写 env 会怎样?

    env:
    name: DB_HOST
    value: "prod-db.example.com"

    这确实可行,但问题在于:

    • 配置无法复用(多个服务要重复写)
    • 修改配置需改 Deployment,触发滚动更新
    • 无法用版本控制单独管理配置

    而 ConfigMap 让配置独立存在,像“配置中心”的轻量版

    创建 ConfigMap 的三种方式

    方式 1:从字面值创建(适合少量键值对)

    kubectl create configmap app-config \\
    –from-literal=log_level=info \\
    –from-literal=db_host=mysql.default.svc.cluster.local \\
    –from-literal=feature_new_ui=true

    查看内容:

    kubectl get configmap app-config -o yaml

    输出片段:

    data:
    log_level: info
    db_host: mysql.default.svc.cluster.local
    feature_new_ui: "true"

    方式 2:从文件创建(适合配置文件)

    假设你有一个 app.properties:

    # app.properties
    server.port=8080
    spring.datasource.url=jdbc:mysql://db:3306/mydb
    logging.level.root=INFO

    创建 ConfigMap:

    kubectl create configmap app-config-from-file \\
    –from-file=app.properties

    注意:文件名会成为 ConfigMap 中的 key,内容是 value。

    方式 3:从 YAML 文件定义(推荐)

    创建 configmap.yaml:

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: myappconfig
    data:
    # 键值对形式
    log_level: "debug"
    db_host: "mysql.prod.svc"

    # 多行配置文件(用 | 保留格式)
    nginx.conf: |
    server {
    listen 80;
    location / {
    root /usr/share/nginx/html;
    }
    }

    app.json: |
    {
    "timeout": 5000,
    "retry": 3
    }

    应用:

    kubectl apply -f configmap.yaml

    这种方式支持复杂结构,且可纳入 Git 版本管理

    在 Pod 中使用 ConfigMap

    场景 1:作为环境变量注入

    # deployment-env.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: myapp
    spec:
    template:
    spec:
    containers:
    name: app
    image: myapp:1.0
    envFrom:
    configMapRef:
    name: myappconfig # 引用上面的 ConfigMap

    Pod 启动后,容器内会自动拥有这些环境变量:

    echo $log_level # 输出: debug
    echo $db_host # 输出: mysql.prod.svc

    注意:如果 ConfigMap 更新,已运行的 Pod 不会自动更新环境变量!需重建 Pod。

    场景 2:挂载为配置文件(推荐用于复杂配置)

    # deployment-volume.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nginxapp
    spec:
    template:
    spec:
    containers:
    name: nginx
    image: nginx:alpine
    volumeMounts:
    name: configvolume
    mountPath: /etc/nginx/conf.d # 挂载到容器目录
    volumes:
    name: configvolume
    configMap:
    name: myappconfig
    items:
    key: nginx.conf # ConfigMap 中的 key
    path: default.conf # 在挂载目录中的文件名

    效果:

    • 容器内的 /etc/nginx/conf.d/default.conf 内容 = ConfigMap 中 nginx.conf 的值
    • Nginx 启动时会自动加载这个配置

    优势:配置以文件形式存在,应用无需改造!

    实战:部署一个带配置的 Node.js 应用

    Step 1:准备配置

    app-config.yaml:

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: nodejsconfig
    data:
    PORT: "3000"
    DB_URL: "mongodb://mongo:27017/mydb"
    LOG_LEVEL: "info"

    Step 2:编写 Deployment(使用环境变量)

    nodejs-deploy.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nodejsapp
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: nodejs
    template:
    metadata:
    labels:
    app: nodejs
    spec:
    containers:
    name: app
    image: node:18alpine
    command: ["sh", "-c"]
    args:
    |
    echo "Server starting on port $$PORT";
    while true; do echo "Ping DB: $$DB_URL"; sleep 10; done

    envFrom:
    configMapRef:
    name: nodejsconfig

    Step 3:部署并验证

    kubectl apply -f app-config.yaml
    kubectl apply -f nodejs-deploy.yaml

    # 查看日志
    kubectl logs -l app=nodejs

    输出:

    Server starting on port 3000
    Ping DB: mongodb://mongo:27017/mydb

    配置成功注入

    ConfigMap vs Secret:怎么选

    特性ConfigMapSecret
    存储内容 非敏感配置(如端口、开关) 敏感信息(密码、密钥、Token)
    存储格式 明文(Base64 可读) Base64 编码(仍需配合 RBAC)
    使用方式 几乎相同(env / volume) 几乎相同
    安全建议 ❌ 不要存密码! ✅ 用 Secret + 加密插件(如 Sealed Secrets)

    重要:数据库密码、API Key 等绝不能放在 ConfigMap 中

    ConfigMap 能热更新吗

    • 挂载为文件:✅ 是!Kubelet 会定期同步(默认每秒检查),文件内容会自动更新(但应用需支持 reload)
    • 作为环境变量:❌ 否!Pod 创建时注入,之后不会变

    提示:Nginx、Spring Boot 等支持配置重载的应用,适合用 Volume 方式。

    最佳实践

    建议说明
    ✅ 用 YAML 文件管理 ConfigMap 便于 Git 版本控制
    ✅ 按应用/环境命名(如 user-svc-prod-config) 避免冲突
    ✅ 复杂配置用 Volume 挂载 比环境变量更清晰
    ❌ 不要存敏感信息 用 Secret 代替
    ✅ 配合 CI/CD 自动更新 实现配置即代码(Configuration as Code)

    总结

    问题ConfigMap 解法
    配置写死在镜像里? ✅ 外部化,独立管理
    多环境配置混乱? ✅ 创建 dev-config / prod-config
    改配置要重打包? ✅ 只需更新 ConfigMap(部分场景自动生效)
    配置无法复用? ✅ 多个 Pod 引用同一个 ConfigMap
    赞(0)
    未经允许不得转载:171主机测评 » 告别硬编码,用 ConfigMap 管理 Kubernetes 中的配置文件
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址