Skip to content

Latest commit

 

History

History
95 lines (65 loc) · 3.9 KB

File metadata and controls

95 lines (65 loc) · 3.9 KB

In Kubernetes containers within a Pod can share volumes. Unfortunately, there is currently no way to share a directory from within a container directly with another container (but this is planned). In order to still use immutable configuration containers for application configuration init containers can be used to initialize an empty shared volume during startup.

In the Docker example the configuration Docker image was based on scratch which is an empty Docker image without any operating system files. We didn’t need anything more there because all what we want was the configuration data which is shared via Docker volumes. So this image is completely passive. However for the reason stated above we need some help from the base image to copy over the configuration data to the share directory. busybox is a good choice for the base image which allows us to use plain Unix cp for this task.

Create images

The images are created similar as in the plain Docker case. Like in the other examples we are using minikube as platform and the included Docker daemon for building the image. The following instructions assume that you already have a minikube running.

  • Set the Docker environment variables to point to the minikube Docker daemon

eval $(minikube docker-env)
  • Create the application Docker Image first which uses demo.war :

docker build -t k8spatterns/demo:1 -f Dockerfile-demo .
  • Now create the image config-dev-image which holds the configuration for the developer environment:

docker build --build-arg config=dev.properties -f Dockerfile-config -t k8spatterns/config-dev:1 .
Have a look into `Dockerfile-config`, it's a bit different then for usage with the Docker volume. It uses `busybox` as base images and contains an `ENTRYPOINT` for allowing to copy the configuration data. Also we don't need a container here, the image is sufficient.
  • Next lets create the configuration for the production environment from prod.properties. We create a production configuration similar to the development configuration:

docker build --build-arg config=prod.properties -f Dockerfile-config -t k8spatterns/config-prod:1 .

Apply Kubernetes resources

It’s time now to apply the Kubernetes resource descriptor:

kubectl create -f demo.yml
  • Open application

open $(minikube service --url demo)/demo

The only thing we have finally to do is to exchange the configuration image within the pod declaration of our deployment:

kubectl patch deployment demo --type json -p \
  '[ {"op" : "replace", "path": "/spec/template/spec/initContainers/0/image", "value": "k8spatterns/config-prod:1"}]'
Warning
There is currently an issue with Kubernetes not updating initContainers with kubectl patch or kubectl apply. Please track these issues for updates.

OpenShift Template

If you are on OpenShift, e.g. by running minishift, you can benefit from the template mechanism provided by OpenShift.

Our example can be deployed with the template defined in demo-openshift-template.yml:

oc create -f demo-openshift-template.yml

The template contains the same elements as in demo.yml but is parameterised on the init containers' image. The template variable used here is CONFIG_IMAGE and defaults to k8spatterns/config-dev:1.

To instantiate the template just call oc new-app with the configuration image you want to use:

oc new-app demo -p CONFIG_IMAGE=k8spatterns/config-prod:1