Home > Net >  How to pass environment variables to mongo service in kubernetes?
How to pass environment variables to mongo service in kubernetes?

Time:11-04

I have configured minikube and am trying to run kubenetes on my local ubuntu machine. When I build the MongoDB docker image on my local, I can pass the env variables this way and it works well with the backend API:

mongo_db:
    image: mongo:latest
    container_name: db_container
    environment:
      - MONGODB_INITDB_DATABASE=contacts
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=password
    ports:
      - 27017:27017
    volumes:
      - ./mongodb_data_container:/data/db
    

But when I try to run the entire application(frontend, backend, and MongoDB) in Kubernetes, how do I initiate the MongoDB with the env variables so the backend API can connect to the database pod instance? I'm pulling latest mongodb instance, here's the mongo-deployment yaml file:

# MongoDB Deployment - Database
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
      app: mern-stack
  replicas: 1
  template:
    metadata:
      labels:
        app: mern-stack
    spec:
      containers:
        - name: mern-stack
          image: mongo:latest
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: db-data
              mountPath: /data
              readOnly: false
      volumes:
        - name: db-data
          persistentVolumeClaim:
            claimName: mern-stack-data

I have tried to pass the env variables this way, but it doesn't seem to work:

...
          volumeMounts:
            - name: db-data
              mountPath: /data
              readOnly: false
          env:
            - name: MONGODB_INITDB_DATABASE
              value: "contacts"
            - name: MONGO_INITDB_ROOT_USERNAME
              value: "root"
            - name: MONGO_INITDB_ROOT_PASSWORD
              value: "password"
...

What's the quick solution? Should I try config map and secret eventually?

CodePudding user response:

volumeMounts usually used for the whole config file e.g. ***.conf It's more convenient for you to use secret in your case.

1、create secret resource

apiVersion: v1
data:
  db_url: YWRtaW4=
  db_password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
  name: <secretname>
  namespace: <namespaceuwant>
type: Opaque

2、you can use in your mongodb

mongo_db:
    image: mongo:latest
    container_name: db_container
    env:
    - name: db_url # env you can get 
      valueFrom:
        secretKeyRef:
          name: <secretname> # step 1 create
          key: db_url # in your secret 
       .
       .
       .

CodePudding user response:

  1. Configure kubectl to default to your namespace.

If you have not already, run the following command to execute all kubectl commands in the namespace you created:

 kubectl config set-context $(kubectl config current-context) --namespace=<metadata.namespace>
  1. You can choose to use a cleartext password:

apiVersion: v1
kind: Secret
metadata:
  name: <mms-user-1-password>
  # corresponds to user.spec.passwordSecretKeyRef.name
type: Opaque
stringData:
  password: <my-plain-text-password>
  # corresponds to user.spec.passwordSecretKeyRef.key
data:
  password: <base-64-encoded-password>
  # corresponds to user.spec.passwordSecretKeyRef.key
...

or you can choose to use a Base64-encoded password:

---
apiVersion: v1
kind: Secret
metadata:
  name: <mms-user-1-password>
  # corresponds to user.spec.passwordSecretKeyRef.name
type: Opaque
stringData:
  password: <my-plain-text-password>
  # corresponds to user.spec.passwordSecretKeyRef.key
data:
  password: <base-64-encoded-password>
  # corresponds to user.spec.passwordSecretKeyRef.key
...
  1. Create a new User Secret YAML file.

To learn about your options for secret storage, see https://kubernetes.io/docs/concepts/configuration/secret/

  1. Change these values to yours.

    stringData.password #Plaintext password for the desired user.

    data.password #Base64-encoded password for the desired user.

  2. Save the User Secret file with a .yaml extension

Create MongoDBUser

  • Copy the following example MongoDBUser

apiVersion: mongodb.com/v1
kind: MongoDBUser
metadata:
      name: <mms-scram-user-1>
spec:
  passwordSecretKeyRef:
name: <mms-user-1-password>

    # Match to metadata.name of the User Secret
    key: password

  username: "<mms-scram-user-1>"

  db: "admin" #
  mongodbResourceRef:

    name: "<my-replica-set>"

    # Match to MongoDB resource using authenticaiton
  roles:

    - db: "admin"

      name: "clusterAdmin"

    - db: "admin"

      name: "userAdminAnyDatabase"

    - db: "admin"

      name: "readWrite"

    - db: "admin"

      name: "userAdminAnyDatabase"

...
  • Add your own fields.
  • Add any additional roles for the user to the MongoDBUser.
  • Invoke the following Kubernetes command to create your database user:

kubectl apply -f <database-user-conf>.yaml

When you create a new MongoDB database user, Kubernetes Operator automatically creates a new Kubernetes secret. The Kubernetes secret contains the following information about the new database user:

  • username: Username for the database user
  • password: Password for the database user
  • connectionString.standard: Standard connection string that can connect you to the database as this database user.
  • connectionString.standardSrv: DNS seed list connection string that can connect you to the database as this database user.

For more details, you can visit here

CodePudding user response:

You can populate a container's environment variables through the use of Secrets or ConfigMaps. Use Secrets when the data you are working with is sensitive (e.g. passwords), and ConfigMaps when it is not.

In your Pod definition specify that the container should pull values from a Secret:

apiVersion: v1
kind: Pod
metadata: 
  labels: 
    context: docker-k8s-lab
    name: mongo-pod
  name: mongo-pod
spec: 
  containers:
  - image: "mongo:latest"
    name: mongo
    ports: 
    - containerPort: 3306
    envFrom:
      - secretRef:
         name: mongo-secret

You can now define two different Secrets, one for production and one for dev.

dev-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
type: Opaque
data:
  MYSQL_USER: bXlzcWwK
  MYSQL_PASSWORD: bXlzcWwK
  MYSQL_DATABASE: c2FtcGxlCg==
  MYSQL_ROOT_PASSWORD: c3VwZXJzZWNyZXQK

prod-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
type: Opaque
data:
  MYSQL_USER: am9obgo=
  MYSQL_PASSWORD: c2VjdXJlCg==
  MYSQL_DATABASE: cHJvZC1kYgo=
  MYSQL_ROOT_PASSWORD: cm9vdHkK

And deploy the correct secret to the correct Kubernetes cluster:

kubectl config use-context dev
kubectl create -f dev-secret.yaml

kubectl config use-context prod
kubectl create -f prod-secret.yaml

Now whenever a Pod starts it will populate its environment variables from the values specified in the Secret.

  • Related