dependency injection
Context and problem
Dependency injection (DI) or "well known plugins" are a common and robust pattern in customization scenarios in the enterprise.
It's a pattern that has been used by ISVs to enable thier down stream users to customize products.
This can present challanges as ISVs modernize to containers because the ISVs want to deliver software in immutable containers but the requirement to customize by including libraries is still a concrete requirement.
Solution
Configure the application container at start up with an init container.
The sample defines a disk volume that enables config to be passed from an initialization container to the main application container.
This scenario provides a pod definition a starting point that can be extended to meet the requirements.
In production this should be a persistent volume claim and NOT a hostPath as deployments will clobber each other
Issues and considerations
Loading libraries and config from an external source may require managing PATH
priorities and loading orders that could potentially be brittle.
Areas of responsibility between vendor and client can become blurred although no worse that the virtual machine scenario.
When to use this scenario
This pattern is probably most relevent when moving from Rehost to Replatform.
Use this approach when you have additional configuration that needs to be deployed on a per container basis.
Example
apiVersion: v1
kind: Pod
metadata:
name: di-pod
labels:
app.kubernetes.io/name: DiApp
spec:
containers:
# The main container that echos the file created by the init container.
- name: app-container
image: registry.access.redhat.com/ubi8/ubi-minimal
command: ['sh', '-c', 'cat /usr/share/initfile && sleep 3600']
volumeMounts:
- name: shared-data
mountPath: /usr/share
initContainers:
# A simple init container that echos a file into the shared data folder on startup
- name: init-deps
image: registry.access.redhat.com/ubi8/ubi-minimal
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ['sh', '-c', "echo Hello from the init container > /pod-data/initfile"]
# defines a volume to enable config to be passed to the main container
# In production this should be a persistent volume claim
# NOT a hostPath as deployments will clobber each other
volumes :
- hostPath:
path: /tmp/di
type: Directory
name: shared-data
To run the scenario locally make sure you have podman installed and run the following commands:
-
Create a folder to match the volume definitions
mkdir /tmp/di
-
Play the pod definition with podman
podman play kube pod.yaml
-
Inspect the logs to see the main container has access to the file generated by the init container.
podman logs di-pod-app-container Hello from the init container!
-
Clean up
podman pod stop di-pod podman pod rm di-pod rm -fr /tmp/di