0

I have what I believe to be the simplest of k8s deployments using a configmap value as a file and it refuses to work, instead returning this error message:

The Pod "configmap-demo-pod" is invalid: spec.containers[0].volumeMounts[0].name: Not found: "the-thing"

This is a watered-down version of what I found in the documentation so I am completely at a loss as to what I'm missing.

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo
data:
  the-thing: |
    hello

---


apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      volumeMounts:
      - mountPath: "/"
        name: the-thing
  volumes:
    - name: config
      configMap:
        name: demo
        items:
        - key: the-thing
          path: "filename"
Daniel Quinn
  • 555
  • 2
  • 6
  • 14
  • 1
    Your configmap volume is named `config`, not `the-thing`. Separately, it seems highly unlikely you want to mount it on `/`; that will probably result in nothing working. – larsks Jul 02 '22 at 19:56
  • Sorry, but could you walk me through that a little more? If the volume mount doesn't have the name of the config item it's supposed to put in the file, how does it know what to put in there? If I had a second config item called `the-other-thing` how would I indicated which data goes on which file of they both have `config` in the mount point name? As for the `/` mount point, that can be anything at this point and I thought leaving it as `/` would reduce complications for the question. – Daniel Quinn Jul 02 '22 at 22:49

1 Answers1

3

You have defined a volume like this:

  volumes:
    - name: config
      configMap:
        name: demo
        items:
        - key: the-thing
          path: "filename"

The volume is named config, because you have name: config. It refers to a ConfigMap named demo, and you are (trying to) explicitly include just a single key, named the-thing.

When you mount this volume in a container, you refer to it using the name you assigned to the volume, config. So:

volumeMounts:
  - name: config
    mountPath: /some/path

You would never want mountPath to be / because that would attempt to mount the volume over the contents of the filesystem root, which would result in an unusable container.


But let's take a brief step back.

Given a ConfigMap with multiple keys, like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo
data:
  the-thing: |
    hello
  an-example: |
    this is a test

We can expose all the keys as files on the filesystem like this:

apiVersion: v1
data:
  an-example: |
    this is a test
  the-thing: |
    hello
kind: ConfigMap
metadata:
  name: demo
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
  - command:
    - sleep
    - inf
    image: alpine
    name: demo
    volumeMounts:
    - mountPath: /config
      name: config
  volumes:
  - configMap:
      name: demo
    name: config

If we were to deploy those into kubernetes, we would find:

$ kubectl exec -it configmap-demo-pod -- sh
/ # ls /config
an-example  the-thing
/ # cat /config/the-thing
hello
/ # cat /config/an-example
this is a test
/ #

If we want to expose a subset of the available keys, we can modify the volume definition to specify a list of keys and paths, like this:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command:
        - sleep
        - inf
      volumeMounts:
      - mountPath: "/config"
        name: config
  volumes:
    - name: config
      configMap:
        name: demo
        items:
          - key: the-thing
            path: another-thing

Here, items provides a list of the keys we want to expose, along with the corresponding name they will have in the filesystem. In this example, we're exposing the key the-thing as a file named another-thing. Deploying using this manifest gets us:

$ kubectl exec -it configmap-demo-pod -- sh
/ # ls /config
another-thing
/ # cat /config/another-thing
hello
/ #

The above two examples expose the ConfigMap as a directory, and give you access to either all available keys (the first example) or a subset of the keys (the second example). It's also possible to expose a specific key as a file at an arbitrary location in the filesystem using the subPath option on your volumeMount configuration, like this:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command:
        - sleep
        - inf
      volumeMounts:
      - mountPath: "/etc/the-thing"
        name: config
        subPath: the-thing
  volumes:
    - name: config
      configMap:
        name: demo

Deploying that gives us:

[lars@madhatter k8s]$ kubectl exec -it configmap-demo-pod -- sh
/ # cat /etc/the-thing
hello
larsks
  • 41,276
  • 13
  • 117
  • 170