skip to Main Content

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?

3

Answers


  1. Chosen as BEST ANSWER
    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


  2. 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 
           .
           .
           .
    
    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search