The InitContainer
resource in Kubernetes is an interesting, and very useful resource; in many cases, you'll see it used to do things like prepopulate data in a volume before creating the containers in a Pod
deployment, so upon spinning up the containers, the volume data is already initialized.
In my case, I have a simple web frontend with a single static page, and it boots using the standard nginx
Docker image to serve a manifest file:
FROM nginx
COPY index.html /usr/share/nginx/html/index.html
COPY smartos.ipxe /usr/share/nginx/html/smartos.ipxe
This image builds and downloads very quickly, which is awesome, but partly because it's stateless; the the smartos.ipxe
file, for example, makes reference to release data that, upon spinning up the app, needs to be available or else those references will not work as intended (abstracted as a 404
HTTP response):
#!ipxe
dhcp
set base-url http://sdc-ipxe.east.gourmet.yoga
kernel ${base-url}/smartos/smartos/platform/i86pc/kernel/amd64/unix -B smartos=true,console=ttyb,ttyb-mode="115200,8,n,1,-"
module ${base-url}/smartos/smartos/platform/i86pc/amd64/boot_archive type=rootfs name=ramdisk
boot
These files, however, are not part of the app image because, for example, it updates frequently, so each time we rollout a new version, we'd like the latest release available in the volume, and since we don't need to maintain these files in the image, or else it would be very large and costly to store in our registry, we can mount a Volume to the containers in the Pod to provide them.
So, basically, we need a way to pre-populate a volume we're mounting to /usr/share/nginx/html/smartos
.
Using the InitContainer
resource, we can specify a command to be run, and like any other container in a Pod
, we can allocate a volume to be mounted, so let's start with a Kubernetes manifest like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sdc-ipxe-deployment
labels:
app: sdc-ipxe
spec:
replicas: 2
selector:
matchLabels:
app: sdc-ipxe
template:
metadata:
labels:
app: sdc-ipxe
spec:
initContainers:
- name: config-data
image: ubuntu:xenial
command: ["/bin/sh","-c"]
args: ["apt update; apt install -y wget tar; wget https://us-east.manta.joyent.com/Joyent_Dev/public/SmartOS/platform-latest.tgz; tar xvf platform-latest.tgz -C /data; mkdir /data/smartos; mv /data/platform* /data/smartos/platform"]
volumeMounts:
- mountPath: /data
name: sdc-data
volumes:
- name: sdc-data
hostPath:
path: /mnt/kube-data/sdc-ipxe/
type: DirectoryOrCreate
So, at this point, we're provisioning the volume sdc-data
, mounting it to an initContainer
called config-data
at /data
, and running:
"apt update; apt install -y wget tar; wget https://us-east.manta.joyent.com/Joyent_Dev/public/SmartOS/platform-latest.tgz; tar xvf platform-latest.tgz -C /data; mkdir /data/smartos; mv /data/platform* /data/smartos/platform"
to download and extract the data to the volume. Now, we we add a containers:
key to the manifest, and attach that Volume again, the prepopulated data will be availabnle:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sdc-ipxe-deployment
labels:
app: sdc-ipxe
...
containers:
- name: sdc-ipxe
image: coolregistryusa.bix/jmarhee/sdc-ipxe:latest
imagePullPolicy: Always
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/smartos
name: sdc-data
...
with the volume mounted where the app in the container expects, /usr/share/nginx/html/smartos
using the same sdc-data
volume.
Other examples of this pattern being useful can be if your application relies on configurations with variable requirements; maybe you're issued a token, or an address is fairly dynamic, and this needs to be passed through files on disk, rather than the environment (i.e. a loadbalancer, or webserver, or database client with a configuration file, not easily handled through a Secret or ConfigMap because of how often they change), this provides a somewhat easily programmable interface for pre-populating or completing the templating of data handed to a container.
Further Reading
Using InitContainers to pre-populate Volume data in Kubernetes
Top comments (0)