Prerequisites: kubernetes
Containers in the same Pod share a network namespace, but their image filesystems are otherwise separate. A Pod volume is the explicit bridge that lets selected containers see the same files. Each container must mount the named volume into its own filesystem.
The rendered Grafana Pod contains this volume:
volumes:
- name: sc-dashboard-volume
emptyDir: {}Both the dashboard sidecar and Grafana mount it at the same path:
volumeMounts:
- name: sc-dashboard-volume
mountPath: /tmp/dashboardsflowchart LR API[Kubernetes API\nselected ConfigMaps] S[Sidecar container\n/tmp/dashboards] V[(Pod emptyDir\nsc-dashboard-volume)] G[Grafana container\n/tmp/dashboards] API -->|watch and copy| S S -->|write file| V V -->|same mounted bytes| G
The two /tmp/dashboards paths look identical, but the important link is the shared volume name. A path inside a container is not automatically a host path and is not automatically visible to another container. Kubernetes mounts the same Pod-owned storage into both container mount namespaces.
What emptyDir means
Kubernetes creates an emptyDir when the Pod is assigned to a node. It survives an individual container crash because the Pod still exists. It is deleted when the Pod itself is removed from the node.
That lifecycle is correct here. The dashboard directory is a working cache, not the source of truth:
Git manifest -> ConfigMap -> sidecar copy -> emptyDir fileIf the Pod is replaced, the new volume starts empty. The sidecar watches the Kubernetes API, finds the labeled ConfigMap, and writes the file again. A persistent volume would add durability where none is required. Grafana’s database uses the separate kps-grafana-longhorn PersistentVolumeClaim because that state has a different lifecycle.
Why the exact path matters
Three independent settings must agree:
| Setting | Value |
|---|---|
| Sidecar root folder | /tmp/dashboards |
| ConfigMap folder annotation | /tmp/dashboards/Devata |
| Grafana home dashboard path | /tmp/dashboards/Devata/devata-overview.json |
The provider scans the root folder. The annotation adds the Devata subdirectory. The data key adds the filename. Grafana’s home setting points to the final result. A typo at any layer produces a valid Pod and a missing home dashboard.
Prove both containers see the same file:
pod=$(kubectl -n monitoring get pod \
-l app.kubernetes.io/name=grafana \
-o jsonpath='{.items[0].metadata.name}')
kubectl -n monitoring exec "$pod" -c grafana-sc-dashboard -- \
ls -l /tmp/dashboards/Devata/devata-overview.json
kubectl -n monitoring exec "$pod" -c grafana -- \
ls -l /tmp/dashboards/Devata/devata-overview.jsonOfficial reference: Kubernetes volumes and emptyDir.