From 81d192d577261de600e03a12779e0ca1f6110870832750441c33ad247f030478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Tue, 24 Mar 2026 21:16:21 +0800 Subject: [PATCH] Now we properly preloaded the images without load at boot --- alpine/preload-k8s-images.sh | 152 ++++++++++-------- .../rootfs-extra/opt/scripts/load-images.sh | 56 ------- alpine/rootfs-extra/opt/scripts/test-crio.sh | 65 ++++++++ 3 files changed, 148 insertions(+), 125 deletions(-) delete mode 100755 alpine/rootfs-extra/opt/scripts/load-images.sh create mode 100755 alpine/rootfs-extra/opt/scripts/test-crio.sh diff --git a/alpine/preload-k8s-images.sh b/alpine/preload-k8s-images.sh index 22388dd..a1aa0f8 100755 --- a/alpine/preload-k8s-images.sh +++ b/alpine/preload-k8s-images.sh @@ -4,103 +4,117 @@ set -euo pipefail : "${KUBE_IMG_CACHE:?KUBE_IMG_CACHE is required}" : "${KUBE_VERSION:?KUBE_VERSION is required}" : "${ARCH:?ARCH is required}" +: "${ROOTFS:?ROOTFS is required}" OS=linux -REGISTRY_PORT=5000 -# Keep everything version/arch scoped so caches do not get mixed. +# IMPORTANT: +# This must match what the target system will use at runtime. +# If your target CRI-O uses overlay, leave this as overlay. +# If overlay seeding fails in your build environment, fix the build env; +# do not silently switch to vfs unless the target will also use vfs. +STORAGE_DRIVER="${STORAGE_DRIVER:-overlay}" + +# Optional. Needed by many overlay-in-container setups. +FUSE_OVERLAYFS="${FUSE_OVERLAYFS:-/usr/bin/fuse-overlayfs}" + +# Keep archive cache version/arch scoped so downloads do not get mixed. ARCHIVE_DIR="${KUBE_IMG_CACHE}/archives/${ARCH}/${KUBE_VERSION}" -REGISTRY_DATA_DIR="${KUBE_IMG_CACHE}/registry-data/${ARCH}/${KUBE_VERSION}" -REGISTRY_TAR="${KUBE_IMG_CACHE}/registry.tar" -REGISTRY_IMAGE="docker.io/library/registry:2" -if podman image exists "${REGISTRY_IMAGE}"; then - echo "Registry image already present: ${REGISTRY_IMAGE}" +# Seed directly into the target rootfs image store. +TARGET_GRAPHROOT="${ROOTFS}/var/lib/containers/storage" -elif [ -f "${REGISTRY_TAR}" ]; then - echo "Loading registry image from cache: ${REGISTRY_TAR}" - podman load -i "${REGISTRY_TAR}" - -else - echo "Cache miss → pulling and saving registry image" - - podman pull "${REGISTRY_IMAGE}" - podman save -o "${REGISTRY_TAR}" "${REGISTRY_IMAGE}" -fi - -mkdir -p "${ARCHIVE_DIR}" -rm -rf "${REGISTRY_DATA_DIR}" -mkdir -p "${REGISTRY_DATA_DIR}" - -echo "============================================================" -echo "Preparing Kubernetes image cache" -echo " KUBE_VERSION = ${KUBE_VERSION}" -echo " ARCH = ${ARCH}" -echo " ARCHIVE_DIR = ${ARCHIVE_DIR}" -echo " REGISTRY_DATA_DIR = ${REGISTRY_DATA_DIR}" -echo "============================================================" - -# Start a temporary local registry backed by REGISTRY_DATA_DIR. -# We use host network here to avoid messing with nested networking. -podman rm -f temp-registry >/dev/null 2>&1 || true - -podman run -d \ - --name temp-registry \ - --network host \ - --cgroups=disabled \ - -v "${REGISTRY_DATA_DIR}:/var/lib/registry" \ - docker.io/library/registry:2 +# Build-host temporary runtime state for containers/storage. +TMPDIR="$(mktemp -d)" +RUNROOT="${TMPDIR}/runroot" +STORAGE_CONF="${TMPDIR}/storage.conf" cleanup() { - podman rm -f temp-registry >/dev/null 2>&1 || true + rm -rf "${TMPDIR}" } trap cleanup EXIT -# Wait for registry to answer. -for _ in $(seq 1 30); do - if curl -fsS "http://127.0.0.1:${REGISTRY_PORT}/v2/" >/dev/null; then - break - fi - sleep 1 -done +mkdir -p "${ARCHIVE_DIR}" +mkdir -p "${TARGET_GRAPHROOT}" +mkdir -p "${RUNROOT}" -if ! curl -fsS "http://127.0.0.1:${REGISTRY_PORT}/v2/" >/dev/null; then - echo "Temporary registry did not start" +echo "============================================================" +echo "Preparing Kubernetes CRI-O image store" +echo " KUBE_VERSION = ${KUBE_VERSION}" +echo " ARCH = ${ARCH}" +echo " ARCHIVE_DIR = ${ARCHIVE_DIR}" +echo " TARGET_GRAPHROOT = ${TARGET_GRAPHROOT}" +echo " STORAGE_DRIVER = ${STORAGE_DRIVER}" +echo "============================================================" + +# Build a temporary containers/storage config that writes directly into +# the target rootfs image store. +if [ "${STORAGE_DRIVER}" = "overlay" ]; then + cat > "${STORAGE_CONF}" < "${STORAGE_CONF}" </dev/null 2>&1; then - echo "Registry hit: 127.0.0.1:${REGISTRY_PORT}/${ref}" + # If already present in the target containers/storage, skip. + if skopeo inspect "containers-storage:${img}" >/dev/null 2>&1; then + echo "Store hit: ${img}" continue fi - echo "Seeding registry: $ref" + echo "Seeding CRI-O store: ${img}" skopeo copy \ - --dest-tls-verify=false \ - "oci-archive:$archive" \ - "docker://127.0.0.1:${REGISTRY_PORT}/${ref}" -done < <(qemu-aarch64-static "$ROOTFS/usr/local/bin/kubeadm" config images list --kubernetes-version "${KUBE_VERSION}") + --override-os "${OS}" \ + --override-arch "${ARCH}" \ + "oci-archive:${archive}" \ + "containers-storage:${img}" +done echo echo "Done." -echo "Archives: ${ARCHIVE_DIR}" -echo "Registry data: ${REGISTRY_DATA_DIR}" +echo "Archives: ${ARCHIVE_DIR}" +echo "CRI-O storage: ${TARGET_GRAPHROOT}" \ No newline at end of file diff --git a/alpine/rootfs-extra/opt/scripts/load-images.sh b/alpine/rootfs-extra/opt/scripts/load-images.sh deleted file mode 100755 index 8700097..0000000 --- a/alpine/rootfs-extra/opt/scripts/load-images.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh -set -eu - -KUBE_VERSION="${KUBE_VERSION:-v1.35.3}" -REGISTRY_ADDR="${REGISTRY_ADDR:-127.0.0.1:5000}" - -mkdir -p /opt/registry -cat >/opt/registry/config.yml </opt/crictl.yaml <<'EOF' -runtime-endpoint: unix:///var/run/crio/crio.sock -image-endpoint: unix:///var/run/crio/crio.sock -timeout: 10 -debug: false -EOF - -registry serve /opt/registry/config.yml >/var/log/registry.log 2>&1 & -REG_PID=$! - -cleanup() { - kill "$REG_PID" 2>/dev/null || true -} -trap cleanup EXIT INT TERM - -for _ in $(seq 1 30); do - if curl -fsS "http://${REGISTRY_ADDR}/v2/_catalog" >/dev/null; then - break - fi - sleep 1 -done - -curl -fsS "http://${REGISTRY_ADDR}/v2/_catalog" >/dev/null - -for img in $(kubeadm config images list --kubernetes-version "${KUBE_VERSION}"); do - name="${img#registry.k8s.io/}" - echo "Importing ${img} from ${REGISTRY_ADDR}/${name}" - skopeo copy --src-tls-verify=false \ - "docker://${REGISTRY_ADDR}/${name}" \ - "containers-storage:${img}" -done - -echo "Imported images now visible to CRI-O:" -crictl images - -kill "$REG_PID" 2>/dev/null || true -wait "$REG_PID" 2>/dev/null || true -trap - EXIT INT TERM diff --git a/alpine/rootfs-extra/opt/scripts/test-crio.sh b/alpine/rootfs-extra/opt/scripts/test-crio.sh new file mode 100755 index 0000000..eb11fec --- /dev/null +++ b/alpine/rootfs-extra/opt/scripts/test-crio.sh @@ -0,0 +1,65 @@ +#!/bin/bash +set -euo pipefail + +RUNTIME_ENDPOINT="${RUNTIME_ENDPOINT:-unix:///var/run/crio/crio.sock}" + +# 1. Get pause image +PAUSE_IMAGE="$(kubeadm config images list | grep pause)" + +echo "Using pause image: $PAUSE_IMAGE" + +# 2. Create pod sandbox config +cat > pod.json < container.json <