A fairly common setup I see for docker is to have a container spin up perform a task and then exit. This is something I do quite often with docker-compose where I have a node container that performs a build process and doesn't need to stay up once the static files have been built. In these cases if I look at the docker-compose ps
output, while my other containers are up and exposed on a port, the node containers state will be "Exit 0". Although otherwise dormant if I need to access this container it's available to be spun up.
What's a good practice for translating this setup to Kubernetes?
My initial approach was to place everything in one pod but the container exiting causes a CrashLoopBackOff and due to the pod restart policy the pod keeps restarting. If I were to keep this setup I'd only want the pod to restart if one of the other containers were to fail. It already moves the build static files into a volume that is accessible by the other containers.
Should this container be moved into another pod that does not restart? Seems like this would unnecessarily complicate the deployment.
Generally, to prevent POD from restating use restartPolicy: Never
(more on Restart Policy).
Also, for the thing which you want to run "to completion" use k8s component called Job
(more on Job):
apiVersion: batch/v1
kind: Job
metadata:
name: <job_name>
spec:
template:
spec:
containers:
<...>
To run Job till the first success (which is exit code 0
) set restartPolicy: OnFailure
.
a node container that performs a build process and doesn't need to stay up once the static files have been built
That sounds like exactly the definition of an init container: "They always run to completion. Each one must run successfully before the next one is started."
In your Deployment spec, in the Pod template part, you'd have a separate initContainers:
section that contains the separate build-only container. It has the exact same format as the containers:
section that contains the main application, but runs first, to completion, once. You may need to create a volume within the context of the Pod to share contents with the main container, but this can be something like an emptyDir:
type pod with no actual persistent storage.
If you really are "building" something in the sense of running a tool like Webpack that mostly generates static files, it's better still to move this process into a Dockerfile, so that you can run the unmodified image without doing still more building at deploy time.