BuildKit containerd worker image
Creating container image for BuildKit containerd worker
This article is part of the Building streamable containers in EKS series.
Remote containerd buildkit workers
Our end goal is to create a Kubernetes pod that will run buildkit, containerd and soci-snapshotter daemons, allow buildkit to communicate with containerd and also allow containerd to use the soci-snapshotter.
We could attempt to have a pod with 2 containers - one for buldkit and one for containerd, however, that would require a lot cross-mounting between the two containers, as containerd client and daemon require the same “view” of file system mounts (see here, here and here)
Instead we’ll create a single container that runs all required daemons controlled with supervisord
Dockerfile
Below is a Dockerfile for our image that combines all buildkit, containerd, soci-snapshotter and a few other supporting utilities.
FROM ubuntu:22.04
ARG CONTAINERD_VERSION=2.0.0
ARG NERDCTL_VERSION=2.0.1
ARG SOCI_VERSION=0.8.0
ARG PLUGINS_VERSION=1.6.1
ARG CRITOOLS_VERSION=1.31.1
ARG BUILDKIT_VERSION=0.18.1
ARG RUNC_VERSION=1.2.2
USER root
ENV DEBIAN_FRONTEND=noninteractive
# tools
RUN --mount=type=cache,sharing=locked,id=apt-cache,target=/var/cache/apt apt-get update -y \
&& apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
amazon-ecr-credential-helper \
curl \
fuse3 \
fuse-overlayfs \
git \
gnupg \
iproute2 \
iptables \
kmod \
net-tools \
socat \
jq \
unzip \
supervisor \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# containerd
RUN mkdir /tmp/containerd \
&& cd /tmp/containerd \
&& curl -sL https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz -o "containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz" \
&& tar xvf containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz \
&& mv bin/containerd-shim-runc-v2 /usr/bin/containerd-shim-runc-v2 \
&& mv bin/containerd /usr/bin/containerd \
&& mv bin/containerd-stress /usr/bin/containerd-stress \
&& mv bin/ctr /usr/bin/ctr \
&& cd / \
&& rm -rf /tmp/containerd \
&& mkdir -p /etc/containerd
# containerd plugins
RUN mkdir -p /opt/cni/bin /opt/containerd \
&& cd /opt/cni/bin \
&& ln -s /opt/cni/bin /opt/containerd/bin \
&& cd /opt/cni/bin \
&& curl -sL "https://github.com/containernetworking/plugins/releases/download/v${PLUGINS_VERSION}/cni-plugins-linux-amd64-v${PLUGINS_VERSION}.tgz" -o "cni-plugins-linux-amd64-${PLUGINS_VERSION}.tgz" \
&& tar xvf "cni-plugins-linux-amd64-${PLUGINS_VERSION}.tgz" \
&& rm -rf "cni-plugins-linux-amd64-${PLUGINS_VERSION}.tgz"
# critools
RUN mkdir /tmp/critools \
&& cd /tmp/critools \
&& curl -sL "https://github.com/kubernetes-sigs/cri-tools/releases/download/v${CRITOOLS_VERSION}/crictl-v${CRITOOLS_VERSION}-linux-amd64.tar.gz" -o "crictl-v${CRITOOLS_VERSION}-linux-amd64.tar.gz" \
&& tar xvf "crictl-v${CRITOOLS_VERSION}-linux-amd64.tar.gz" \
&& mv crictl /usr/local/bin \
&& cd / \
&& rm -rf /tmp/critools
# runc
RUN mkdir /tmp/runc \
&& cd /tmp/runc \
&& curl -sL "https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.amd64" -o "runc.amd64" \
&& mv runc.amd64 /usr/local/bin/runc \
&& chmod +x /usr/local/bin/runc \
&& cd / \
&& rm -rf /tmp/runc
# buildkit
RUN mkdir /tmp/buildkit \
&& cd /tmp/buildkit \
&& curl -sL "https://github.com/moby/buildkit/releases/download/v${BUILDKIT_VERSION}/buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz" -o "buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz" \
&& tar xvf "buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz" \
&& mv bin/* /usr/bin \
&& cd / \
&& rm -rf /tmp/buildkit \
&& mkdir -p /etc/buildkit
# nerdctl
RUN mkdir /tmp/nerdctl \
&& cd /tmp/nerdctl \
&& curl -sL "https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz" -o "nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz" \
&& tar xvf "nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz" \
&& mv nerdctl /usr/local/bin \
&& cd / \
&& rm -rf /tmp/nerdctl
# soci
RUN mkdir /tmp/soci \
&& cd /tmp/soci \
&& curl -sL "https://github.com/awslabs/soci-snapshotter/releases/download/v${SOCI_VERSION}/soci-snapshotter-${SOCI_VERSION}-linux-amd64.tar.gz" -o "soci-snapshotter-${SOCI_VERSION}-linux-amd64.tar.gz" \
&& tar -zxvf "soci-snapshotter-${SOCI_VERSION}-linux-amd64.tar.gz" \
&& mv soci /usr/local/bin \
&& mv soci-snapshotter-grpc /usr/local/bin \
&& cd \
&& rm -rf /tmp/soci
# create a helper script for building SOCI indexes using nerdctl
COPY <<'EOF' /soci.sh
#!/usr/bin/env bash
# build and push image SOCI index with nerdctl, pulling the image first if needed.
# soci.sh <containerd namespace> <image:tag>
all_images="$(nerdctl --namespace ${1} images --format json)"
if [[ "${all_images}" = "" ]]; then
nerdctl --namespace ${1} pull ${image_name}
elif ! echo ${all_images} | jq -e --arg name "${2}" 'select(.Name == $name)'; then
nerdctl --namespace ${1} pull ${image_name}
fi
nerdctl --namespace ${1} push --snapshotter=soci ${2}
EOF
RUN chmod +x /soci.sh
# create docker config with aws credential helper config
# This example assumes use of ECR as the target registry for pushing buult images and SOCI indexes
COPY <<'EOF' /root/.docker/config.json
{
"credsStore": "ecr-login"
}
EOF
WORKDIR /
ENV CONTAINERD_VERSION=${CONTAINERD_VERSION}
ENV NERDCTL_VERSION=${NERDCTL_VERSION}
ENV SOCI_VERSION=${SOCI_VERSION}
ENV PLUGINS_VERSION=${PLUGINS_VERSION}
ENV CRITOOLS_VERSION=${CRITOOLS_VERSION}
ENV BUILDKIT_VERSION=${BUILDKIT_VERSION}
ENV RUNC_VERSION=${RUNC_VERSION}
ENTRYPOINT ["/usr/bin/supervisord"]
Pre-built linux/amd64 image is available at ghcr.io/maratoid/containerd-soci-builder:1.0.0
More
- Previous: SOCI, buildkit and containerd
- Check out the complete Building streamable containers in EKS series