diff --git a/test/e2e-framework/components/kubernetes/kubeadm.go b/test/e2e-framework/components/kubernetes/kubeadm.go index b713a77066af..7534c657005b 100644 --- a/test/e2e-framework/components/kubernetes/kubeadm.go +++ b/test/e2e-framework/components/kubernetes/kubeadm.go @@ -32,6 +32,10 @@ const kubeadmContainerdRepoReleasever = "9" // the current upstream latest release happens to ship. const kubeadmFlannelVersion = "v0.28.5" +// kubeadmMinorFile carries the Kubernetes minor from the CRI-O install step to +// the kubelet install step, which run as separate remote commands on the node. +const kubeadmMinorFile = "/etc/kubeadm-e2e-k8s-minor" + // ContainerRuntime selects the CRI installed on the kubeadm node. The Agent // produces identical SBOMs across runtimes; only the install steps and the CRI // socket differ. @@ -151,6 +155,12 @@ systemctl restart containerd`, kubeadmContainerdRepoReleasever) // newest stream that exists. The repo is $basearch (no $releasever), so // one repo serves RHEL 9 and 10, and CRI-O defaults to the systemd // cgroup driver, matching the kubelet. + // + // CRI-O releases track the Kubernetes minor they ship for, so the stream + // that was found also decides the cluster version: it is recorded in + // kubeadmMinorFile for the kubelet install below, which keeps the pair on + // one minor. A kubelet talking to a CRI-O two minors older brings pods up + // as far as Init:ImagePullBackOff and no further. runtimeScript = fmt.Sprintf(`kmaj=$(echo %[1]s | cut -d. -f1); kmin=$(echo %[1]s | cut -d. -f2) crio_ver="" for d in 0 1 2 3 4; do @@ -158,6 +168,8 @@ for d in 0 1 2 3 4; do if curl -fsSL -o /dev/null "https://pkgs.k8s.io/addons:/cri-o:/stable:/${cand}/rpm/repodata/repomd.xml"; then crio_ver="$cand"; break; fi done test -n "$crio_ver" || { echo "no CRI-O stable stream available at or below v%[1]s"; exit 1; } +printf '%%s' "${crio_ver#v}" >%[2]s +echo "CRI-O ${crio_ver} selected, pinning Kubernetes to ${crio_ver#v}" cat >/etc/yum.repos.d/cri-o.repo </etc/yum.repos.d/kubernetes.repo <<'EOF' + // The CRI-O install pins the minor it found in kubeadmMinorFile, so the + // kubelet follows the runtime onto one minor. The containerd path writes + // no such file and installs the requested minor. + Create: rootScript(fmt.Sprintf(`minor=%[1]s +if [ -s %[2]s ]; then minor=$(cat %[2]s); fi +cat >/etc/yum.repos.d/kubernetes.repo <