如何在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
相关产品推荐
相关产品推荐

