Make container building first class
Building a container should be easy, and with docker build
on your laptop, it is.
Unfortunately docker build
does not work very well in Kubernetes:
- It requires docker-in-docker, along with privileged mode, which is a significant security concern.
- Setting up dind requires extra non-obvious configuration, and it can run very slowly.
What you probably want to use is a tool like kaniko or img, or potentially a third party service like Google Container Builder.
But, these tools are not well known, and most developers probably think docker build
should just work... until they start getting strange errors because their GitLab Runner isn't privileged.
Because building Docker containers is a very typical workflow, we should make doing so easy and first class.
Proposal
We should consider developers who want to build containers, but may not know the best way to do so in Kubernetes or other container based environments.
MVC.1: CI YML templates
As a first iteration, we could create CI YML templates that could be included for different options:
- Kaniko
- Google Container Builder
- etc.
This requires no code changes, other than supporting kaniko, and so could be done quickly.
docker build
notification
MVC.2: There are two problems with MVC.1, one of which is discoverability. Users would first have to likely run into the limitations/problems of docker build
, then have to debug the issue and look for solutions. We could help by detecting someone attempting a docker build
, and provide information on solutions.
We could solve this by adding a notification for docker build
in one of a few potential areas:
- The CI YML linter, but the drawback here would be that it may not know when a job was run inside a container versus something like a shell. (Running docker build in a shell is fine.)
- We could add a post-processing step to the build log, which would run whenever a build job failed. If the failing step was
docker build
, we could helpfully point out that they may want to utilize a template as an alternative. This means they'd have to try and fail first, after potentially investing time trying to figure this all out, before we helped them. - Some other location.
Longer term: First class container builds
Since building containers is a very common job for CI to perform, we could consider special casing it. This way users don't need to worry about the details, and we can make it very easy to use the right tool for the job.
One way we do this would be to add some additional options to our CI YML format, to specifically denote a job syntax for building containers, without the implementation details. We would offer some optional configuration, if you wanted to override defaults (tag is SHA, repo is GitLab, etc.) Something like:
build:
type: container-build
parameters:
- repository: hub.docker.com
- image: debian
- tag: $CI_COMMIT_TAG
Given the above paramters, we could offer the project admin a selection of container builder solutions:
- kaniko: Building containers (propose as being the default)
- docker build, runC build, etc: Use the standard tools to build the container, perhaps on a
shell
executor - Google Container Builder, other services: If you want to use a service to do so, this can make it transparent
We would then automatically kick off the container build using your selected technology, and you could even seamlessly change technologies without much work in editing CI YML. The config necessary to authenticate to said service could be provided in this UI.
Even nicer, a company could potentially set this at the instance/group level to maintain some level of control.