Merge branch 'main' into codex/fix-offline-package-k3s-installer-arm64.tar.gz-k7ywqv
Signed-off-by: shenlan <manbuzhe2009@qq.com>
This commit is contained in:
commit
38d3ebcfed
@ -1,23 +1,23 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# gitops/scripts/ingress-installer.sh
|
# scripts/ingress-installer.sh
|
||||||
# 目标:最小化参数/分支,专注“一键离线安装”
|
# 目标:一键“离线安装” NGINX Ingress,兼容 K3s 1.29~1.33(containerd)
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Config & Defaults(仅支持环境变量覆盖)
|
# Config & Defaults(仅支持环境变量覆盖)
|
||||||
# ======================
|
# ======================
|
||||||
: "${NGINX_IC_IMAGE:=nginx/nginx-ingress:2.4.0}"
|
: "${NGINX_IC_IMAGE:=nginx/nginx-ingress:5.1.1}"
|
||||||
: "${CERT_IMG:=registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407}"
|
: "${CERT_IMG:=registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407}"
|
||||||
|
|
||||||
# 打包阶段写入的 OCI layout 内部引用名(如果你改了打包 ref.name,这里相应改)
|
# 打包阶段写入的 OCI layout 内部引用名(如果你改了打包 ref.name,这里相应改)
|
||||||
: "${OCI_NGINX_REF:=nginx-ingress-2.4.0}"
|
: "${OCI_NGINX_REF:=nginx-ingress-5.1.1}"
|
||||||
: "${OCI_CERT_REF:=kube-webhook-certgen}"
|
: "${OCI_CERT_REF:=kube-webhook-certgen}"
|
||||||
|
|
||||||
# 目录布局固定:charts、images、脚本位于离线包根目录
|
# 目录布局固定:charts、images、脚本位于离线包根目录
|
||||||
: "${CHART_DIR:=./charts/nginx-ingress}"
|
: "${CHART_DIR:=./charts/nginx-ingress}"
|
||||||
: "${NAMESPACE:=ingress}"
|
: "${NAMESPACE:=ingress}"
|
||||||
: "${OCI_ARCHIVE:=images/oci-archive.tar}" # 优先使用
|
: "${OCI_ARCHIVE:=images/oci-archive.tar}" # 优先使用(oci-archive)
|
||||||
: "${DOCKER_IMG_TAR:=images/nginx-ingress.tar}" # 回退(docker save)
|
: "${DOCKER_IMG_TAR:=images/nginx-ingress.tar}" # 回退(docker-archive)
|
||||||
: "${DOCKER_CERT_TAR:=images/kube-webhook-certgen.tar}"
|
: "${DOCKER_CERT_TAR:=images/kube-webhook-certgen.tar}"
|
||||||
: "${NERDCTL_TAR:=nerdctl.tar.gz}"
|
: "${NERDCTL_TAR:=nerdctl.tar.gz}"
|
||||||
|
|
||||||
@ -33,6 +33,57 @@ ok() { echo "✅ $*"; }
|
|||||||
warn() { echo "⚠️ $*"; }
|
warn() { echo "⚠️ $*"; }
|
||||||
have() { command -v "$1" &>/dev/null; }
|
have() { command -v "$1" &>/dev/null; }
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# Runtime Detection(K3s / containerd / docker / nerdctl)
|
||||||
|
# ======================
|
||||||
|
NERDCTL_BIN=""
|
||||||
|
detect_nerdctl() {
|
||||||
|
# 优先使用离线包内置路径(install_nerdctl 会解到 /usr/local/bin/nerdctl)
|
||||||
|
if [ -x /usr/local/bin/nerdctl ]; then
|
||||||
|
NERDCTL_BIN="/usr/local/bin/nerdctl"
|
||||||
|
elif have nerdctl; then
|
||||||
|
NERDCTL_BIN="$(command -v nerdctl)"
|
||||||
|
else
|
||||||
|
NERDCTL_BIN=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
have_nerdctl() { [ -n "${NERDCTL_BIN}" ]; }
|
||||||
|
|
||||||
|
detect_containerd() {
|
||||||
|
# 优先使用 K3s 的 containerd
|
||||||
|
if [ -S /run/k3s/containerd/containerd.sock ]; then
|
||||||
|
CTR_SOCK="/run/k3s/containerd/containerd.sock"
|
||||||
|
CTR_NS="k8s.io"
|
||||||
|
if have k3s; then
|
||||||
|
CTR_BIN="k3s ctr" # 避免系统 ctr 指向其他 containerd
|
||||||
|
else
|
||||||
|
CTR_BIN="ctr --address ${CTR_SOCK}"
|
||||||
|
fi
|
||||||
|
NERDCTL_ADDR_OPT=(--address "${CTR_SOCK}" --namespace "${CTR_NS}")
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 其次使用系统 containerd
|
||||||
|
if [ -S /run/containerd/containerd.sock ]; then
|
||||||
|
CTR_SOCK="/run/containerd/containerd.sock"
|
||||||
|
CTR_NS="k8s.io"
|
||||||
|
CTR_BIN="ctr --address ${CTR_SOCK}"
|
||||||
|
NERDCTL_ADDR_OPT=(--address "${CTR_SOCK}" --namespace "${CTR_NS}")
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
CTR_SOCK=""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 统一的 ctr/nerdctl 执行器
|
||||||
|
ctr_exec() {
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
${CTR_BIN} -n "${CTR_NS}" "$@"
|
||||||
|
}
|
||||||
|
nerdctl_exec() {
|
||||||
|
"${NERDCTL_BIN}" "${NERDCTL_ADDR_OPT[@]}" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Nerdctl Install (wrapper)
|
# Nerdctl Install (wrapper)
|
||||||
# ======================
|
# ======================
|
||||||
@ -42,16 +93,26 @@ install_nerdctl() {
|
|||||||
$SUDO tar xzf "${NERDCTL_TAR}" -C /usr/local/bin/
|
$SUDO tar xzf "${NERDCTL_TAR}" -C /usr/local/bin/
|
||||||
$SUDO chmod +x /usr/local/bin/nerdctl || true
|
$SUDO chmod +x /usr/local/bin/nerdctl || true
|
||||||
fi
|
fi
|
||||||
|
detect_nerdctl
|
||||||
|
if have_nerdctl; then
|
||||||
|
log "🧰 nerdctl 就绪:${NERDCTL_BIN}"
|
||||||
|
else
|
||||||
|
warn "未检测到 nerdctl,将仅依赖 ctr/docker 执行导入。"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Import images(优先 OCI,其次 docker save tar)
|
# Import images(优先 OCI,其次 docker-archive)
|
||||||
# ======================
|
# ======================
|
||||||
import_images_from_oci() {
|
import_images_from_oci() {
|
||||||
# 首选:OCI 归档
|
detect_containerd
|
||||||
|
log "🔌 containerd socket: ${CTR_SOCK:-<not found>}"
|
||||||
|
|
||||||
|
# 首选:OCI 归档(oci-archive)—— 标准且最稳
|
||||||
if [ -f "${OCI_ARCHIVE}" ]; then
|
if [ -f "${OCI_ARCHIVE}" ]; then
|
||||||
log "📦 从 OCI 归档导入镜像:${OCI_ARCHIVE}"
|
log "📦 从 OCI 归档导入镜像:${OCI_ARCHIVE}"
|
||||||
# A) Docker 环境(需要 skopeo)
|
|
||||||
|
# A) Docker 守护进程(需要 skopeo)—— 可选路径
|
||||||
if have docker && docker info &>/dev/null; then
|
if have docker && docker info &>/dev/null; then
|
||||||
if have skopeo; then
|
if have skopeo; then
|
||||||
skopeo --insecure-policy copy --all "oci-archive:${OCI_ARCHIVE}:${OCI_NGINX_REF}" "docker-daemon:${NGINX_IC_IMAGE}"
|
skopeo --insecure-policy copy --all "oci-archive:${OCI_ARCHIVE}:${OCI_NGINX_REF}" "docker-daemon:${NGINX_IC_IMAGE}"
|
||||||
@ -59,46 +120,68 @@ import_images_from_oci() {
|
|||||||
ok "OCI → docker-daemon 导入完成"
|
ok "OCI → docker-daemon 导入完成"
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
warn "docker 环境未安装 skopeo,改用 docker-archive 回退(需 images/*.tar)"
|
warn "docker 环境未安装 skopeo,改用 containerd 路径。"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# B) containerd 环境(K3s 或系统 containerd)
|
|
||||||
if [ -S /run/k3s/containerd/containerd.sock ] || [ -S /run/containerd/containerd.sock ]; then
|
# B) containerd 环境(K3s 或系统 containerd)—— 主路径
|
||||||
local ns="k8s.io"
|
if [ -n "${CTR_SOCK}" ]; then
|
||||||
$SUDO ctr -n "${ns}" images import --all-platforms "${OCI_ARCHIVE}"
|
ctr_exec images import --all-platforms "${OCI_ARCHIVE}"
|
||||||
$SUDO ctr -n "${ns}" images tag "${OCI_NGINX_REF}" "${NGINX_IC_IMAGE}" || true
|
# 补打期望 tag(让 ctr/nerdctl/k8s 三方都一致)
|
||||||
$SUDO ctr -n "${ns}" images tag "${OCI_CERT_REF}" "${CERT_IMG}" || true
|
ctr_exec images tag "${OCI_NGINX_REF}" "${NGINX_IC_IMAGE}" || true
|
||||||
|
ctr_exec images tag "${OCI_CERT_REF}" "${CERT_IMG}" || true
|
||||||
|
|
||||||
|
# 若 nerdctl 可用,再用 nerdctl 做一次 tag(有助于命令行一致性)
|
||||||
|
if have_nerdctl; then
|
||||||
|
nerdctl_exec tag "${OCI_NGINX_REF}" "${NGINX_IC_IMAGE}" || true
|
||||||
|
nerdctl_exec tag "${OCI_CERT_REF}" "${CERT_IMG}" || true
|
||||||
|
fi
|
||||||
|
|
||||||
ok "OCI → containerd 导入完成"
|
ok "OCI → containerd 导入完成"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
warn "未检测到 docker/skopo 或 containerd 可直接用 OCI 导入,尝试 docker-archive 回退。"
|
|
||||||
|
warn "未检测到可用于 OCI 导入的 containerd,将尝试 docker-archive 回退。"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 回退:docker save 的 tar 包
|
# 回退:docker save 的 tar 包(docker-archive)
|
||||||
if [ -f "${DOCKER_IMG_TAR}" ] && [ -f "${DOCKER_CERT_TAR}" ]; then
|
if [ -f "${DOCKER_IMG_TAR}" ] && [ -f "${DOCKER_CERT_TAR}" ]; then
|
||||||
log "📦 从 docker-archive tar 回退导入 images/*.tar"
|
log "📦 从 docker-archive tar 回退导入 images/*.tar"
|
||||||
|
|
||||||
|
# 优先:nerdctl(离线包自带/系统均可)
|
||||||
|
if have_nerdctl; then
|
||||||
|
if [ -n "${CTR_SOCK}" ]; then
|
||||||
|
nerdctl_exec load -i "${DOCKER_IMG_TAR}"
|
||||||
|
nerdctl_exec load -i "${DOCKER_CERT_TAR}"
|
||||||
|
else
|
||||||
|
# 极少见:未探测到 socket,尝试 nerdctl 默认
|
||||||
|
"${NERDCTL_BIN}" load -i "${DOCKER_IMG_TAR}"
|
||||||
|
"${NERDCTL_BIN}" load -i "${DOCKER_CERT_TAR}"
|
||||||
|
fi
|
||||||
|
ok "nerdctl load 完成"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 其次:docker 守护进程
|
||||||
if have docker && docker info &>/dev/null; then
|
if have docker && docker info &>/dev/null; then
|
||||||
docker load -i "${DOCKER_IMG_TAR}"
|
docker load -i "${DOCKER_IMG_TAR}"
|
||||||
docker load -i "${DOCKER_CERT_TAR}"
|
docker load -i "${DOCKER_CERT_TAR}"
|
||||||
ok "docker load 完成"
|
ok "docker load 完成"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
if have nerdctl; then
|
|
||||||
nerdctl load -i "${DOCKER_IMG_TAR}"
|
# 兜底:ctr(可导入 docker-archive,但不如 nerdctl 稳妥)
|
||||||
nerdctl load -i "${DOCKER_CERT_TAR}"
|
if [ -n "${CTR_SOCK}" ]; then
|
||||||
ok "nerdctl load 完成"
|
ctr_exec images import --all-platforms "${DOCKER_IMG_TAR}"
|
||||||
return
|
ctr_exec images import --all-platforms "${DOCKER_CERT_TAR}"
|
||||||
fi
|
|
||||||
if [ -S /run/k3s/containerd/containerd.sock ] || [ -S /run/containerd/containerd.sock ]; then
|
|
||||||
$SUDO ctr -n k8s.io images import --all-platforms "${DOCKER_IMG_TAR}"
|
|
||||||
$SUDO ctr -n k8s.io images import --all-platforms "${DOCKER_CERT_TAR}"
|
|
||||||
ok "ctr import 完成"
|
ok "ctr import 完成"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
die "找不到可用容器运行时导入 images/*.tar"
|
die "找不到可用容器运行时导入 images/*.tar"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
die "未发现可用的镜像来源(缺少 ${OCI_ARCHIVE} 或 ${DOCKER_IMG_TAR}/${DOCKER_CERT_TAR)})"
|
die "未发现可用的镜像来源(缺少 ${OCI_ARCHIVE} 或 ${DOCKER_IMG_TAR}/${DOCKER_CERT_TAR})"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
@ -116,29 +199,29 @@ generate_values() {
|
|||||||
tag="${NGINX_IC_IMAGE##*:}"
|
tag="${NGINX_IC_IMAGE##*:}"
|
||||||
|
|
||||||
cat > values.yaml <<EOF
|
cat > values.yaml <<EOF
|
||||||
controller:
|
controller:
|
||||||
ingressClass:
|
ingressClass:
|
||||||
name: nginx
|
name: nginx
|
||||||
create: true
|
create: true
|
||||||
setAsDefaultIngress: false
|
setAsDefaultIngress: false
|
||||||
replicaCount: 2
|
replicaCount: 2
|
||||||
image:
|
image:
|
||||||
repository: ${repo}
|
repository: ${repo}
|
||||||
tag: "${tag}"
|
tag: "${tag}"
|
||||||
service:
|
service:
|
||||||
enabled: true
|
enabled: true
|
||||||
type: NodePort
|
type: NodePort
|
||||||
externalIPs:
|
externalIPs:
|
||||||
- ${INGRESS_IP}
|
- ${INGRESS_IP}
|
||||||
nodePorts:
|
nodePorts:
|
||||||
http: 80
|
http: 80
|
||||||
https: 443
|
https: 443
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [[ -n "${NODE_LABEL}" ]]; then
|
if [[ -n "${NODE_LABEL}" ]]; then
|
||||||
cat >> values.yaml <<EOF
|
cat >> values.yaml <<EOF
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
${NODE_LABEL%%=*}: "${NODE_LABEL#*=}"
|
${NODE_LABEL%%=*}: "${NODE_LABEL#*=}"
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,6 +211,27 @@ check_images(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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"
|
echo "[INFO] 安装 CLI → /usr/local/bin"
|
||||||
install_bin "${BIN_DIR}/k3s-${ARCH}" /usr/local/bin/k3s
|
install_bin "${BIN_DIR}/k3s-${ARCH}" /usr/local/bin/k3s
|
||||||
install_bin "${BIN_DIR}/helm-${ARCH}" /usr/local/bin/helm
|
install_bin "${BIN_DIR}/helm-${ARCH}" /usr/local/bin/helm
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user