0

I have deployed bitnami's Mongodb helm chart in the replicaset mode on a K8s cluster, using this minimal config (for now):

  architecture: replicaset
  auth:
    enabled: false

Now I have two replicas (one primary and one secondary, allegedly) and an arbiter (no data, just voting rights). Additionally, I got two services: appname-mongodb-headless, appname-mongodb-arbiter-headless. However, the MongoDB docs specify the connection string in case of replicaset installations as mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myRepl.

I can use mongodb://appname-mongodb-headless:27017 to connect to the db, but is it the "real experience" (i.e. highly available, etc)?

  • Do I need to specify the replicaset name (as in the example) and how do I find out what it is?
  • If the current services are enough, do I need to include the arbiter in the connection string?
  • Or should I create separate services for each replica and build the recommended connection string?
    externalAccess:
      enabled: true
      autoDiscovery:
        enabled: true
    
  • I will eventually enable authentication after sorting out this part of the connection. What is this replicaSetKey ("Key used for authentication in the replicaset"), and where do I use it?

I found this similar question. It is for another chart, but it suggests me that some combination of the headless services should be enough. Nonetheless, it doesn't answer all aspects of my question.

alparius
  • 60
  • 8

2 Answers2

2

The headless service serves as an entrypoint for you to connect to MongoDB, without the need to specify a pod address. Kubernetes will balance the load and serve it to a specific pod.

If you wish to connect to MongoDB, using externalAccess.enabled, you should take a look at the Helm deployment notes that are shown when you deploy the chart. You can read them post-deployment by executing the helm get notes MY-RELEASE command.

For instance, in my case, it shows this, though depending on the deployment options it would show something else:

To connect to your database, create a MongoDB® client container:

    kubectl run --namespace default mbmongo-mongodb-client --rm --tty -i --restart='Never' --env="MONGODB_ROOT_PASSWORD=$MONGODB_ROOT_PASSWORD" --image docker.io/bitnami/mongodb:4.4.8-debian-10-r24 --command -- bash

Then, run the following command:
    mongo admin --host "mbmongo-mongodb-0.mbmongo-mongodb-headless.default.svc.cluster.local:27017,mbmongo-mongodb-1.mbmongo-mongodb-headless.default.svc.cluster.local:27017,mbmongo-mongodb-2.mbmongo-mongodb-headless.default.svc.cluster.local:27017" --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD

To connect to your database nodes from outside, you need to add both primary and secondary nodes hostnames/IPs to your Mongo client. To obtain them, follow the instructions below:

    MongoDB® nodes domain: you can reach MongoDB® nodes on any of the K8s nodes external IPs.

        kubectl get nodes -o wide

    MongoDB® nodes port: You will have a different node port for each MongoDB® node. You can get the list of configured node ports using the command below:

        echo "$(kubectl get svc --namespace default -l "app.kubernetes.io/name=mongodb,app.kubernetes.io/instance=mbmongo,app.kubernetes.io/component=mongodb,pod" -o jsonpath='{.items[*].spec.ports[0].nodePort}' | tr ' ' '\n')"

From the notes you can see this line:

To connect to your database nodes from outside, you need to add both primary and secondary nodes hostnames/IPs to your Mongo client

That means that you do need to specify all primary/secondary node names, but not arbiters.


As for replicaSetKey, it refers to the contents of the MongoDB keyFile to use for internal cluster replication, so it can happen in a secure manner. You can read more about it here.

If you continue finding issues, I suggest you create an issue in the bitnami/charts repository.

  • I read the chart's description but I always forget about the deployment notes. Thank you for bringing that up, it does actually explain it in details. It made me realize I missed the point of the service being headless, the `mongodb://appname-mongodb-headless:27017` URL connects to the db through a proxy, I actually need to list the two pod service addresses so that my app knows about the replicas. – alparius Sep 01 '21 at 18:35
0

Adding to Marcos' answer, there is another URI format called DNS Seed List Connection Format from 3.6+ which you can use with a single host name of your headless service and still take advantage of the replicaset.

mongodb+srv://server.example.com/

It is described here: https://docs.mongodb.com/manual/reference/connection-string/#dns-seed-list-connection-format

Daniel Arechiga
  • 847
  • 7
  • 19