What are good practices to connect the dots within Kubernetes?

6/21/2019

For example I want to run my node js application. I can create Deployment and expose it via Service. In order to keep it running I need to deploy MongoDB. It will create its own service. I can give it static service name like mongo.svc.cluster.local and hardcode it for my Node.js app. Kubernetes will take care of DNS etc.

I don't know if it is a good practice or not. But it doesn't feel like that.

I am trying to wrap my mind around Labels. I understand I can label my MongoDB service with "component: mongo" but I can't get the concept how can I use it for discovery MongoDB hostname and passing it as env var into my application.

Can someone explain that to me?

-- zoonman
kubernetes

1 Answer

6/21/2019

You should always make these hostnames configurable; via an environment variable is easiest to set in a Docker/Kubernetes world. Consider the scenario you're describing:

  • When you're doing purely local development, you want to connect to the MongoDB on your desktop, which will likely be localhost:27017.
  • You can do basic integration testing of your Docker container with Docker Compose, and the host name will be an unqualified mongodb:27017.
  • In a Kubernetes environment you can want to use the FQDN mongodb.default.svc.cluster.local:27017, especially if you think the database might live in a different namespace.
  • There are good arguments to run a database outside Docker or Kubernetes, in which case you'd need to provide some other hostname.

Almost every language gives some way to access the environment variables (Node's process.env, Python's os.environ, Ruby's ENV, ...) and so you can look this up with some default that makes sense.

const mongoHost = process.env.MONGO_HOST || 'localhost:27017';

In your Kubernetes Deployment spec you can explicitly set this as an environment variable.

- name: MONGO_HOST
  value: 'mongodb.default.svc.cluster.local:27017'

I would not worry about letting the application dynamically try to find the database; just pass in its location as configuration. (You don't need to think about labels except to the extent that the tell the service what to serve.)

-- David Maze
Source: StackOverflow