9

We ran into an issue recently as to using environment variables inside container.

OS: windows 10 pro
k8s cluster: minikube
k8s version: 1.18.3

1. The way that doesn't work, though it's preferred way for us

Here is the deployment.yaml using 'envFrom':

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  labels:
    app.kubernetes.io/name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: db
  template:
    metadata:
      labels:
        app.kubernetes.io/name: db
    spec:
      serviceAccountName: default
      securityContext:
        {}
      containers:
        - name: db
          image: "postgres:9.4"
          ports:
            - name: http
              containerPort: 5432
              protocol: TCP
          envFrom:
            - configMapRef:
                name: db-configmap

here is the db.properties:

POSTGRES_HOST_AUTH_METHOD=trust

step 1:

kubectl create configmap db-configmap ./db.properties

step 2:

kebuctl apply -f ./deployment.yaml

step 3:

kubectl get pod

Run the above command, get the following result:

db-8d7f7bcb9-7l788        0/1    CrashLoopBackOff   1      9s

That indicates the environment variables POSTGRES_HOST_AUTH_METHOD is not injected.

2. The way that works (we can't work with this approach)

Here is the deployment.yaml using 'env':

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  labels:
    app.kubernetes.io/name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: db
  template:
    metadata:
      labels:
        app.kubernetes.io/name: db
    spec:
      serviceAccountName: default
      securityContext:
        {}
      containers:
        - name: db
          image: "postgres:9.4"
          ports:
            - name: http
              containerPort: 5432
              protocol: TCP
          env:
            - name: POSTGRES_HOST_AUTH_METHOD
              value: trust

step 1:

kubectl apply -f ./deployment.yaml

step 2:

kubectl get pod

Run the above command, get the following result:

db-fc58f998d-nxgnn                   1/1        Running        0            32s

the above indicates the environment is injected so that the db starts.

What did I do wrong in the first case?

Thank you in advance for the help.

Update:

Provide the configmap:

 kubectl describe configmap db-configmap
Name:         db-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
db.properties:
----
POSTGRES_HOST_AUTH_METHOD=trust

zeisen
  • 105
  • 2
  • 7
  • Can you please replace your screenshots with copy/pastes of the actual text? It helps people searching for similar errors (and to an extent helps with accessibility here on SO) – c-x-berger Jul 24 '20 at 18:54

3 Answers3

9

For creating config-maps for usecase-1. please use the below command

kubectl create configmap db-configmap --from-env-file db.properties
Ramakrishnan M
  • 482
  • 1
  • 6
  • 16
  • 1
    this works. marked as solution. didn't realize there is a separate option --from-env-file specifically for environment variables. – zeisen Jul 24 '20 at 23:59
0

Are you missing the key? (see "key:" (no quotes) below) And I think you need to provide the name of the env-variable...which people usually use the key-name, but you don't have to. I've repeated the same value ("POSTGRES_HOST_AUTH_METHOD") below as the environment variable NAME and the keyname of the config-map.

  #start env .. where we add environment variables
env:
    # Define the environment variable
- name: POSTGRES_HOST_AUTH_METHOD
  #value: "UseHardCodedValueToDebugSometimes"

  valueFrom:
    configMapKeyRef:
          # The ConfigMap containing the value you want to assign to environment variable (above "name:")
      name: db-configmap 
          # Specify the key associated with the value
      key: POSTGRES_HOST_AUTH_METHOD      

My example (trying to use your values)....comes from this generic example:

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#define-container-environment-variables-using-configmap-data

pods/pod-single-configmap-env-variable.yaml

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # Define the environment variable
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
              name: special-config
              # Specify the key associated with the value
              key: special.how
  restartPolicy: Never

PS

You can use "describe" to take a looksie at your config-map, after you (think:) ) you have set it up correctly.

kubectl describe configmap db-configmap --namespace=IfNotDefaultNameSpaceHere
granadaCoder
  • 26,328
  • 10
  • 113
  • 146
  • @grandaCoder thank you for the quick response. As I mentioned in my post, using 'env' works, weather we use 'name/value' or 'name/valueFrom' as you did, but we are instead looking for using 'envFrom' as a more generic solution. This way, it will work with whatever env variables in a property file. – zeisen Jul 24 '20 at 20:25
  • Are you talking about a properties file built with your containerr? I think you may be missing the point of config map and k8 secrets. This is the way to deal with config values AND NOT baking those values into the container. It is a horrible practice to bake secrets into the container. https://techbeacon.com/devops/how-keep-your-container-secrets-secure – granadaCoder Jul 24 '20 at 21:16
  • @grandaCoder, the intent is to inject the config data in a file to k8s container via configMap. Those are non-secret config data. Also, not sure what you mean when you say baking values into container. If what I attempt to achieve is not the right way to inject data in container, please do let me know what is the best practice – zeisen Jul 25 '20 at 00:06
  • 1. Push configmap and/ or secrets into the kubernetes system. Probably they will set up these values per environment (dev, QA, staging, production). ... Then a container is built that needs config values. The container does not contain the config values or secrets built into the container. But the container knows how to find/read the config values and secrets. The place for the container to find the config values/secrets is where kubernetes MOUNTS the values...designated by yml .. which is typically two ways. – granadaCoder Jul 25 '20 at 00:31
  • As ENVIRONMENT variable or as a virtual "txt" file where the filename is the secret name and the contents of the file is the value. The mounting occurs when the pod/container are created. But the publishing if the config values/ secrets happens before and as a separate activity then the mounting of the values. – granadaCoder Jul 25 '20 at 00:34
  • When I asked to run the "describe". That would have told you if you properly published the config values. And from the answer you marked as the answer...that looks like it was the issue. And now somebody downvoted my answer ... As I was trying to explain the process and the "key" I saw missing. I get I might get the upvote, but why the downvote? My answer was an legitimate attempt to help. – granadaCoder Jul 25 '20 at 00:41
  • thank you for the detailed explanation. I believe what we try to achieve is in line with what you described. The only difference is we have made conscious decision to not go with volume mount; instead, we simply inject the config data into container when the pods are being created. I really appreciate your effort to help. and I am not sure about the downvote. – zeisen Jul 25 '20 at 15:12
0

See when you do it like you described.

deployment# exb db-7785cdd5d8-6cstw
root@db-7785cdd5d8-6cstw:/# env | grep -i TRUST
db.properties=POSTGRES_HOST_AUTH_METHOD=trust

the env set is not exactly POSTGRES_HOST_AUTH_METHOD its actually taking filename in env. create configmap via kubectl create cm db-configmap --from-env-file db.properties and it will actually put env POSTGRES_HOST_AUTH_METHOD in pod.

Abhi Gadroo
  • 200
  • 1
  • 10
  • Thank you for the answer. it's interesting to see the environment variable is not in the expected format. but it does work in my case. Please let me now if anything I need to be concerned about with this approach. – zeisen Jul 25 '20 at 15:16
  • I think the whole idea to use postgres like this on production is not okay. Even when I ran this on my testing setup it gave me a warning that I should not do it like this. Moreover how are you going to persist data? And what about HA? master slave? – Abhi Gadroo Jul 25 '20 at 19:19
  • I am using postgres as an example for the issue I posted. In reality, we simply use managed db service in the cloud. – zeisen Jul 27 '20 at 18:13