Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ jobs:
esac
echo "OK: image bundles the k8s ${{ matrix.minor }} toolchain"

- name: Verify containerd sandbox (pause) image is version-matched (C4)
run: |
set -euo pipefail
img="kairos-kubeadm:ci-${{ matrix.minor }}"
# The build pins containerd's sandbox_image to the pause kubeadm expects;
# assert they match so a stale/hardcoded pause tag can't regress (C4).
want="$(docker run --rm --entrypoint /usr/bin/kubeadm "$img" \
config images list --image-repository registry.k8s.io | grep -E '/pause:[0-9]')"
got="$(docker run --rm --entrypoint sh "$img" -c \
"grep -oE 'registry.k8s.io/pause:[0-9.]+' /etc/containerd/config.toml")"
echo "kubeadm pause: ${want}; containerd sandbox_image: ${got}"
[ "$got" = "$want" ] || { echo "pause mismatch (C4): containerd ${got} != kubeadm ${want}" >&2; exit 1; }
echo "OK: sandbox_image is version-matched to kubeadm"

- name: Verify kubeadm exposes the upgrade-path surface (ADR-12)
run: |
set -euo pipefail
Expand Down
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,21 @@ COPY systemd/kubelet.service.d/10-kubeadm.conf /etc/systemd/system/kubelet.servi
COPY sysctl/k8s.conf /etc/sysctl.d/k8s.conf
COPY modules-load/k8s.conf /etc/modules-load.d/k8s.conf

# Pin containerd's pod-sandbox (pause) image to the EXACT version the bundled
# kubeadm expects for this Kubernetes minor, instead of a hardcoded tag. kubeadm
# bumps the pause version per release (e.g. 3.10.1 in 1.34/1.35 -> 3.10.2 in 1.36);
# a stale tag means containerd pulls a different pause than kubeadm pre-pulled
# (duplicate image / drift -- pitfall C4). Resolved from kubeadm at build time so
# it always matches the bundled toolchain. kubeadm is static and runs here on musl.
RUN set -eux; \
pause="$(/usr/bin/kubeadm config images list \
--kubernetes-version "${KUBERNETES_VERSION}" \
--image-repository registry.k8s.io | grep -E '/pause:[0-9]')"; \
test -n "${pause}"; \
sed -i "s#^\([[:space:]]*sandbox_image[[:space:]]*=\).*#\1 \"${pause}\"#" /etc/containerd/config.toml; \
grep -q "sandbox_image = \"${pause}\"" /etc/containerd/config.toml; \
echo "pinned containerd sandbox_image to ${pause}"

# --- Boot-time setup: enable services; modules and sysctls load via /etc -----
RUN systemctl enable containerd.service kubelet.service

Expand Down
7 changes: 5 additions & 2 deletions containerd/config.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# containerd configuration for kubeadm clusters built with provider-kubernetes.
# - sandbox image pinned to registry.k8s.io (NOT the dead k8s.gcr.io).
# - sandbox_image uses registry.k8s.io (NOT the dead k8s.gcr.io). The pause TAG
# below is a placeholder: the image build overwrites it with the exact pause
# version the bundled kubeadm expects for the target Kubernetes minor (see the
# Dockerfile), so it is always version-matched rather than a stale hardcoded tag.
# - SystemdCgroup = true, matching the kubelet's default cgroup driver
# ("systemd"); see https://kubernetes.io/docs/setup/production-environment/container-runtimes/.
version = 2
root = "/var/lib/containerd"

[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.k8s.io/pause:3.10"
sandbox_image = "registry.k8s.io/pause:3.10.1"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
Expand Down