Building container images
OpsChain step runners are executed in unprivileged containers to maintain security. This means that Docker, BuildKit, and Buildah cannot be run within an OpsChain step runner container.
Using remote tools to build images
OpsChain step runners can leverage external build infrastructure to build container images whilst maintaining security within the OpsChain stack. This means that the external tooling can follow an organisation's best practices, and then OpsChain can leverage that tooling.
Using cloud image builders
Some cloud providers offer services for building container images - for example the Azure Container Registry Tasks.
These can be used from OpsChain as normal.
Using Kaniko
Kaniko is a Kubernetes native tool for building container images.
A Kaniko instance can be used from an OpsChain step runner as normal.
The default opschain-runner
service account does not have permission to create pods within Kubernetes, hence new Kaniko containers cannot be created with the default setup. You can update the opschain-runner
service account's roles (see an example), however care should be taken when adding permissions to the runner as this may create security issues.
Using Docker
OpsChain step runner containers can use their custom step runner Dockerfile to install the Docker CLI and interact with a remote Docker host, for example:
RUN dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo && dnf install -y docker-ce-cli
Then in the OpsChain properties add the configuration for the Docker host to use (this example uses SSH to access the remote Docker instance, but another authentication method could be used):
{
"opschain": {
"env": {
"DOCKER_HOST": "ssh://user@docker-remote-host"
},
"files": {
"~/.ssh/id_rsa": {
"content": "{{ssh key for docker-remote-host}}",
"mode": "0600"
},
"~/.ssh/known_hosts": {
"content": "{{known_hosts file for docker-remote-host}}",
"mode": "0600"
}
}
}
}
Now the docker
command can be used within the step runner, but the actual commands will be run using the remote Docker host.
Docker volumes are mounted from the host running the daemon, so uses of Docker volumes will not mount paths from the OpsChain step runner, which may be confusing. Build contexts are transparently copied to the remote host.
Using BuildKit
Similar to how Docker can be used remotely, BuildKit can be run on a remote host (or container) and leveraged from within the OpsChain step runner.
BuildKit provides the buildctl
tool which can be used to perform builds against a remote BuildKit instance.
buildctl
is a lower-level tool than Docker, so whilst it is an option, using Docker as suggested above may be simpler.
Directly modifying images
The skopeo and umoci tools can be used to retrieve and modify container images directly.
These tools can be installed as part of a custom step runner Dockerfile, e.g.:
RUN dnf install -y skopeo
RUN curl -L https://github.com/opencontainers/umoci/releases/latest/download/umoci.amd64 -o /usr/local/bin/umoci && chmod +x /usr/local/bin/umoci
Example - adding files to an image
Below is an example of using skopeo and umoci to modify the contents of the Docker Library nginx image. This example is analogous to placing static web assets in a container as part of a web application deployment, or placing a WAR file into an application server container.
First, copy the base image from the remote registry using skopeo (this is using the nginx image from Docker Hub):
skopeo copy docker://nginx:alpine oci:nginx:alpine
Next, unpack the image to allow for modifications:
umoci unpack --rootless --image nginx:alpine bundle
Now perform any desired modifications - this is a simple example of modifying a file, but this could use files retrieved from a source like Artifactory:
echo 'Hello world' > bundle/rootfs/usr/share/nginx/html/index.html
Once the desired modifications have been made, use umoci to repack the image:
umoci repack --image nginx:demo bundle
Now skopeo can be used to upload the image to a registry, or the image could be exported as a Docker tarball for use by docker load
:
# Example 1: copy the image into the main Docker Hub registry as organisation/nginx-testing:demo
$ skopeo copy --dest-creds '{{registry creds}}' oci:nginx:demo docker://organisation/nginx-testing:demo
# Example 2: copy the image to a Docker tarball, upload `demo-image.tar` somewhere for use by Docker
$ skopeo copy --additional-tag nginx:demo oci:nginx:demo docker-archive:demo-image.tar
# e.g. load and run the image, assumes a remote Docker exists and is configured
$ docker -H ssh://username@remote-docker load < demo-image.tar
$ docker -H ssh://username@remote-docker run -p 8080:80 -d --name nginx-demo nginx:demo
$ curl remote-docker:8080
Hello world
Feedback
We're planning to enhance OpsChain's abilities to build container images in the future. If this is a feature you're interested in, we would love to hear from you so that we can learn more about your use case.