Kubernetes has a rich way of expressing volumes/ volumeMounts for mounting files, emptyDir for ephemeral directories, and env/envFrom for adding environment variables to your container definition running on a Kubernetes cluster.
However, if you are actively iterating on the development of an image, it may slow you down to require a deployment to a remote Kubernetes cluster or even a small local Kubernetes implementation.
In this article, I will show you how to use the Docker equivalent of volumes/volumeMounts, emptyDir, and env/envFrom so that you can develop and test on your local Docker service without needing Kubernetes.
Equivalent of volumes/volumeMounts
You can mount local files to a specific location using the ‘-v’ volume flag.
Here is an example of mounting a local file at ‘/etc/nginx/nginx.conf’ which would control the main configuration of an NGINX based container.
docker ... -v /my/local/path/nginx.conf:/etc/nginx/nginx.conf:ro
Equivalent of emptyDir
You can create ephemeral directories using a tmpfs mount.
The example below creates a local directory only available inside the container at ‘/var/log/nginx’ that could be used to write logs.
docker ... --mount type=tmpfs,destination=/var/log/nginx
Equivalent of env/envFrom
Set a single environment variable using the ‘env’ flag.
docker ... --env key=value
Set a group of key/value pairs from a file using the ‘env-file’ flag.
docker ... --env-file env.properties
Example Project
I’ve uploaded a project to github to test the above scenarios.
sudo apt install git curl make -y git clone https://github.com/fabianlee/k8s-vol-and-vars-for-docker.git cd k8s-vol-and-vars-for-docker root_dir=$(realpath .)
Deployment to Kubernetes
First, let’s get a baseline of functionality used in our Kubernetes deployment.
- volumeMounts for /usr/share/nginx/html/index.html (main content for HTTP)
- volumeMounts for secret at /usr/share/nginx/html/.htpasswd (BASIC auth)
- volumeMounts for /etc/nginx/nginx.conf (config and BASIC auth)
- emptyDir for /var/log/nginx (access and error logs)
- inline static env var “my_key”
- envFrom for all keys in file “env.properties”
cd $root_dir # view, then apply manifests make k8s-apply # run tests against kubernetes deployment make k8s-test
The output of the tests will show delivery of the custom index.html, BASIC auth for restricted content (which shows that nginx.conf and .htpasswd are in place), and the environment variables that are both static as well as from the env.properties file.
Test equivalents in Docker
If you do not already have Docker installed, you can refer back to my previous article for installation steps. Then deploy the same Docker image with mounts and environment variables matching the Kubernetes deployment.
sudo apt install git curl make -y cd $root_dir # build image make # run docker container in background make docker-run-bg # run tests against docker container running locally make test
The output of the tests will show delivery of the custom index.html, BASIC auth for restricted content (which shows that nginx.conf and .htpasswd are in place), and the environment variables that are both static as well as from the env.properties file.
Test of public content curl http://localhost:8080 Hello, World! k8s deployment with configmap, secret, and log emptyDir Test of restricted content curl -u "myuser:MyF4kePassw@rd" http://localhost:8080/restricted/ Hello, World! k8s deployment with configmap, secret, and log emptyDir Check environmental variables "docker" exec -it k8s-vol-and-vars-for-docker /bin/sh -c "env | sort | grep ^[a-z]" foo=bar fruit=apple my_key=My value vegetable=spinach
With these equivalent file mounts and environment definitions, you can get a tight write-deploy-test lifecycle that can be used to validate correctness of your image. And only then push the image to a registry accessible by your Kubernetes cluster.
Other image dependencies
If your image has other dependencies that cannot be substituted (e.g. service dependencies), and you must develop/test within Kubernetes, you should consider a small local Kubernetes implementation like microk8s or k3s.
REFERENCE
docker, declare environment files
jeffgeerling.com, mounting k8s secret single file inside pod
yogihosting, mounting configmap as file