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
解决方案
核心问题分析
- 初始化脚本未执行:
MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD仅在MongoDB首次启动且/data/db为空时生效。如果PV中已有旧数据,初始化脚本不会重新运行,导致管理员账号未创建。 - 配置语法错误:修改后的StatefulSet中,
MONGO_INITDB_ROOT_USERNAME同时定义了value和valueFrom,这是无效配置,会被Kubernetes忽略。 - 无凭证登录原因: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
相关产品推荐
相关产品推荐

