0

I have the following configmap spec:

apiVersion: v1
data:
  MY_NON_SECRET: foo
  MY_OTHER_NON_SECRET: bar
kind: ConfigMap
metadata:
  name: web-configmap
  namespace: default
$ kubectl describe configmap web-configmap
Name:         web-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
MY_NON_SECRET:
----
foo
MY_OTHER_NON_SECRET:
----
bar
Events:  <none>

And the following pod spec:

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  containers:
    - name: web
      image: kahunacohen/hello-kube:latest
      envFrom:
        - configMapRef:
            name: web-configmap
      ports:
      - containerPort: 3000
$ kubectl describe pod web-deployment-5bb9d846b6-8k2s9
Name:         web-deployment-5bb9d846b6-8k2s9
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Mon, 12 Jul 2021 12:22:24 +0300
Labels:       app=web-pod
              pod-template-hash=5bb9d846b6
              service=web-service
Annotations:  <none>
Status:       Running
IP:           172.17.0.5
IPs:
  IP:           172.17.0.5
Controlled By:  ReplicaSet/web-deployment-5bb9d846b6
Containers:
  web:
    Container ID:   docker://8de5472c9605e5764276c345865ec52f9ec032e01ed58bc9a02de525af788acf
    Image:          kahunacohen/hello-kube:latest
    Image ID:       docker-pullable://kahunacohen/hello-kube@sha256:930dc2ca802bff72ee39604533342ef55e24a34b4a42b9074e885f18789ea736
    Port:           3000/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 12 Jul 2021 12:22:27 +0300
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-tcqwz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-tcqwz:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  19m   default-scheduler  Successfully assigned default/web-deployment-5bb9d846b6-8k2s9 to minikube
  Normal  Pulling    19m   kubelet            Pulling image "kahunacohen/hello-kube:latest"
  Normal  Pulled     19m   kubelet            Successfully pulled image "kahunacohen/hello-kube:latest" in 2.3212119s
  Normal  Created    19m   kubelet            Created container web
  Normal  Started    19m   kubelet            Started container web

The pod has container that is running expressjs with this code which is trying to print out the env vars set in the config map:

const process = require("process");
const express = require("express");
const app = express();


app.get("/", (req, res) => {
  res.send(`<h1>Kubernetes Expressjs Example 0.3</h2>
  <h2>Non-Secret Configuration Example</h2>
  <p>This uses ConfigMaps as env vars.</p>
  <ul>
    <li>MY_NON_SECRET: "${process.env.MY_NON_SECRET}"</li>
    <li>MY_OTHER_NON_SECRET: "${process.env.MY_OTHER_NON_SECRET}"</li>
  </ul>
  `);
});


app.listen(3000, () => {
  console.log("Listening on http://localhost:3000");
})

When I deploy these pods, the env vars are undefined

When I do $ kubectl exec {POD_NAME} -- env

I don't see my env vars.

What am I doing wrong? I've tried killing the pods, waiting till they restart then check again to no avail.

Aaron
  • 3,249
  • 4
  • 35
  • 51
  • 1
    Is the pod in the default namespace as well? – whites11 Jul 12 '21 at 09:39
  • Yes, when I describe it I see: Name: web-deployment-5bb9d846b6-ng2n8 Namespace: default Is it normal for it to be listed as web-deployment when the pod's name is specified as "web-pod" in the yaml spec? – Aaron Jul 12 '21 at 10:14

1 Answers1

2

It looks like your pods are managed by web-deployment deployment. You cannot patch such pods directly.

If you run kubectl get pod <pod-name> -n <namespace> -oyaml, you'll see a block called ownerReferences under the metadata section. This tells you who is the owner/manager of this pod.

In case of a deployment, here is the ownership hierarchy:

Deployment -> ReplicaSet -> Pod

i.e. A deployment creates replicaset and replicaset in turn creates pod.

So, if you want to change anything in the pod Spec, you should make that change in the deployment, not in the replicaset or the pod directly as they will get overwritten.

Patch your deployment either by running and edit the environment field there:

kubectl edit deployment.apps <deployment-name> -n <namespace>

or update the deployment yaml with your changes and run

kubectl apply -f <deployment-yaml-file>
Raghwendra Singh
  • 2,084
  • 1
  • 13
  • 13
  • So you are saying that the `envFrom` block belongs in the deployment.yaml manifest? Being a kubernetes newbie, I also noticed that in my case the `spec.containers` block is basically repeated between the pod yaml and deployment yaml. So can I get rid of that block in the pod yaml and just let deployment yaml define them since it's the "parent"? If so, there's not much left in the pod yaml. Do I even need it? I'm having trouble understanding what goes in the pod spec and what in the deployment spec. Is there ever a need for a pod spec but no deployment spec? – Aaron Jul 12 '21 at 12:01
  • The `spec.containers` details from deployment is passed down the hierarchy. So it is not duplication, rather config getting passed on to the lowest level. A pod is an atomic compute object in kubernetes(k8s), just like a virtual machine is to a hypervisor. You can create it independently but you will be responsible for its lifecycle. K8s will not take any action when the pod dies or gets evicted. However with constructs like `deployment`, `statefulSet`, `replicaSet`, you provide some level of automation related to pod lifecycle. So, instead of creating simple pod, one creates `deployment` etc – Raghwendra Singh Jul 12 '21 at 12:19
  • So it is fine to define the container in deployment and not the pod if I never plan to use a pod without a container? – Aaron Jul 12 '21 at 12:51
  • It is better to use `deployment` than just `pod` for deploying a container in production because with `deployment`, you get a lot more features than a simple standalone `pod`. A brief explanation on why you need to deploy your container as part of `deployment` and not just `pod`: https://stackoverflow.com/a/47729498/777617 – Raghwendra Singh Jul 12 '21 at 14:10
  • Yay. @raghwendra-singh, this works. I can now see the env vars if I do `kb exec web-deployment-db786f754-jv9gl -- env`, but. my express app still can't read it. It prints out as undefined. Is there anything else I need as far as configuration? – Aaron Jul 12 '21 at 15:29
  • This all works for me now. I had an issue with the express image. Thanks! – Aaron Jul 13 '21 at 07:07