如何在 kubernetes 部署中获取 MONGODB_URI 的值?

How do I get the value of MONGODB_URI in a kubernetes deploy?

我在 minikube 上有一个有效的 mongoDB 部署,我已经成功地创建了一个数据库、集合以及一个用户(与 yaml 中引用的用户相同)来对该数据库进行备份。

在备份 cron 作业的 yaml 文件中,我需要指定一个 MONGODB_URI 参数,坦率地说,我不知道获取的确切约定这个(你到底从哪里得到价值)。

作为检查,我做了一个 kubectl exec -it <pod_name>,这样我就可以检查 我是否要预先放置正确的 URI。 运行ning kubectl exec -it 在随后的提示中我尝试了以下操作:

1.

mongosh mongodb://aaa:abc123@mongodb-service.default.svc.cluster.local:27017/plaformdb/?directConnection=true

不工作我得到错误:

Current Mongosh Log ID: 62938b50880f139dad4b19c4
Connecting to:          mongodb://mongodb-service.default.svc.cluster.local:27017/platformdb/?directConnection=true&appName=mongosh+1.4.2
MongoServerSelectionError: Server selection timed out after 30000 ms
mongosh mongodb://aaa:abc123@mongodb-service.svc.cluster.local:27017/platformdb?directConnection=true

不工作我也收到错误:

MongoNetworkError: getaddrinfo ENOTFOUND mongodb-service.svc.cluster.local
mongosh mongodb://aaa:abc123@mongodb-deployment-757ffdfdr5-thuiy.mongodb-service.default.svc.cluster.local:27017/platformdb

不工作我得到一个错误:

Current Mongosh Log ID: 62938c93829ft678h88990
Connecting to:          mongodb://mongodb-deployment-757ccdd6y8-thhhh.mongodb-service.default.svc.cluster.local:27017/platformdb?directConnection=true&appName=mongosh+1.4.2
MongoNetworkError: getaddrinfo ENOTFOUND mongodb-deployment-757ffdd5f5-tpzll.mongodb-service.default.svc.cluster.local

然而,根据 :docs

,这是推荐的方式

预期:

我 运行 执行该命令后,我应该能够登录到数据库。

我的部署是这样定义的:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
  labels:
    app: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo
        imagePullPolicy: "IfNotPresent"
        ports:
          - containerPort: 27017
        env:
            - name: MONGO_INITDB_ROOT_USERNAME
              valueFrom:
                secretKeyRef:
                  name: mongodb-secret-amended
                  key: mongo-root-username
            - name: MONGO_INITDB_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mongodb-secret-amended
                  key: mongo-root-password
        volumeMounts: 
            - mountPath: /data/db
              name: mongodb-vol
      volumes:
      - name: mongodb-vol
        persistentVolumeClaim:
          claimName: mongodb-claim
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  selector:
    app: mongodb
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017 

而且我需要在这个 cron 作业中指定 MONGODB_URI :

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mongodump-backup
spec:
  schedule: "0 */6 * * *" #Cron job every 6 hours
  startingDeadlineSeconds: 60
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 2
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: mongodump-backup
              image: golide/backupsdemo
              imagePullPolicy: "IfNotPresent"
              env:
                - name: DB_NAME
                  value: "microfunctions"
                - name:  MONGODB_URI
                  value: mongodb://aaa:abc123@host-mongodb:27017/dbname
              volumeMounts:
                - mountPath: "/mongodump"
                  name: mongodump-volume
              command: ['sh', '-c',"./dump.sh"]
          restartPolicy: OnFailure
          volumes:
            - name: mongodump-volume
              persistentVolumeClaim:
                claimName: mongodb-backup

更新 我已经在我的本地主机 minikube 上尝试了建议的解决方案,但我仍然遇到错误:

mongo mongodb://aaa:abc123@mongodb-service:27017/platformdb?

authSource=admi
n
MongoDB shell version v5.0.8
connecting to: mongodb://mongodb-service:27017/platformdb?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Error: couldn't connect to server mongodb-service:27017, connection attempt failed: SocketException: Error connecting to mongodb-service:27017 (10.102.216.34:27017) :: caused by :: Connection timed out :
connect@src/mongo/shell/mongo.js:372:17
@(connect):2:6
exception: connect failed
exiting with code 1

即使我删除端口并使用 mongodb://aaa:abc123@mongodb-service/platformdb?authSource=admin[,也会出现同样的错误=81=]。我也试过在 URL 周围加上引号 "" 但得到同样的错误。

作为检查,我尝试在另一个具有相同结构的 mongodb 部署上复制完全相同的场景(它也有无头服务)。但是,此部署位于远程 k8s 集群上。 这是我发现的:

  1. 我无法使用 root 用户以外的用户进行连接。我创建了一个自定义用户来进行备份:

     db.createUser( {user: "aaa", pwd: "abc123", roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase","backup"], mechanisms:["SCRAM-SHA-1"]})
    

注意:我在 minikube context 上也创建了相同的用户。 对于这个自定义用户,我每次尝试连接时都会收到身份验证失败错误:

mongo mongodb://aaa:abc123@mongodb-headless-service:27017/TestDb?

authSource=admin
MongoDB shell version v4.4.7
connecting to: mongodb://mongodb-headless-service:27017/TestDb?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:374:17
@(connect):2:6
exception: connect failed
exiting with code 1
  1. 我可以使用 root 用户连接,但连接尝试时断时续。有时我必须退出 pod 并重新 运行 命令才能连接。 这似乎是一个错误,除非我遗漏了其他明显的东西。

下面的屏幕显示连接成功,但在随后的尝试中,完全相同的连接失败了: 在第一次尝试时,我设法登录并 运行 一个 show collections 命令,但是一旦我注销并尝试连接,我就得到身份验证失败。该功能充其量似乎不稳定。

鉴于 Service 的结构,您需要使用主机名 mongodb-service(或者 mongodb-service.<namesapce>.svc.cluster.local,如果您喜欢完全限定的名称)。连接 URI——据我所知 the documentation——将是:

mongodb://<username>:<password>@mongodb-service/dbname?authSource=admin

也可以像this:L

一样连接成功
mongodb://<username>:<password>@mongodb-service/

因为:

If [the username and password are] specified, the client will attempt to authenticate the user to the authSource. If authSource is unspecified, the client will attempt to authenticate the user to the defaultauthdb. And if the defaultauthdb is unspecified, to the admin database.


我使用稍微修改过的 Deployment 测试了这个(主要是,我放弃了 volumeMounts,因为我不需要持久存储进行测试,我使用 envFrom 因为我发现这通常更容易)。

我使用 kustomize (kubectl apply -k .) 部署了这个 kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mongo

commonLabels:
  app: mongodb

resources:
- deployment.yaml
- service.yaml

secretGenerator:
  - name: mongo-credentials
    envs:
      - mongo.env

这个deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: mongodb
          image: docker.io/mongo:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 27017
          envFrom:
            - secretRef:
                name: mongo-credentials

这个service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017

还有这个mongo.env

MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=secret

一切就绪后 运行,我启动了一个客户端 pod:

kubectl run --image docker.io/mongo:latest mongoc -- sleep inf

而且我能够在该 pod 中启动 shell 并连接到数据库:

$ kubectl exec -it mongoc -- bash
Current Mongosh Log ID: 6293a4bc534ff40ec737c383
Connecting to:          mongodb://<credentials>@mongodb-service.mongo.svc.cluster.local/?directConnection=true&appName=mongosh+1.4.2
Using MongoDB:          5.0.8
Using Mongosh:          1.4.2
[...]
test>