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

Kubernetes部署MongoDB后预设凭证登录失败问题求助

问题描述

在Kubernetes集群中使用StatefulSet部署MongoDB,Pod已正常运行,但无法使用StatefulSet清单中配置的默认凭证登录,且无需凭证即可直接登录MongoDB。尝试添加authorization: enabled和密钥文件配置后问题仍未解决,求排查错误及禁止无凭证登录的方法。

当前使用的清单文件

StatefulSet 清单

apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: mongo
  name: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
        - name: mongo
          image: mongo:latest
          resources:
            limits:
              cpu: 100m
              memory: 200Mi
            requests:
              cpu: 100m
              memory: 100Mi
          env:
            - name: MONGO_INITDB_ROOT_USERNAME
              valueFrom:
                configMapKeyRef:
                  key: username
                  name: mongodb-config
            - name: MONGO_INITDB_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: password
                  name: mongodb-secret
          command:
            - mongod
            - "--bind_ip_all"
            - "--config=/etc/mongo/mongodb.conf"
          volumeMounts:
            - name: mongo-volume
              mountPath: /data/db
            - name: mongodb-config
              mountPath: /etc/mongo
      volumes:
        - name: mongodb-config
          configMap:
            name: mongodb-config
            items:
              - key: mongodb.conf
                path: mongodb.conf
  volumeClaimTemplates:
    - metadata:
        name: mongo-volume
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: local-path
        resources:
          requests:
            storage: 1Gi

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: mongo
  name: mongodb-config
immutable: false  # Indicates that the ConfigMap can be modified
data:
  username: admin  # Sets the value of the "username" key to "admin1"
  mongodb.conf: |  # Defines the content of the MongoDB configuration file
    storage:
      dbPath: /data/db  # Sets the MongoDB data storage path
    replication:
      replSetName: "rs0"

Secret

apiVersion: v1
data:
  password: UGFzc3dvcmQK    #base64 value for Password@
kind: Secret
metadata:
  creationTimestamp: null
  name: mongodb-secret
  namespace: mongo

Service

apiVersion: v1
kind: Service
metadata:
  namespace: mongo
  name: mongo  # Specifies the name of the Service
spec:
  ports:
    - name: mongo  # Specifies the name of the port
      port: 27017  # Specifies the port number
      targetPort: 27017  # Specifies the target port on the pods
  clusterIP: None  # Specifies that no cluster IP is assigned (Headless Service)
  selector:
    app: mongo

执行命令结果

尝试用凭证登录失败:

mongosh --host localhost --port 27017 -u admin -p Password@ --authenticationDatabase admin

输出:

Current Mongosh Log ID: 673dc9349d4791ba0dc1c18b
Connecting to:          mongodb://<credentials>@localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000&authSource=admin&appName=mongosh+2.3.3
MongoServerError: Authentication failed.

无需凭证可直接登录:

mongosh --host localhost --port 27017 

输出:

ubuntu@achebe-2:~$ mongosh --host localhost --port 27017 
Current Mongosh Log ID: 673dcc91af14392b9cc1c18b
Connecting to:          mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.3.3
Using MongoDB:          8.0.3
Using Mongosh:          2.3.3

test> 

修改后的配置尝试

修改后的ConfigMap:

Name:         mongodb-config
Namespace:    mongo
Labels:       <none>
Annotations:  <none>

Data
====
mongodb.conf:
----
storage:
  dbPath: /data/db  # Sets the MongoDB data storage path
replication:
  replSetName: "rs0"
security:
  keyFile: /etc/mongodb-keyfile/keyfile
  authorization: enabled

username:
----
admin

BinaryData
====

Events:  <none>

修改后的StatefulSet清单:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
  namespace: mongo
spec:
  persistentVolumeClaimRetentionPolicy:
    whenDeleted: Retain
    whenScaled: Retain
  podManagementPolicy: OrderedReady
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: mongo
  serviceName: mongo
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: mongo
    spec:
      initContainers:
        - name: fix-keyfile-permissions
          image: busybox:1.34
          command:
            - sh
            - -c
            - |
              cp /etc/mongodb-keyfile-secret ~/keyfile
              chmod 400 ~/keyfile
              chown 999:999 ~/keyfile
              cp ~/keyfile /etc/mongodb-keyfile/keyfile
          volumeMounts:
            - name: mongodb-keyfile-secret
              mountPath: /etc/mongodb-keyfile-secret
              subPath: mongodb-keyfile
            - name: mongodb-keyfile
              mountPath: /etc/mongodb-keyfile
      containers:
      - command:
          - mongod
          - "--replSet"
          - "rs0"
          - "--auth"
          - --bind_ip_all
          - --config=/etc/mongo/mongodb.conf
          - --keyFile=/etc/mongodb-keyfile/keyfile
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          value: "admin"
          valueFrom:
             configMapKeyRef:
                key: username
                name: mongodb-config
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              key: password
              name: mongodb-secret
        image: mongo:latest
        imagePullPolicy: Always
        name: mongo
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - name: mongodb-keyfile
          mountPath: /etc/mongodb-keyfile
        - mountPath: /etc/mongo
          name: mongodb-config
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - name: mongodb-keyfile-secret
        secret:
          secretName: mongodb-keyfile-secret
      - name: mongodb-keyfile
        emptyDir: {}
      - configMap:
          defaultMode: 420
          items:
          - key: mongodb.conf
            path: mongodb.conf
          name: mongodb-config
        name: mongodb-config
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
  volumeClaimTemplates:
  - apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      creationTimestamp: null
      name: mongo-volume
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: local-path
      volumeMode: Filesystem
    status:
      phase: Pending

解决方案

核心问题分析

  1. 初始化脚本未执行:MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD仅在MongoDB首次启动且/data/db为空时生效。如果PV中已有旧数据,初始化脚本不会重新运行,导致管理员账号未创建。
  2. 配置语法错误:修改后的StatefulSet中,MONGO_INITDB_ROOT_USERNAME同时定义了value和valueFrom,这是无效配置,会被Kubernetes忽略。
  3. 无凭证登录原因:MongoDB未启用认证时,本地连接默认允许无凭证访问;启用认证后才会强制验证身份。

修复步骤

步骤1:清理旧数据(允许的情况下)

因为PV中已有未初始化的数据,初始化脚本不会触发,需先清空数据:

# 进入第一个MongoDB Pod
kubectl exec -it mongo-0 -n mongo -- bash
# 删除数据目录内容
rm -rf /data/db/*
# 退出后重启所有Pod
kubectl delete pod mongo-0 mongo-1 mongo-2 -n mongo

步骤2:修正StatefulSet配置

  • 移除命令行中重复的--replSet和--auth,配置文件中已定义对应参数,避免重复配置。
  • 删除MONGO_INITDB_ROOT_USERNAME中的value: "admin",保留valueFrom即可。

修正后的容器命令和环境变量部分:

containers:
- command:
    - mongod
    - "--bind_ip_all"
    - "--config=/etc/mongo/mongodb.conf"
  env:
  - name: MONGO_INITDB_ROOT_USERNAME
    valueFrom:
       configMapKeyRef:
          key: username
          name: mongodb-config
  - name: MONGO_INITDB_ROOT_PASSWORD
    valueFrom:
      secretKeyRef:
        key: password
        name: mongodb-secret

步骤3:确保密钥文件配置正确

检查mongodb-keyfile-secret是否存在,且内容为有效随机字符串:

# 生成密钥文件内容
openssl rand -base64 756 > keyfile
# 创建Secret
kubectl create secret generic mongodb-keyfile-secret -n mongo --from-file=mongodb-keyfile=keyfile

步骤4:初始化复制集

即使配置了replSetName,也需要手动初始化复制集:

# 进入第一个Pod
kubectl exec -it mongo-0 -n mongo -- mongosh
# 初始化3节点复制集
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo-0.mongo.mongo.svc.cluster.local:27017" },
    { _id: 1, host: "mongo-1.mongo.mongo.svc.cluster.local:27017" },
    { _id: 2, host: "mongo-2.mongo.mongo.svc.cluster.local:27017" }
  ]
})
# 验证复制集状态
rs.status()

步骤5:验证认证效果

重启所有Pod后,尝试无凭证登录:

mongosh --host localhost --port 27017

此时应报错MongoServerError: command listDatabases requires authentication,说明认证已启用。再用凭证登录:

mongosh --host localhost --port 27017 -u admin -p Password@ --authenticationDatabase admin

关键注意事项

  • MONGO_INITDB_*系列环境变量仅在首次启动且数据目录为空时生效,后续修改不会触发重新初始化。
  • 复制集必须初始化完成,否则基于密钥文件的认证无法正常工作。
  • 密钥文件权限必须为400,属主为MongoDB用户(UID 999),否则MongoDB会拒绝启动。

内容的提问来源于stack exchange,提问作者okechukwu achebe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:49:51