diff --git a/.github/workflows/offline-package-k3s-installer.yaml b/.github/workflows/offline-package-k3s-installer.yaml index 7f7f93f..e1f5227 100644 --- a/.github/workflows/offline-package-k3s-installer.yaml +++ b/.github/workflows/offline-package-k3s-installer.yaml @@ -76,7 +76,7 @@ jobs: needs: build-k3s-installer strategy: matrix: - arch: [amd64] + arch: [amd64, arm64] runs-on: ubuntu-latest steps: @@ -91,7 +91,40 @@ jobs: cd test-dir tar -xzvf offline-package-k3s-installer-${{ matrix.arch }}.tar.gz + - name: Install jq + run: | + sudo apt-get update + sudo apt-get install -y jq + + - name: Verify k3s binary arch + run: | + set -euo pipefail + BIN="test-dir/k3s-offline-package/bin/k3s-${{ matrix.arch }}" + file "$BIN" + if [ "${{ matrix.arch }}" = "amd64" ]; then + file "$BIN" | grep -q 'x86-64' + else + file "$BIN" | grep -q 'aarch64' + fi + + - name: Verify image platforms + run: | + set -euo pipefail + TAR="test-dir/k3s-offline-package/images/k3s-airgap-images-${{ matrix.arch }}.tar" + tmp=$(mktemp -d) + tar -xf "$TAR" -C "$tmp" manifest.json + configs=$(jq -r '.[].Config' "$tmp/manifest.json") + for cfg in $configs; do + tar -xf "$TAR" -C "$tmp" "$cfg" + arch=$(jq -r '.architecture' "$tmp/$cfg") + if [ "$arch" != "${{ matrix.arch }}" ]; then + echo "unexpected arch $arch in $cfg" >&2 + exit 1 + fi + done + - name: Setup K3s and Test + if: matrix.arch == 'amd64' run: | cd test-dir/k3s-offline-package bash install-server.sh diff --git a/scripts/make_k3s_offline_package.sh b/scripts/make_k3s_offline_package.sh index 35e1222..97d578d 100644 --- a/scripts/make_k3s_offline_package.sh +++ b/scripts/make_k3s_offline_package.sh @@ -59,14 +59,14 @@ pull_and_save_images() { log "拉取核心镜像(runtime=$rt)…" case "$rt" in docker) - for i in "${imgs[@]}"; do docker pull "$i"; done + for i in "${imgs[@]}"; do docker pull --platform=linux/${ARCH} "$i"; done log "保存镜像 → $out_tar" docker save -o "$out_tar" "${imgs[@]}" ;; nerdctl-default) - for i in "${imgs[@]}"; do sudo nerdctl --address /run/containerd/containerd.sock pull "$i"; done + for i in "${imgs[@]}"; do sudo nerdctl --address /run/containerd/containerd.sock --platform=linux/${ARCH} pull "$i"; done log "保存镜像 → $out_tar" - sudo nerdctl --address /run/containerd/containerd.sock save -o "$out_tar" "${imgs[@]}" + sudo nerdctl --address /run/containerd/containerd.sock --platform=linux/${ARCH} save -o "$out_tar" "${imgs[@]}" ;; esac [[ -s "$out_tar" ]] || err "未生成镜像包:$out_tar" @@ -200,6 +200,16 @@ case "$ARCH" in x86_64|amd64) ARCH=amd64;; aarch64|arm64) ARCH=arm64;; *) echo " BIN_DIR="./bin" install_bin(){ sudo cp "$1" "$2"; sudo chmod +x "$2"; echo " ↳ $2"; } +check_images(){ + echo "[INFO] 验证已加载镜像架构" + local out + out=$(sudo nerdctl --namespace k8s.io --address /run/k3s/containerd/containerd.sock images -a --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.Platform}}') + echo "$out" + if echo "$out" | awk '{print $3}' | grep -v "linux/${ARCH}" >/dev/null; then + echo "[ERROR] 发现非 ${ARCH} 架构镜像" >&2 + exit 1 + fi +} echo "[INFO] 安装 CLI → /usr/local/bin" install_bin "${BIN_DIR}/k3s-${ARCH}" /usr/local/bin/k3s @@ -220,6 +230,8 @@ mkdir -p ~/.kube && cp -f /etc/rancher/k3s/k3s.yaml ~/.kube/config || true kubectl apply -f addons/node-exporter.yaml || true kubectl apply -f addons/kube-state-metrics.yaml || true +check_images + echo "[SUCCESS] 离线 K3s 安装完成 ✅" SH chmod +x "${BASE_DIR}/install-server.sh" @@ -235,6 +247,16 @@ case "$ARCH" in x86_64|amd64) ARCH=amd64;; aarch64|arm64) ARCH=arm64;; *) echo " BIN_DIR="./bin" install_bin(){ sudo cp "$1" "$2"; sudo chmod +x "$2"; echo " ↳ $2"; } +check_images(){ + echo "[INFO] 验证已加载镜像架构" + local out + out=$(sudo nerdctl --namespace k8s.io --address /run/k3s/containerd/containerd.sock images -a --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.Platform}}') + echo "$out" + if echo "$out" | awk '{print $3}' | grep -v "linux/${ARCH}" >/dev/null; then + echo "[ERROR] 发现非 ${ARCH} 架构镜像" >&2 + exit 1 + fi +} echo "[INFO] 安装 CLI → /usr/local/bin" install_bin "${BIN_DIR}/k3s-${ARCH}" /usr/local/bin/k3s @@ -246,6 +268,8 @@ INSTALL_K3S_SKIP_DOWNLOAD=true INSTALL_K3S_EXEC="agent" bash install/k3s-officia echo "[INFO] 加载 airgap 镜像" sudo nerdctl --namespace k8s.io --address /run/k3s/containerd/containerd.sock load -i "images/k3s-airgap-images-${ARCH}.tar" || true +check_images + echo "[SUCCESS] Agent 节点离线安装完成 ✅" SH chmod +x "${BASE_DIR}/install-agent.sh" @@ -285,7 +309,11 @@ rm -rf "${BASE_DIR}" mkdir -p "${BASE_DIR}/"{bin,images,cni-plugins,addons,registry/docker.io,registry/ghcr.io,install} # 核心二进制 -download "${K3S_URL_BASE}/k3s" "${BASE_DIR}/bin/k3s-${ARCH}" +K3S_BIN="k3s" +if [[ "${ARCH}" != "amd64" ]]; then + K3S_BIN="k3s-${ARCH}" +fi +download "${K3S_URL_BASE}/${K3S_BIN}" "${BASE_DIR}/bin/k3s-${ARCH}" chmod +x "${BASE_DIR}/bin/k3s-${ARCH}" download "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" "${BASE_DIR}/bin/kubectl-${ARCH}"