Search code examples
kuberneteskubernetes-podconfigmap

Duplicated env variable names in pod definition, what is the precedence rule to determine the final value?


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

Solution

  • 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