Kubernetes ConfigMap keys have to match subpaths

I use Kubernetes ConfigMaps to expose static configuration data (such as a configuration or password file), where:

  1. I’m OK with the config file being read-only within the container, and..
  2. I don’t want to bother using a (minimum 1Gb) persistent disk for a few scrawny files.

I’d been under the impression that I could create a configmap from any local file (i.e. batman.txt), and expose it to my pod with an arbitrary filename (i.e. /etc/superman.txt). As it turns out, that’s not the case…

I tried my renaming trick in a recent MQTT broker deployment I’ve been working on. I created the configmap for a customized version of mosquitto.conf (I already had a ConfigMap for a standard version), as follows:

kubectl -n mqtt create configmap mosquitto-batman.conf \
--from-file=mosquitto-batman.conf

Then I tried to mount this into my pod as follows:

- name: mosquitto-batman-conf
  mountPath: /mosquitto/conf/mosquitto.conf
  subPath: mosquitto.conf

(Why use a subPath? Because there was another ConfigMap also mounted inside the /mosquitto/conf directory)

The result of the above, inside the container, was a empty directory (not a file), named /mosquitto/conf/mosqitto.conf/. Not what I wanted!

As I discovered by reading this issue, if you’re going to use a subPath, the value of the subPath must match the “key” of the ConfigMap. But wait, what’s the key? Well, it’s the name of the file we imported to create the ConfigMap.

You can identify the key by “describing” the ConfigMap:

[davidy:~] % kubectl describe configmap mosquitto-batman-conf -n mqtt
Name:         mosquitto-batman-conf
Namespace:    mqtt
Labels:       <none>
Annotations:  <none>

Data
====
mosquitto-batman.conf:
----
# Config file for mosquitto
#
# See mosquitto.conf(5) for more information.
#

# =================================================================
# General configuration
# =================================================================
<blah blah other stuff>

In this case, it’s “mosqitto-batman.conf” - but I was trying to use a subPath of “mosquitto.conf”!

So, this ended up as a classic case of trying to be too clever for my own good. I renamed the file to “batman/mosquitto.conf”, and recreated the ConfigMap by running:

kubectl -n mqtt create configmap mosquitto-batman.conf \
--from-file=batman/mosquitto.conf

Now when I describe my ConfigMap, the key is correct:

Data
====
mosquitto.conf:

And I expose it to the container using:

- name: mosquitto-batman-conf
  mountPath: /mosquitto/conf/mosquitto.conf
  subPath: mosquitto.conf

Success!