You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在K8s集群同一Pod部署Python应用与Mongo容器并自动初始化Mongo

解决方案

一、MongoDB自动初始化用户名密码与副本集

官方Mongo镜像支持通过初始化脚本自动完成配置,你可以借助Kubernetes的ConfigMap和Secret挂载脚本,让Pod启动时自动执行初始化逻辑。

1. 自动配置用户与密码

首先创建用户初始化脚本init-mongo.js,通过环境变量读取Secret中的密码(避免明文暴露):

var adminPwd = process.env.ADMIN_PASSWORD;
var appPwd = process.env.APP_PASSWORD;

// 创建管理员用户
db.createUser({
  user: "admin",
  pwd: adminPwd,
  roles: [{ role: "root", db: "admin" }]
});

// 创建应用专用用户
db.getSiblingDB("your-app-db").createUser({
  user: "app-user",
  pwd: appPwd,
  roles: [{ role: "readWrite", db: "your-app-db" }]
});

将脚本存入ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-init-scripts
data:
  init-mongo.js: |
    var adminPwd = process.env.ADMIN_PASSWORD;
    var appPwd = process.env.APP_PASSWORD;
    db.createUser({
      user: "admin",
      pwd: adminPwd,
      roles: [{ role: "root", db: "admin" }]
    });
    db.getSiblingDB("your-app-db").createUser({
      user: "app-user",
      pwd: appPwd,
      roles: [{ role: "readWrite", db: "your-app-db" }]
    });

创建存储密码的Secret:

kubectl create secret generic mongo-secrets --from-literal=admin-password=your-secure-password --from-literal=app-password=app-password

最后在Mongo的Deployment/StatefulSet中挂载ConfigMap并注入环境变量:

containers:
- name: mongo
  image: mongo:latest
  args: ["--auth"] # 启动时开启认证
  env:
  - name: ADMIN_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mongo-secrets
        key: admin-password
  - name: APP_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mongo-secrets
        key: app-password
  volumeMounts:
  - name: init-scripts
    mountPath: /docker-entrypoint-initdb.d/ # 官方镜像会自动执行该目录下的脚本
volumes:
- name: init-scripts
  configMap:
    name: mongo-init-scripts

2. 自动配置副本集

副本集建议用StatefulSet部署(Pod有固定名称,便于节点发现),仅在第一个节点(如mongo-0)执行初始化逻辑:
添加副本集初始化脚本init-replica-set.js到ConfigMap:

// 仅在mongo-0节点执行副本集初始化
if (process.env.HOSTNAME === "mongo-0") {
  var adminPwd = process.env.ADMIN_PASSWORD;
  db.getSiblingDB("admin").auth("admin", adminPwd);
  
  rs.initiate({
    _id: "rs0",
    members: [
      { _id: 0, host: "mongo-0.mongo.default.svc.cluster.local:27017" },
      { _id: 1, host: "mongo-1.mongo.default.svc.cluster.local:27017" },
      { _id: 2, host: "mongo-2.mongo.default.svc.cluster.local:27017" }
    ]
  });

  // 等待副本集初始化完成
  while (rs.status().stateStr !== "PRIMARY") {
    sleep(1000);
  }
}

更新ConfigMap后,StatefulSet配置示例:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
spec:
  serviceName: "mongo" # 用于内部DNS解析
  replicas: 3
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo
        image: mongo:latest
        args: ["--replSet", "rs0", "--bind_ip_all", "--auth"]
        ports:
        - containerPort: 27017
        env:
        - name: ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secrets
              key: admin-password
        - name: APP_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secrets
              key: app-password
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
        - name: init-scripts
          mountPath: /docker-entrypoint-initdb.d/
      volumes:
      - name: init-scripts
        configMap:
          name: mongo-init-scripts
  volumeClaimTemplates: # 持久化存储,避免数据丢失
  - metadata:
      name: mongo-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

启动后,mongo-0会自动初始化副本集,其余节点加入后自动同步配置。

二、同一Pod部署Python应用与Mongo容器

同一Pod内的容器共享网络命名空间和存储卷,Python应用可通过localhost直接访问Mongo。示例Deployment配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-mongo
spec:
  replicas: 1 # 注意:每个Pod都有独立Mongo,数据不共享,适合开发/测试场景
  selector:
    matchLabels:
      app: app-with-mongo
  template:
    metadata:
      labels:
        app: app-with-mongo
    spec:
      containers:
      - name: python-app
        image: your-python-app-image:latest
        env:
        - name: MONGO_URI
          value: "mongodb://app-user:app-password@localhost:27017/your-app-db?authSource=admin"
        ports:
        - containerPort: 8000
      - name: mongo
        image: mongo:latest
        args: ["--auth"]
        env:
        - name: ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secrets
              key: admin-password
        - name: APP_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongo-secrets
              key: app-password
        volumeMounts:
        - name: init-scripts
          mountPath: /docker-entrypoint-initdb.d/
        - name: mongo-data
          mountPath: /data/db
      volumes:
      - name: init-scripts
        configMap:
          name: mongo-init-scripts
      - name: mongo-data
        emptyDir: {} # 临时存储,重启Pod数据丢失;生产环境替换为PersistentVolumeClaim

注意:生产环境不建议用这种模式,因为数据无法跨Pod共享,且Mongo的资源隔离性差。推荐单独用StatefulSet部署Mongo,Python应用通过Service访问。

内容的提问来源于stack exchange,提问作者Muhammad Awais

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:30:57