6

Using Kubernetes 1.19.3, I initialize env variable values using 3 different ways:

  • env field with explicit key/value in the pod definition
  • envFrom using configMapRef and secretRef

When a key name is duplicated, as shown in the example below, DUPLIK1 and DUPLIK2 are defined multiple times with different values.

What is the precedence rule that Kubernetes uses to assign the final value to the variable?

# create some test Key/Value configs and Key/Value secrets
kubectl create configmap myconfigmap --from-literal=DUPLIK1=myConfig1 --from-literal=CMKEY1=CMval1 --from-literal=DUPLIK2=FromConfigMap -n mydebugns

kubectl create secret generic mysecret --from-literal=SECRETKEY1=SECval1 --from-literal=SECRETKEY2=SECval2 --from-literal=DUPLIK2=FromSecret -n mydebugns

# create a test pod
cat <<EOF | kubectl apply -n mydebugns -f -
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
    - name: container1
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
      - name: DUPLIK1
        value: "Key/Value defined in field env"
      envFrom:
      - configMapRef:
          name: myconfigmap
      - secretRef:
          name: mysecret          
  restartPolicy: Never
EOF

Show environement variables values. The result is deterministic. Deleting resources + recreate always end up with the same result.

kubectl logs pod/pod1 -n mydebugns

CMKEY1=CMval1
DUPLIK1=Key/Value defined in field env
DUPLIK2=FromSecret
SECRETKEY1=SECval1
SECRETKEY2=SECval2

Cleanup test resources

kubectl delete pod/pod1 -n mydebugns
kubectl delete cm/myconfigmap  -n mydebugns
kubectl delete secret/mysecret -n mydebugns
Polymerase
  • 6,311
  • 11
  • 47
  • 65

1 Answers1

11

From Kubernetes docs:

envVar: List of environment variables to set in the container. Cannot be updated.

envFrom: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

The above link clearly states the env will take precedence over envFrom and cannot be updated.

Also, when a referenced key is present in multiple resources, the value associated with the last source will override all previous values.

Based on the above, the result you are seeing is expected behavior:

  1. DUPLIK1 is added as env field and thus cannot be updated
  2. DUPLIK2 is added as envFrom and so the one from the secret takes precedence as it is defined at the last
Krishna Chaurasia
  • 8,924
  • 6
  • 22
  • 35
  • 1
    Wonderful, thank you very much. I swaped the declarative positions to have `configMapRef` as last and indeed `DUPLIK2=fromConfigMap`. BTW, where does the docs page (/reference/generated) you gave come from? The doc I used to see looks different (no generated): https://kubernetes.io/docs/concepts/configuration/secret/. What is the difference between these 2 docs? – Polymerase Feb 20 '21 at 06:48
  • They are referenced here in the kubernetes.io: https://kubernetes.io/docs/reference/using-api/ and I believe the reference docs are generated from https://github.com/kubernetes/kubernetes/tree/master where each version has its own specific branch. `1.20` for example are present at https://github.com/kubernetes/kubernetes/tree/release-1.20. – Krishna Chaurasia Feb 20 '21 at 06:54
  • Was trying to find the same page you showed [WORKLOAD APIS / Container v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core) in the non generated doc. But could not. I wonder when I should use one or the other (generated vs non-generated doc) – Polymerase Feb 20 '21 at 06:58
  • 1
    The kubernetes.io I believe includes technical concepts as well while the generated one mostly include API reference and should mostly be required if you are working with some resource which are not fully matured. For example, a resource may be in `beta` in some version and we would then need to look at the respective version of the API reference. – Krishna Chaurasia Feb 20 '21 at 07:03