Problem: I needed to copy some database files into a container running on Kubernetes without modifying the image or restarting the parent Pod.
Solution: The Kubernetes CLI includes a sub-command for copying files into and out of a running container: kubectl cp /tmp/foo <some-pod>:/tmp/bar
Background
I’ve never found the need to copy files into a running container without issuing an updated image. This is somewhat of an anti-pattern as modifications to containerised filesystems that aren’t mounted externally are lost when the container process terminates.
I was trying to seed the Trivy vulnerability database in an air-gapped deployment (instructions here).
The Kubernetes documentation is the best place to go for a full description of how to use kubectl cp
. Options are limited but there are examples for most use-cases.
The documentation includes the following note:
“!!!Important Note!!! # Requires that the ’tar’ binary is present in your container # image. If ’tar’ is not present, ‘kubectl cp’ will fail.”
This piqued my curiosity. Why the need for the tar command? How do you copy a file into a container? A look at the source code shows the following:
- Start a go routine to tar the source and write it to an io.Writer
- Run
tar -xmf -
inside the target container usingkubectl exec
- Connect the io.Writer from #1 to
stdin
on #2
The command run in the container extracts the tar stream. The -f -
option tells us it reads the stream from stdin
.
If I’d had to guess how this was implemented, I’d have assumed the command was somehow copying files directly to the container filesystem on the underlying node. The actual solution is a lot nicer.