ubunbu 26.04,用bash脚本自动下载kubeadm的deb离线安装包 + containerd.io的deb离线安装包+ 离线镜像包
准备一台没有安装过containerd、并且没有安装过kubeadm、kubelet、kubectl的ubuntu 26.04的是脑。
一,离线资源清单
1.ubuntu26.04、 kubernetes、containerd依赖包清单
| 资源名称 | deb名称 | 示例 |
| utuntu20.04系统依赖 |
socat conntrack iproute2 iptables net-tools iputils-ping ethtool ebtables apt-transport-https ca-certificates gnupg lsb-release |
26.04 |
| containerd |
containerd.io_${version}_amd64.deb cri-tools_${version}_amd64.deb |
containerd.io_2.3.3-1~ubuntu.26.04~resolute_amd64.deb cri-tools_1.32.0-1.1_amd64.deb |
| kubernetes |
kubeadm_${version}_amd64.deb kubectl_${version}_amd64.deb kubelet_${version}_amd64.deb kubernetes-cni_${version}_amd64.deb |
kubeadm_1.32.13-1.1_amd64.deb kubectl_1.32.13-1.1_amd64.deb kubelet_1.32.13-1.1_amd64.deb kubernetes-cni_1.6.0-1.1_amd64.deb |
2. kubeadm、calico、ingress需要的镜像清单
| 资源名称 | 镜像 | 示例 |
| kubeadm镜像 |
registry.k8s.io/kube-apiserver:${version} registry.k8s.io/kube-controller-manager:${version} registry.k8s.io/kube-scheduler:${version} registry.k8s.io/kube-proxy:${version} registry.k8s.io/etcd:${etcd_version} registry.k8s.io/coredns/coredns:${coredns_version} registry.k8s.io/pause:${pause_version} |
registry.k8s.io/kube-apiserver:v1.36.3 registry.k8s.io/kube-controller-manager:v1.36.3 registry.k8s.io/kube-scheduler:v1.36.3 registry.k8s.io/kube-proxy:v1.36.3 registry.k8s.io/etcd:3.5.18-0 registry.k8s.io/coredns/coredns:v1.12.0 registry.k8s.io/pause:3.10.1 |
| calico镜像 |
quay.io/calico/cni:${version} quay.io/calico/node:${version} quay.io/calico/kube-controllers:${version} |
quay.io/calico/cni:v3.31.6 quay.io/calico/node:v3.31.6 quay.io/calico/kube-controllers:v3.31.6 |
| ingress镜像 |
registry.k8s.io/ingress-nginx/controller:${version} registry.k8s.io/ingress-nginx/kube-webhook-certgen:${certgen_version} |
registry.k8s.io/ingress-nginx/controller:v1.15.1 registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9 |
3. yaml部署文件清单
| yaml名称 | yaml文件名 | 示例 |
| calico部署yaml | calico-${calico_ver}.yaml | calico-v1.32.1.yaml |
| ingress部署yaml | ingress-nginx-${ingress_ver}.yaml | ingress-nginx-v1.15.1.yaml |
4.calico版与本k8s版本对应规则
规则:Calico Open Source 一个大版本支持连续 3 个 K8s minor 版本;patch 版本不影响兼容性。
Calico 开源版本与 K8S 官方兼容矩阵:
| Kubernetes 版本 | 生产推荐 Calico 版本 | calico.yaml 下载地址模板 |
| v1.32.x | v3.31.6 | https://raw.githubusercontent.com/projectcalico/calico/v3.31.6/manifests/calico.yaml |
| v1.33.x | v3.31.6 | https://raw.githubusercontent.com/projectcalico/calico/v3.31.6/manifests/calico.yaml |
| v1.34.x | v3.32.1 | https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml |
| v1.35.x | v3.32.1 | https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml |
| v1.36.x | v3.32.1 | https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml |
官方文档入口:https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements
5. ingress与k8s版本对应规则
| Kubernetes 版本 | 生产推荐ingress-nginx-controller版本 | ingress-deploy.yaml 下载地址模板 |
| v1.32.x | v1.14.5 | https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.5/deploy/static/provider/cloud/deploy.yaml |
| v1.33.x | v1.14.5 | https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.5/deploy/static/provider/cloud/deploy.yaml |
| v1.34.x | v1.15.1 | https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/cloud/deploy.yaml |
| v1.35.x | v1.15.1 | https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/cloud/deploy.yaml |
| v1.36.x | 需要使用F5 NGINX Ingress Controller v5.54 社区版ingress-nginx已停止维护 |
https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v5.5.4/deploy/crds.yaml https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v5.5.4/deploy/nginx-ingress.yaml |
二,安装必备工具
1. 安装系统工具
apt update && apt install -y ca-certificates curl wget gnupg lsb-release
2. 安装nerdctl
下载nerdctl完整包:nerdctl-full(推荐离线,一步到位,自带 buildkit)
完整版下载: https://github.com/containerd/nerdctl/releases/download/v2.3.3/nerdctl-full-2.3.3-linux-amd64.tar.gz
精简版下载:https://github.com/containerd/nerdctl/releases/download/v2.3.4/nerdctl-2.3.4-linux-amd64.tar.gz
下载后的离线文件清单(完整版本或精简版下载其一即可)
nerdctl-full-2.3.3-linux-amd64.tar.gz
nerdctl-2.3.4-linux-amd64.tar.gz
精简版部署
curl https://github.com/containerd/nerdctl/releases/download/v2.3.4/nerdctl-2.3.4-linux-amd64.tar.gz tar -zxvf nerdctl-2.3.4-linux-amd64.tar.gz mv nerdctl /usr/local/bin/ chmod +x /usr/local/bin/nerdctl # 同样配置默认命名空间 mkdir -p /etc/nerdctl cat > /etc/nerdctl/nerdctl.toml <<EOF namespace = "k8s.io" address = "/run/containerd/containerd.sock" cgroup_manager = "systemd" EOF
三,下载deb离线包
规划下载的离线包目录结构:
/data/k8s/k8s-v1.32.13 ├── calico-images-v3.31.6.list ├── calico-images-v3.31.6.tar.gz ├── calico-v3.31.6.yaml ├── ingress-nginx-images-v1.14.5.list ├── ingress-nginx-images-v1.14.5.tar.gz ├── ingress-nginx-v1.14.5.yaml ├── k8s-debs │ ├── containerd.io_2.3.3-1~ubuntu.26.04~resolute_amd64.deb │ ├── cri-tools_1.32.0-1.1_amd64.deb │ ├── kubeadm_1.32.13-1.1_amd64.deb │ ├── kubectl_1.32.13-1.1_amd64.deb │ ├── kubelet_1.32.13-1.1_amd64.deb │ └── kubernetes-cni_1.6.0-1.1_amd64.deb ├── k8s-images-v1.32.13.list ├── k8s-images-v1.32.13.tar.gz └── k8s-offline.conf
1. 全局变量配置文件
mkdir -p /data/k8s/k8s-v1.32.13
vi /data/k8s/k8s-v1.32.13/k8s-offline.conf
k8s-offline.conf 文件内容:
# K8s离线资源下载统一配置 # 提供k8s & containerd数据源、deb包下载、镜像拉取脚本共用版本与路径变量 base_dir="/data/k8s" # k8s_apt_branch:apt源分支 1.32 / 1.33 / 1.34 / 1.35 / 1.36 k8s_apt_branch="v1.32" k8s_pkg_ver="1.32.13-1.1" # containerd.io deb安装包完整版本号 containerd_io_pkg_ver="2.3.3-1~ubuntu.26.04~resolute" # k8s版本 k8s_ver="v1.32.13" # kubeadm二进制文件目录 kubeadm_bin_dir="/data/k8s/kubeadm-bin" calico_ver="v3.31.6" ingress_ver="v1.14.5"
2. 下载ubuntu 26.04系统依赖(注意加了圆括号新开shell,exit不会退出终端)
进到 k8s-offline.conf所在的目录执行:
#!/bin/bash set -euo pipefail ( # 配置文件:当前版本目录内的离线构建配置 conf_file="./k8s-offline.conf" # 1. 判断配置文件 if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" # 变量校验 check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } check_var base_dir # ===================== # 定义本地变量,从全局配置读取值 # ===================== local_base_dir="${base_dir}" local_sysdep_pack_dir="ubuntu-26.04-sys-debs" local_sysdep_tar_filename="${local_sysdep_pack_dir}.tar.gz" # 清理apt缓存旧包 apt clean rm -f /var/cache/apt/archives/*.deb rm -rf "${local_base_dir}/${local_sysdep_pack_dir}" mkdir -p "${local_base_dir}/${local_sysdep_pack_dir}" cd "${local_base_dir}/${local_sysdep_pack_dir}" apt-get download \ socat \ conntrack \ iproute2 \ iptables \ net-tools \ iputils-ping \ ethtool \ ebtables \ apt-transport-https \ ca-certificates \ gnupg \ lsb-release rm -f "${local_base_dir}/${local_sysdep_tar_filename}" cd "${local_base_dir}" tar -zcvf "${local_sysdep_tar_filename}" "${local_sysdep_pack_dir}" echo -e "\n系统依赖包下载完成:${local_base_dir}/${local_sysdep_tar_filename}" ls -lh "${local_base_dir}/${local_sysdep_pack_dir}" )
3.配置仓库
1) 配置新版本containerd仓库源
#!/bin/bash # 探测信息赋值本地副本变量 local_arch=$(dpkg --print-architecture) local_ubuntu_codename=$(lsb_release -cs) # 清理旧docker源 rm -f /etc/apt/sources.list.d/docker.list rm -f /etc/apt/trusted.gpg.d/docker*.gpg # 阿里云docker-ce公钥 curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg # 添加阿里云docker-ce源(包含 containerd.io) echo "deb [arch=${local_arch} signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu ${local_ubuntu_codename} stable" | tee /etc/apt/sources.list.d/docker.list apt update echo -e "\n=== 当前架构:${local_arch},系统代号:${local_ubuntu_codename} ===" echo -e "\n=== 查看当前源可用 containerd.io 版本 ===" apt-cache madison containerd.io
2) 配置k8s仓库源,需要哪个版本的k8s就配置哪个版本的仓库源
同一时间只能配置一个k8s版本,多个k8s版本需要先删除旧的k8s源,然后逐个配置
#!/bin/bash set -euo pipefail ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" # 校验依赖变量 check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } check_var k8s_apt_branch # ====================== # 定义本地变量,从全局配置读取值
# apt源分支 1.32 / 1.33 / 1.34 / 1.35 / 1.36
# ====================== local_k8s_apt_branch="${k8s_apt_branch}" # 后续全部使用 local_ 前缀本地变量 # 清理旧k8s源 rm -f /etc/apt/sources.list.d/kubernetes.list rm -f /etc/apt/trusted.gpg.d/kubernetes-*.gpg # 导入对应版本密钥 curl -fsSL "https://pkgs.k8s.io/core:/stable:/${local_k8s_apt_branch}/deb/Release.key" | gpg --dearmor -o "/etc/apt/trusted.gpg.d/kubernetes-v${local_k8s_apt_branch}.gpg" # 添加对应版本apt源 echo "deb [signed-by=/etc/apt/trusted.gpg.d/kubernetes-v${local_k8s_apt_branch}.gpg] https://pkgs.k8s.io/core:/stable:/${local_k8s_apt_branch}/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list # 更新缓存 apt update # 查看可用kubeadm版本 echo -e "\n========== 可用 kubeadm 版本列表 ==========" apt-cache madison kubeadm )
4. 下载离线deb包(containerd、kubeadm、kubelet、kubectl)
#!/bin/bash set -euo pipefail ( conf_file="./k8s-offline.conf" # 校验配置文件存在 if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" # 变量校验函数 check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } # 校验公共配置原始变量 check_var base_dir check_var k8s_pkg_ver check_var containerd_io_pkg_ver # ====================== # 脚本本地副本变量 # ====================== local_base_dir="${base_dir}" local_k8s_pkg_ver="${k8s_pkg_ver}" local_containerd_io_pkg_ver="${containerd_io_pkg_ver}" # 衍生变量,基于本地副本计算,目录带上v前缀 k8s-v1.32.13 local_k8s_short_ver=$(echo "${local_k8s_pkg_ver}" | cut -d'-' -f1) local_deb_dir="${local_base_dir}/k8s-v${local_k8s_short_ver}/k8s-debs" rm -rf "${local_deb_dir}" mkdir -p "${local_deb_dir}" cd "${local_deb_dir}" # 清理apt缓存旧包 apt clean rm -f /var/cache/apt/archives/*.deb # 下载核心deb包 apt-get download \ kubeadm=${local_k8s_pkg_ver} \ kubelet=${local_k8s_pkg_ver} \ kubectl=${local_k8s_pkg_ver} \ containerd.io=${local_containerd_io_pkg_ver} \ cri-tools \ kubernetes-cni echo -e "\ndeb包下载完成,目录:${local_deb_dir}" ls -lh "${local_deb_dir}" )
输出:
total 111M -rw-r--r-- 1 root root 22M Aug 13 20:51 containerd.io_2.3.3-1~ubuntu.26.04~resolute_amd64.deb -rw-r--r-- 1 root root 16M Dec 9 2024 cri-tools_1.32.0-1.1_amd64.deb -rw-r--r-- 1 root root 12M Feb 27 08:18 kubeadm_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 11M Feb 27 08:18 kubectl_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 15M Feb 27 08:18 kubelet_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 37M Dec 12 2024 kubernetes-cni_1.6.0-1.1_amd64.deb
四. 安装containerd 2.3(安装一次即可,高版本continerd向下兼容k8s各版本)
#!/bin/bash set -euo pipefail ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" # 变量校验 check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } check_var base_dir check_var k8s_pkg_ver # 本地变量副本 local_base_dir="${base_dir}" local_k8s_pkg_ver="${k8s_pkg_ver}" local_k8s_short_ver=$(echo "${local_k8s_pkg_ver}" | cut -d'-' -f1) local_deb_dir="${local_base_dir}/k8s-v${local_k8s_short_ver}/k8s-debs" # 判断deb目录是否存在 if [ ! -d "${local_deb_dir}" ];then echo "ERROR: deb包目录不存在:${local_deb_dir}" exit 1 fi echo "=====================================" echo "离线安装目录:${local_deb_dir}" echo "=====================================" cd "${local_deb_dir}" # 升级 containerd:先停止服务,防止进程占用二进制 echo -e "\n===== 停止 containerd.service =====" systemctl stop containerd || true # 【可选操作,正常升级不需要开启】 # 如需彻底卸载旧版本(出现冲突时手动启用) # apt remove -y containerd.io # apt purge -y containerd.io echo -e "\n===== 安装/升级 containerd.io =====" dpkg -i ./containerd.io_*.deb echo -e "\n===== 安装 cri-tools =====" dpkg -i ./cri-tools_*.deb echo -e "\n===== 安装 kubeadm kubelet kubectl kubernetes-cni =====" dpkg -i ./kube*.deb ./kubernetes-cni*.deb # 离线修复依赖 echo -e "\n===== 修复依赖 --no-download =====" apt-get install -y -f --no-download # 启动组件 echo -e "\n===== 启用并启动 kubelet =====" systemctl enable --now kubelet echo -e "\n===== 启动 containerd =====" systemctl enable --now containerd echo -e "\n===== 离线安装/升级完成 =====" containerd --version kubeadm version kubectl version --client )
配置 containerd(根据 pause版本修改)
#!/bin/bash # 根据K8s的pause镜像的版本修改 PAUSE_VERSION="3.10" #生成默认配置 containerd config default | tee /etc/containerd/config.toml # 修改cgroup驱动为systemd sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml # 正则替换pause版本,直接内嵌变量 sed -i "s#sandbox_image = \".*pause:[0-9.]*\"#sandbox_image = \"registry.k8s.io/pause:${PAUSE_VERSION}\"#g" /etc/containerd/config.toml # 重启containerd systemctl daemon-reload systemctl restart containerd systemctl enable --now containerd # systemctl status containerd # 校验连接文件 ls -l /run/containerd/containerd.sock
五,获取kubeadm需要的镜像
1. 下载kubeadm二进制,用于获取依赖的镜像
下载规则:
# 国内下载地址
https://mirrors.aliyun.com/kubernetes-release/release/${tag}/bin/linux/${arch}/kubeadm # 官方下载地址 https://dl.k8s.io/release/${tag}/bin/linux/${arch}/kubeadm
tag = v1.32.13(必须带 v)
arch = amd64 / arm64
下载kubeadm二进制包
#!/bin/bash ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 配置文件不存在 -> ${conf_file}" exit 1 fi source "${conf_file}" check_var() { local name="$1" if [[ -z "${!name}" ]]; then echo "ERROR: 配置变量【$name】不能为空,请检查配置文件" exit 1 fi } check_var base_dir check_var k8s_pkg_ver # =========本地副本变量========= local_base_dir="${base_dir}" local_k8s_pkg_ver="${k8s_pkg_ver}" local_arch=$(dpkg --print-architecture) # 从 k8s_pkg_ver="1.32.13-1~xxx" 截取 1.32.13 local_k8s_short_ver=$(echo "${local_k8s_pkg_ver}" | cut -d'-' -f1) local_k8s_tag="v${local_k8s_short_ver}" # 存放目录 local_kubeadm_bin_dir="${local_base_dir}/kubeadm-bin" mkdir -p "${local_kubeadm_bin_dir}" local_output_file="${local_kubeadm_bin_dir}/kubeadm-${local_k8s_tag}" echo "开始下载 kubeadm ${local_k8s_tag}" # curl下载 curl -L -fsSL "https://mirrors.aliyun.com/kubernetes-release/release/${local_k8s_tag}/bin/linux/${local_arch}/kubeadm" -o "${local_output_file}" # 添加执行权限 chmod +x "${local_output_file}" echo "下载完成:${local_output_file}" ls -lh "${local_kubeadm_bin_dir}" )
已下载的kubeadm二进制文件(加版本区分)
-rwxr-xr-x 1 root root 68M Aug 17 15:56 kubeadm-v1.32.13 -rw-r--r-- 1 root root 72M Aug 16 17:28 kubeadm-v1.33.9 -rw-r--r-- 1 root root 71M Aug 16 17:28 kubeadm-v1.34.10 -rw-r--r-- 1 root root 70M Aug 16 17:29 kubeadm-v1.35.5 -rw-r--r-- 1 root root 70M Aug 16 17:29 kubeadm-v1.36.3
2. 从二进制kubeadm包获取镜像并下载
#!/bin/bash ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 配置文件不存在 -> ${conf_file}" exit 1 fi source "${conf_file}" check_var() { local name="$1" if [[ -z "${!name}" ]]; then echo "ERROR: 配置变量【$name】不能为空,请检查配置文件" exit 1 fi } check_var base_dir check_var k8s_ver # =========本地副本变量========= local_base_dir="${base_dir}" local_k8s_ver="${k8s_ver}" # kubeadm二进制路径 local_kubeadm_bin="${local_base_dir}/kubeadm-bin/kubeadm-${local_k8s_ver}" # 目录与文件定义 local_work_dir="${local_base_dir}/k8s-${local_k8s_ver}" local_img_list_file="${local_work_dir}/k8s-images-${local_k8s_ver}.list" local_all_in_one_tar="${local_work_dir}/k8s-images-${local_k8s_ver}.tar.gz" mkdir -p "${local_work_dir}" # 校验kubeadm二进制文件 if [ ! -f "${local_kubeadm_bin}" ];then echo "ERROR: kubeadm二进制不存在:${local_kubeadm_bin}" exit 1 fi # ============镜像源【手动注释切换】============ # DaoCloud local_registry_prefix="m.daocloud.io" # 华为渡渡鸟DDN-K8s # local_registry_prefix="swr.cn-north-4.myhuaweicloud.com/ddn-k8s" # ============================================== echo "=====================================" echo "K8s版本: ${local_k8s_ver}" echo "命名空间: k8s.io (固定)" echo "镜像加速源前缀: ${local_registry_prefix}" echo "工作目录: ${local_work_dir}" echo "镜像清单文件: ${local_img_list_file}" echo "统一镜像包: ${local_all_in_one_tar}" echo "=====================================" # 旧包存在直接删除,强制覆盖 if [ -f "${local_all_in_one_tar}" ]; then echo "INFO: 删除旧镜像包:${local_all_in_one_tar}" rm -f "${local_all_in_one_tar}" fi # 生成原始镜像清单 echo "生成镜像清单..." ${local_kubeadm_bin} config images list --kubernetes-version=${local_k8s_ver} > "${local_img_list_file}" if [ ! -s "${local_img_list_file}" ];then echo "ERROR: 获取镜像列表为空!" exit 1 fi echo "镜像清单已保存:${local_img_list_file}" origin_img_array=() accel_img_array=() # 拉取镜像、打原生标签 while read -r origin_img; do [ -z "${origin_img}" ] && continue accel_img="${local_registry_prefix}/${origin_img}" accel_img_array+=("${accel_img}") origin_img_array+=("${origin_img}") echo -e "\n===== 拉取镜像:${accel_img} =====" nerdctl -n k8s.io pull "${accel_img}" if [ $? -ne 0 ];then echo "ERROR: ${accel_img} 拉取失败" exit 1 fi echo "打原生标签:${origin_img}" nerdctl -n k8s.io tag "${accel_img}" "${origin_img}" done < "${local_img_list_file}" # 使用 nerdctl save 一次性打包全部镜像 echo -e "\n===== 开始统一导出全部镜像 =====" nerdctl -n k8s.io save -o "${local_all_in_one_tar}" "${origin_img_array[@]}" if [ $? -ne 0 ];then echo "ERROR: 镜像统一导出失败!" exit 1 fi echo "镜像大包导出成功:${local_all_in_one_tar}" # 清理加速标签镜像 echo -e "\n===== 清理所有加速源镜像标签 =====" for img in "${accel_img_array[@]}"; do nerdctl -n k8s.io rmi "${img}" >/dev/null 2>&1 done echo -e "\n===== 全部镜像处理完成 =====" ls -lh "${local_work_dir}" )
输出:
drwxr-xr-x 2 root root 4096 Aug 17 15:16 k8s-debs -rw-r--r-- 1 root root 262 Aug 17 16:33 k8s-images-v1.32.13.list -rw-r--r-- 1 root root 147200000 Aug 17 16:33 k8s-images-v1.32.13.tar.gz
六,下载calico / ingress部署文件及镜像
根据k8s版本下载对应的yaml版本
1,下载yaml文件
1) k8s-v1.32、k8s-v1.33下载两个文件
calico-v3.31.6:https://raw.githubusercontent.com/projectcalico/calico/v3.31.6/manifests/calico.yaml
ingress-nginx-controler-v1.14.5:https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.5/deploy/static/provider/cloud/deploy.yaml
2) k8s-v1.34、k8s-v1.35下载这两个文件
calico-v3.32.1:https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml
ingress-nginx-controler-v1.15.1:https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/cloud/deploy.yaml
下载calico与ingress-nginx的部署文件
#!/bin/bash set -euo pipefail ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } check_var base_dir check_var k8s_ver check_var calico_ver check_var ingress_ver local_base_dir="${base_dir}" local_k8s_ver="${k8s_ver}" local_calico_ver="${calico_ver}" local_ingress_ver="${ingress_ver}" target_dir="${local_base_dir}/k8s-${local_k8s_ver}" mkdir -p "${target_dir}" cd "${target_dir}" || exit 1 calico_yaml="calico-${local_calico_ver}.yaml" ingress_yaml="ingress-nginx-${local_ingress_ver}.yaml" echo "===== 处理 ${calico_yaml} =====" if [ -f "${calico_yaml}" ]; then echo "${calico_yaml} 已存在,跳过下载" else echo "开始下载 ${calico_yaml}" curl -fSL -o "${calico_yaml}" \ https://mirror.ghproxy.com/https://raw.githubusercontent.com/projectcalico/calico/${local_calico_ver}/manifests/calico.yaml || { echo "⚠️ Calico yaml 下载失败" } fi echo -e "\n===== 处理 ${ingress_yaml} =====" if [ -f "${ingress_yaml}" ]; then echo "${ingress_yaml} 已存在,跳过下载" else echo "开始下载 ${ingress_yaml}" curl -fSL -o "${ingress_yaml}" \ https://mirror.ghproxy.com/https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-${local_ingress_ver}/deploy/static/provider/cloud/deploy.yaml || { echo "⚠️ Ingress-Nginx yaml 下载失败" } fi echo -e "\n✅ yaml文件就绪,当前目录yaml列表:" ls -lh *.yaml 2>/dev/null )
2.根据yaml文件里的镜像版本下载calico与ingress-nginx镜像
#!/bin/bash set -euo pipefail ( conf_file="./k8s-offline.conf" if [ ! -f "${conf_file}" ];then echo "ERROR: 当前目录缺少配置文件 ${conf_file}" echo "当前工作目录:$(pwd)" echo "请进入对应k8s版本目录执行脚本!" exit 1 fi source "${conf_file}" check_var() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "ERROR: 配置变量【${name}】不能为空,请检查 ${conf_file}" exit 1 fi } check_var base_dir check_var k8s_ver check_var calico_ver check_var ingress_ver local_base_dir="${base_dir}" local_k8s_ver="${k8s_ver}" local_calico_ver="${calico_ver}" local_ingress_ver="${ingress_ver}" # 渡渡鸟:备用源(仅定义保留,本次不启用拉取) local_mirror_ddn="swr.cn-north-4.myhuaweicloud.com/ddn-k8s/" # DaoCloud 统一主源 local_mirror_dao="m.daocloud.io/" target_dir="${local_base_dir}/k8s-${local_k8s_ver}" mkdir -p "${target_dir}" cd "${target_dir}" || exit 1 calico_yaml="calico-${local_calico_ver}.yaml" calico_list="calico-images-${local_calico_ver}.list" calico_tar="calico-images-${local_calico_ver}.tar.gz" ingress_yaml="ingress-nginx-${local_ingress_ver}.yaml" ingress_list="ingress-nginx-images-${local_ingress_ver}.list" ingress_tar="ingress-nginx-images-${local_ingress_ver}.tar.gz" # 校验yaml必须存在 if [[ ! -f "${calico_yaml}" ]]; then echo "❌ 错误:找不到文件 ${target_dir}/${calico_yaml}" exit 1 fi if [[ ! -f "${ingress_yaml}" ]]; then echo "❌ 错误:找不到文件 ${target_dir}/${ingress_yaml}" exit 1 fi # -------------------------- # Calico镜像拉取打包(DaoCloud源) # -------------------------- echo -e "\n===== 提取 Calico 镜像清单 =====" awk '/image:/ {sub(/@.*/,"",$2);print $2}' "${calico_yaml}" | sort -u > "${calico_list}" cat "${calico_list}" echo -e "\n===== 拉取 Calico 镜像(DaoCloud源) =====" while read -r img; do [[ -z "${img}" ]] && continue mirror_img="${local_mirror_dao}${img}" echo "pull ${mirror_img}" if ! nerdctl -n k8s.io pull "${mirror_img}"; then echo "⚠️ ${mirror_img} 拉取失败,跳过" continue fi echo "tag ${mirror_img} -> ${img}" nerdctl -n k8s.io tag "${mirror_img}" "${img}" echo "rm temp mirror image ${mirror_img}" nerdctl -n k8s.io rmi "${mirror_img}" done < "${calico_list}" echo -e "\n===== 打包 Calico 镜像 ${calico_tar} =====" mapfile -t calico_images < "${calico_list}" if [[ ${#calico_images[@]} -gt 0 ]]; then nerdctl -n k8s.io save -o "${calico_tar}" "${calico_images[@]}" else echo "⚠️ Calico镜像清单为空,跳过打包" fi # -------------------------- # Ingress-Nginx镜像拉取打包(DaoCloud源) # -------------------------- echo -e "\n===== 提取 Ingress-Nginx 镜像清单 =====" awk '/image:/ {sub(/@.*/,"",$2);print $2}' "${ingress_yaml}" | sort -u > "${ingress_list}" cat "${ingress_list}" echo -e "\n===== 拉取 Ingress-Nginx 镜像(DaoCloud源) =====" while read -r img; do [[ -z "${img}" ]] && continue mirror_img="${local_mirror_dao}${img}" echo "尝试拉取(DaoCloud): ${mirror_img}" if nerdctl -n k8s.io pull "${mirror_img}"; then echo "tag ${mirror_img} -> ${img}" nerdctl -n k8s.io tag "${mirror_img}" "${img}" nerdctl -n k8s.io rmi "${mirror_img}" else echo "❌ ${img} DaoCloud源拉取失败,跳过" fi done < "${ingress_list}" echo -e "\n===== 打包 Ingress-Nginx 镜像 ${ingress_tar} =====" mapfile -t ingress_images < "${ingress_list}" if [[ ${#ingress_images[@]} -gt 0 ]]; then nerdctl -n k8s.io save -o "${ingress_tar}" "${ingress_images[@]}" else echo "⚠️ Ingress镜像清单为空,跳过打包" fi echo -e "\n✅ 镜像拉取打包完成!输出压缩包:" ls -lh *.tar.gz *.list )
七,生成的文件清单
ls -lh total 548M -rw-r--r-- 1 root root 95 Aug 17 18:18 calico-images-v3.31.6.list -rw-r--r-- 1 root root 272M Aug 17 18:18 calico-images-v3.31.6.tar.gz -rw-r--r-- 1 root root 324K Aug 17 18:00 calico-v3.31.6.yaml -rw-r--r-- 1 root root 107 Aug 17 18:18 ingress-nginx-images-v1.14.5.list -rw-r--r-- 1 root root 136M Aug 17 18:18 ingress-nginx-images-v1.14.5.tar.gz -rw-r--r-- 1 root root 16K Aug 17 18:00 ingress-nginx-v1.14.5.yaml drwxr-xr-x 2 root root 4.0K Aug 17 17:33 k8s-debs -rw-r--r-- 1 root root 262 Aug 17 17:24 k8s-images-v1.32.13.list -rw-r--r-- 1 root root 141M Aug 17 17:24 k8s-images-v1.32.13.tar.gz -rw-r--r-- 1 root root 528 Aug 17 17:43 k8s-offline.conf ls -lh ./k8s-debs/ total 111M -rw-r--r-- 1 root root 22M Aug 13 20:51 containerd.io_2.3.3-1~ubuntu.26.04~resolute_amd64.deb -rw-r--r-- 1 root root 16M Dec 9 2024 cri-tools_1.32.0-1.1_amd64.deb -rw-r--r-- 1 root root 12M Feb 27 08:18 kubeadm_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 11M Feb 27 08:18 kubectl_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 15M Feb 27 08:18 kubelet_1.32.13-1.1_amd64.deb -rw-r--r-- 1 root root 37M Dec 12 2024 kubernetes-cni_1.6.0-1.1_amd64.deb
八,部署
1. manifest.info 文件配置
vi /data/k8s/k8s-v1.32.13
K8S_BASE="/data/k8s/k8s-v1.32.13" K8S_VERSION="v1.32.13" CALICO_VERSION="v3.29.0" INGRESS_NGINX_VERSION="v1.11.2" PAUSE_VERSION="v3.10"
2. 部署脚本
# 切换版本只改这一行source路径 source /data/k8s/k8s-v1.32.13/manifest.info # 安装deb dpkg -i ${K8S_BASE}/k8s-debs/*.deb # 导入k8s合并镜像包 ctr -n k8s.io images import ${K8S_BASE}/k8s-images-${K8S_VERSION}.tar.gz # calico ctr -n k8s.io images import ${K8S_BASE}/calico-images-${CALICO_VERSION}.tar.gz kubectl apply -f ${K8S_BASE}/calico-${CALICO_VERSION}.yaml # ingress‑nginx ctr -n k8s.io images import ${K8S_BASE}/ingress-nginx-images-${INGRESS_NGINX_VERSION}.tar.gz kubectl apply -f ${K8S_BASE}/ingress-nginx-${INGRESS_NGINX_VERSION}.yaml

浙公网安备 33010602011771号