From 8a1e000f36737b7c3fbae952d542f1dc2eb992b7 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Tue, 29 Sep 2026 22:08:26 +0200 Subject: [PATCH] runner: images: Build multi-arch Kubernetes images Build kube-proxy and pause images for amd64, arm64, and riscv64, and publish them to GHCR. Use these images when provisioning clusters and configuring containerd. --- .github/workflows/deploy-runner.yml | 97 ++++++++++++++++++- .../templates/containerd-config.toml.j2 | 2 +- runner/images/Dockerfile.kube-proxy | 34 +++++++ runner/images/Dockerfile.pause | 21 ++++ runner/images/README.md | 24 +++++ scripts/scw.py | 4 +- 6 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 runner/images/Dockerfile.kube-proxy create mode 100644 runner/images/Dockerfile.pause diff --git a/.github/workflows/deploy-runner.yml b/.github/workflows/deploy-runner.yml index 790de7e..57ba7a8 100644 --- a/.github/workflows/deploy-runner.yml +++ b/.github/workflows/deploy-runner.yml @@ -22,6 +22,9 @@ permissions: contents: write packages: write +env: + KUBERNETES_VERSION: v1.35.9 + jobs: setup: runs-on: ubuntu-latest @@ -95,6 +98,98 @@ jobs: push: ${{ needs.setup.outputs.push-images == 'true' }} pull: ${{ github.ref_name == github.event.repository.default_branch }} + build-kube-proxy: + runs-on: ubuntu-latest + needs: [setup] + permissions: + packages: write + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Login to Container Registry + if: ${{ needs.setup.outputs.push-images == 'true' }} + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Setup QEMU + uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # 4.3.0 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 + + - name: Build kube-proxy image + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 + env: + SOURCE_DATE_EPOCH: 0 + with: + context: runner/images + file: runner/images/Dockerfile.kube-proxy + platforms: linux/amd64,linux/arm64,linux/riscv64 + build-args: | + KUBERNETES_VERSION=${{ env.KUBERNETES_VERSION }} + tags: ghcr.io/${{ github.repository }}/kube-proxy:${{ env.KUBERNETES_VERSION }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: | + ${{ format('type=registry,ref=ghcr.io/{0}/kube-proxy:buildcache', github.repository) }} + cache-to: | + ${{ github.ref_name == github.event.repository.default_branch && format('type=registry,ref=ghcr.io/{0}/kube-proxy:buildcache,mode=max', github.repository) || '' }} + push: ${{ needs.setup.outputs.push-images == 'true' }} + pull: ${{ github.ref_name == github.event.repository.default_branch }} + + build-pause: + runs-on: ubuntu-latest + needs: [setup] + permissions: + packages: write + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Login to Container Registry + if: ${{ needs.setup.outputs.push-images == 'true' }} + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Setup QEMU + uses: docker/setup-qemu-action@1f40c72289eff860ee54a304f1438e3cff362e0a # 4.3.0 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 + + - name: Build pause image + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 + env: + SOURCE_DATE_EPOCH: 0 + with: + context: runner/images + file: runner/images/Dockerfile.pause + platforms: linux/amd64,linux/arm64,linux/riscv64 + build-args: | + KUBERNETES_VERSION=${{ env.KUBERNETES_VERSION }} + tags: ghcr.io/${{ github.repository }}/pause:3.10 + labels: ${{ steps.meta.outputs.labels }} + cache-from: | + ${{ format('type=registry,ref=ghcr.io/{0}/pause:buildcache', github.repository) }} + cache-to: | + ${{ github.ref_name == github.event.repository.default_branch && format('type=registry,ref=ghcr.io/{0}/pause:buildcache,mode=max', github.repository) || '' }} + push: ${{ needs.setup.outputs.push-images == 'true' }} + pull: ${{ github.ref_name == github.event.repository.default_branch }} + test-device-plugin: runs-on: ubuntu-latest defaults: @@ -167,7 +262,7 @@ jobs: deploy-staging: if: github.repository_owner == 'riseproject-dev' && github.ref_name == github.event.repository.default_branch name: "deploy to staging" - needs: [setup, build-images, build-device-plugin] + needs: [setup, build-images, build-kube-proxy, build-pause, build-device-plugin] runs-on: ubuntu-latest environment: staging concurrency: diff --git a/runner/ansible/roles/userspace/templates/containerd-config.toml.j2 b/runner/ansible/roles/userspace/templates/containerd-config.toml.j2 index 1c4fceb..60c115d 100644 --- a/runner/ansible/roles/userspace/templates/containerd-config.toml.j2 +++ b/runner/ansible/roles/userspace/templates/containerd-config.toml.j2 @@ -10,7 +10,7 @@ version = 2 [plugins] [plugins."io.containerd.grpc.v1.cri"] - sandbox_image = "cloudv10x/pause:3.10" + sandbox_image = "ghcr.io/riseproject-dev/riscv-runner/pause:3.10" [plugins."io.containerd.grpc.v1.cri".containerd] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] diff --git a/runner/images/Dockerfile.kube-proxy b/runner/images/Dockerfile.kube-proxy new file mode 100644 index 0000000..cb85fb4 --- /dev/null +++ b/runner/images/Dockerfile.kube-proxy @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: MIT + +ARG BUILDARCH +FROM --platform=linux/${BUILDARCH} golang:1.25.5-trixie AS build + +ARG KUBERNETES_VERSION=v1.35.0 +ARG TARGETARCH + +RUN apt-get update && apt-get install -y --no-install-recommends rsync + +ENV GOTOOLCHAIN=local + +ADD https://github.com/kubernetes/kubernetes.git#${KUBERNETES_VERSION} /src/kubernetes + +WORKDIR /src/kubernetes + +RUN KUBE_BUILD_PLATFORMS="linux/${TARGETARCH}" make WHAT=cmd/kube-proxy \ + && find _output -type f -name kube-proxy -perm /111 -exec cp {} /kube-proxy \; -quit \ + && test -x /kube-proxy + +FROM debian:trixie-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + conntrack \ + iproute2 \ + ipset \ + iptables \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build --chmod=755 /kube-proxy /usr/local/bin/kube-proxy + +ENTRYPOINT ["/usr/local/bin/kube-proxy"] diff --git a/runner/images/Dockerfile.pause b/runner/images/Dockerfile.pause new file mode 100644 index 0000000..068d09f --- /dev/null +++ b/runner/images/Dockerfile.pause @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: MIT + +FROM debian:trixie AS build + +ARG KUBERNETES_VERSION=v1.35.0 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates gcc libc6-dev \ + && rm -rf /var/lib/apt/lists/* + +ADD --checksum=sha256:14a3fe21ab5f8e62937a2b453e76f3b94b0d3c7c04c3d09bc37195f54c1695ea \ + https://raw.githubusercontent.com/kubernetes/kubernetes/${KUBERNETES_VERSION}/build/pause/linux/pause.c /pause.c + +RUN gcc -Os -Wall -Werror -static -o /pause /pause.c && strip /pause + +FROM scratch + +COPY --from=build --chmod=755 /pause /pause + +USER 65535:65535 +ENTRYPOINT ["/pause"] diff --git a/runner/images/README.md b/runner/images/README.md index 2c857a7..b5119bd 100644 --- a/runner/images/README.md +++ b/runner/images/README.md @@ -9,6 +9,8 @@ For the full image inventory (every preinstalled tool with its version), the bui ``` runner/images/ ├── Dockerfile.ubuntu Runner image (multi-stage, parameterised by OS_VERSION) +├── Dockerfile.kube-proxy Multi-architecture Kubernetes kube-proxy image +├── Dockerfile.pause Multi-architecture Kubernetes pause image └── riscv-runner-entrypoint.sh PID-1 entrypoint, exec's run.sh --jitconfig "$RUNNER_JITCONFIG" ``` @@ -32,6 +34,28 @@ docker buildx build \ Best run on a RISC-V host so no emulation is involved. On x86_64, `binfmt_misc` with QEMU will let the build complete, slowly. +Build the Debian trixie-based kube-proxy image for all supported architectures: + +```sh +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/riscv64 \ + --file Dockerfile.kube-proxy \ + --tag ghcr.io/riseproject-dev/riscv-runner/kube-proxy:v1.35.0 \ + --push \ + . +``` + +Build the pause image for the same architectures: + +```sh +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/riscv64 \ + --file Dockerfile.pause \ + --tag ghcr.io/riseproject-dev/riscv-runner/pause:3.10 \ + --push \ + . +``` + ## Updating pinned versions ```sh diff --git a/scripts/scw.py b/scripts/scw.py index 7628a35..b47255b 100644 --- a/scripts/scw.py +++ b/scripts/scw.py @@ -1355,7 +1355,7 @@ def _do_runner_delete(runner): mkdir -p /etc/containerd containerd config default > /etc/containerd/config.toml sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml - sed -i 's|sandbox_image = ".*"|sandbox_image = "cloudv10x/pause:3.10"|' /etc/containerd/config.toml + sed -i 's|sandbox_image = ".*"|sandbox_image = "ghcr.io/riseproject-dev/riscv-runner/pause:3.10"|' /etc/containerd/config.toml systemctl restart containerd # Install kubelet, kubeadm, kubectl from official apt-get repo @@ -1394,7 +1394,7 @@ def _do_runner_delete(runner): kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml # Switch kube-proxy to the multi-arch compatible image - kubectl set image daemonset/kube-proxy -n kube-system kube-proxy=cloudv10x/kube-proxy:1.35.0 + kubectl set image daemonset/kube-proxy -n kube-system kube-proxy=ghcr.io/riseproject-dev/riscv-runner/kube-proxy:v1.35.0 # Create user kubeconfigs (these will use the private IP as server address; # the script replaces it with the public IP when printing)