news 2026/9/29 23:56:30

Kubernetes 1.18.8离线部署全攻略:私有仓库搭建与镜像推送实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes 1.18.8离线部署全攻略:私有仓库搭建与镜像推送实践

简介:K8s 1.18.8 离线安装部署资源包,面向需要在内网或受限网络环境快速搭建容器集群的运维与开发人员。压缩包共21个文件,以脚本、配置清单、服务单元为核心,同时包含集群核心组件、容器镜像离线包及多种辅助工具,整体约610MB,可满足离线交付需求。当前已有289人学习下载。资源预置了完整的部署材料:初始化和主节点配置脚本负责环境预检、控制面初始化与容器运行时适配;集群初始化配置和网络插件清单可一键落地基础服务与网络方案;镜像压缩包便于批量导入私有仓库;另有服务管理配置、连接跟踪、容器命令行等工具,帮助在无外网条件下完成高可用集群搭建和故障排查。借助该资源包能大幅缩短集群环境准备时间,适合离线实施、教学实训与内部交付场景。

1. 拿到 kube1.18.8.tar.gz 之后:面前是一个离线交付包,不是压缩文件

离线机房、内外网隔离的测试区、还要过等保的政务网,在这些地方装 Kubernetes 1.18.8,网络是天然敌人。你从同事移动硬盘里拷来一个 kube1.18.8.tar.gz,解压之后发现里面有二进制、镜像、一堆 yaml。这个包确实能解出来,但真正的问题是:依赖镜像怎么进集群、私有仓库怎么接,以及为什么所有节点上的 kubelet 还是会报 6443 连不上。这篇文章就把这个 tar.gz 从校验、拆包、推私有仓库到离线拉起集群的完整链路讲清楚,适合正在做内网交付或镜像站下载后自己维护的工程师。你手里的不是安装包,是一套需要自己补完的交付物。

2. 先拆包再谈部署:校验、解压、二进制落位一次做对

2.1 用 SHA256 校验“半路货”

离线包最容易翻车的地方是拷一半断了,或者对方给你的包本身就不是完整构建。kube1.18.8.tar.gz 这样的包,常见做法是从中科大开源镜像站或者阿里云镜像站下载原始文件,站点页面一般会列 sha256。下载后先校验,再用 tar 解压,不要跳过这一步,不然后面所有报错都是黑匣子,理不清源头。

# 先拿到发布方给的 sha256 值,比如 4d7029454e2f9c20a12d3b5c8c9ffb7d1eba2d0e2f46e5f2d4d6d8b1a3c9e0a1 echo "4d7029454e2f9c20a12d3b5c8c9ffb7d1eba2d0e2f46e5f2d4d6d8b1a3c9e0a1 kube1.18.8.tar.gz" | sha256sum -c - # 输出 kube1.18.8.tar.gz: OK 则说明文件完整,可以继续

这条命令把期望的哈希值和文件名一起喂给 sha256sum,-c表示核对模式。如果输出不是 OK,别解压,直接回去找包。常见做法是先在镜像站页面把哈希复制到一个文本,再执行校验,避免手敲漏字符。校验通过后解压,不要用 Windows 里的压缩工具解,Linux 上用 tar 是最稳的。

tar -xzf kube1.18.8.tar.gz # 假设包内是一个 kubernetes/ 或 release/ 目录结构 ls -l

解压之后如果看到 bin/ 目录,里面有 kubeadm、kubelet、kubectl、kube-apiserver 等二进制,说明是标准的服务器包结构。有些发行版会把镜像打成单独的 tar,解压后看不到 bin/,那就要先做一次 docker load 再看目录。

2.2 先看目录结构,再决定部署方式

我一般会先把解压后的目录整体看一遍,确认包里有 Kubernetes 1.18.8 的 server 二进制和配套镜像清单。1.18.8 是 2020 年 9 月左右的版本,镜像仓库默认值是 k8s.gcr.io,镜像清单里应该有 pause、etcd、coredns、kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy 这七类。离线环境里,这个默认仓库地址必须改,否则所有节点都会卡在拉镜像这一步。

find . -maxdepth 3 -type f \( -name "*.tar" -o -name "*.yaml" -o -name "*.conf" \) | sort # 这一步是为了确认包里有哪些类型的交付物,决定后续是走 docker load 还是 direct ctr import

如果看到 images/ 目录下有一堆 tar 文件,那就走先 load 再 tag 再 push 的链路。如果包内只有二进制和 yaml,没有镜像 tar,你后面就必须单独准备离线镜像,或者在内网另外搭一个 registry,并保证网络能访问到。

2.3 把二进制放到系统路径,顺手解决 PATH 问题

解压出来的二进制默认没有权限,也未必在 PATH 里。我一般会把它们统一放到 /usr/local/bin,然后把 systemd unit 文件也准备好,方便后面用 kubeadm init 时直接调用。

mkdir -p /opt/kubernetes-1.18.8/bin cp -r kubernetes/server/bin/* /opt/kubernetes-1.18.8/bin/ chmod +x /opt/kubernetes-1.18.8/bin/* ln -sf /opt/kubernetes-1.18.8/bin/kubeadm /usr/local/bin/kubeadm ln -sf /opt/kubernetes-1.18.8/bin/kubelet /usr/local/bin/kubelet ln -sf /opt/kubernetes-1.18.8/bin/kubectl /usr/local/bin/kubectl

这里把二进制从 tar 包里落位到统一目录,然后做软链。软链的好处是以后换版本可以只改 /opt/ 下的目录,不影响 systemd 脚本。1.18.8 的 kubeadm 默认对 Docker 的适配比较完整,但对 containerd 还需要手工指定 cri-socket,这一步后面会专门讲。如果你要在麒麟 v10 这类系统上装,先确认系统自带 glibc 版本,tar.gz 里的二进制是动态编译的,glibc 太老会出现 command not found 或者段错误。

3. 把下载好的 tar.gz 推到私有仓库:这条链路不只 kubekey 在用

3.1 为什么问“怎么推私有仓库”的人最多

实际部署时,master 和 node 都在内网,几乎所有机器都没有外网访问权限。你在镜像站下载 tar.gz 后,第一件事就是把镜像导入到内网私有仓库,比如 registry:5000。很多帖子会提到 kubekey,但 kubekey 本身是 KubeSphere 的安装工具,不是专门处理任意 tar.gz 镜像推送的。常见的做法是手工完成一条链:docker load、docker tag、docker push,或者用 skopeo 在不依赖 docker daemon 的情况下把镜像直接 copy 到 registry。下面我分别给出两条路线。

3.2 路线一:先本地 load,再打标推送到私有仓库

如果 kube1.18.8.tar.gz 里带了镜像 tar,第一件事是先把镜像导入本机 Docker。注意导入的镜像是仓库名+标签的形式,比如 k8s.gcr.io/kube-apiserver:v1.18.8,需要改成内网 registry 的地址,再推送。

# 把 tar.gz 里的镜像文件导入本地 docker docker load -i kube-apiserver.tar docker load -i kube-controller-manager.tar # 对所有需要推送到内网的镜像执行打标签 docker tag k8s.gcr.io/kube-apiserver:v1.18.8 registry.internal:5000/kube-apiserver:v1.18.8 docker push registry.internal:5000/kube-apiserver:v1.18.8

这段命令的作用是把本地镜像库里的原始镜像重新命名为内网 registry 地址,然后再推送。打标签必须注意三层结构,私有仓库路径一般写成 registry地址/项目名/镜像名:版本号。很多人栽在漏掉版本号或多了一个斜杠,push 时报 manifest invalid。如果镜像文件较多,建议写一个循环:

for img in $(docker images --format '{{.Repository}}:{{.Tag}}' | grep 'k8s.gcr.io'); do newimg="registry.internal:5000/${img#k8s.gcr.io/}" docker tag "$img" "$newimg" docker push "$newimg" done

这里的参数替换${img#k8s.gcr.io/}是把镜像名里开头的 k8s.gcr.io/ 去掉,再拼上私有仓库前缀。注意 grep 的写法要按你实际 load 进来的镜像列表来过滤,不能凭空硬编。执行完后,去 registry 的 web 页面或者用 curl 看一下 v2/_catalog,确认镜像已经在仓库里。

3.3 路线二:不想碰 docker daemon 就用 skopeo

有些离线环境没有 Docker,或者 daemon 起不来,这时候 skopeo 就派上用场了。skopeo 可以从本地 tar 直接 copy 到 registry,不需要经过 docker load/tag。

# 把 tar 包里的镜像直接推送到 registry skopeo copy docker-archive:./kube-apiserver.tar docker://registry.internal:5000/kube-apiserver:v1.18.8

这条命令里docker-archive:指本地 tar 包,docker://指目标 registry。skopeo 的好处是它直接操作镜像层,不占用本地 docker 存储空间。缺点是你得先确认 tar 包里到底包含哪些镜像,不能批量处理的时候盲目猜测。常见做法是解包后先看 manifest,再用 skopeo 逐一把镜像 copy 过去。

3.4 推送私有仓库后必须验证一件事

推完镜像后,第一时间做一次拉取测试,从一台没有本地镜像缓存的机器上docker pull registry.internal:5000/kube-apiserver:v1.18.8。如果拉不下来,检查 registry 证书和 HTTP 配置。很多团队用 HTTP 私有仓库,kubelet 默认不允许非 TLS 仓库,需要给所有节点配 containerd 或 Docker 的 insecure-registries。这个不提前做好,后面 kubeadm init 会一直报拉镜像失败,而且日志里只显示 context deadline exceeded,特别像网络不通。

# 拉取测试,确保私有仓库可以被集群内节点访问 curl -X GET http://registry.internal:5000/v2/_catalog # 如果返回的 JSON 里能看到 kube-apiserver 等镜像名,说明仓库侧正常

这一步是玄学集中地。很多人在内网装 registry 后,本机能 curl 通,但到 kubelet 那边就超时,原因是节点上的 Docker 没有配置 insecure-registries,或者 containerd 的 config.toml 里没有加 registry 配置。后面第 5 章会专门展开排错。

4. 用离线包拉起 1.18.8 集群:容器运行时、kubeadm 配置与镜像仓库接线

4.1 先确认你准备用什么容器运行时

kubeadm 1.18.8 默认优先找 Docker,如果你只用 containerd,必须在 init 时指定--cri-socket,否则它找不到运行时直接退出。我一般建议离线环境统一用 containerd,因为它在内网更可控,不依赖 docker daemon 的额外维护成本。但用的 containerd 版本不能太新,太新的 cri 插件路径变了,kubelet 1.18.8 认不出。稳妥做法是先用一台上网机器下载好的 tar.gz 里自带的镜像,在内网机器上先部署 containerd,确认/run/containerd/containerd.sock存在,再继续。

# 启动 containerd 并确认 socket 存在 systemctl enable --now containerd ls -l /run/containerd/containerd.sock

如果 socket 路径不存在,常见原因有两个:containerd 没启动成功,或者配置里的 cri 插件被注释掉了。去/etc/containerd/config.toml看disabled_plugins = ["cri"]是不是被打开了,1.18.8 要求 cri 插件必须启用。这个坑能卡住很多人,因为 containerd 本身起来了,也能拉镜像,但 kubeadm 就是探测不到 runtime。

4.2 写 kubeadm 配置文件并修正 imageRepository

kubeadm 默认从 k8s.gcr.io 拉镜像,离线环境必须改成内网私有仓库。在镜像推送做完后,我一般会生成一份 kubeadm.yaml,把 imageRepository 指到 registry.internal:5000。注意 1.18.8 版本里,kubeadm 的 imageRepository 只支持一个前缀地址,不支持像新版那样写多级仓库路径,所以你的私有仓库地址后面不要带子路径,除非你把镜像 tag 按子路径重推了一份。

# kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.18.8 imageRepository: registry.internal:5000 controlPlaneEndpoint: "192.168.10.10:6443" networking: podSubnet: "10.244.0.0/16" serviceSubnet: "10.96.0.0/12" --- apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.10.10 bindPort: 6443 nodeRegistration: criSocket: /run/containerd/containerd.sock

这段 yaml 是 kubeadm 1.18.8 的标准配置。imageRepository 指到私有仓库后,kubeadm 会拉取registry.internal:5000/kube-apiserver:v1.18.8这样的镜像。controlPlaneEndpoint 写成集群 VIP 或者 master 实际 IP,如果只有一个 master,直接写 master IP。podSubnet 的 10.244.0.0/16 是 Flannel 默认网段,你可以根据自己的 CNI 选型改,但改了之后 CNI 配置要和它一致。

4.3 执行初始化:kubeadm init 前的两个检查

在 init 之前,先做一次kubeadm config images list --config kubeadm-config.yaml,确认 kubeadm 会从私有仓库拉哪些镜像。这一步很重要,能提前发现仓库地址拼写错误或者镜像缺失,比直接 init 省时间。如果镜像列表里出现的是registry.internal:5000/kube-apiserver:v1.18.8,说明--config生效了。

# 预检查镜像列表 kubeadm config images list --config kubeadm-config.yaml # 直接初始化控制面 kubeadm init --config kubeadm-config.yaml --upload-certs | tee kubeadm-init.log

--upload-certs会把证书上传到集群 secret 里,方便后续 join 时不用手动拷贝证书,但 1.18.8 会要求在 join 命令里显式带上--certificate-key。别把这条信息弄丢,kubeadm-init.log里会输出完整的 join 命令。如果 init 失败,先看日志里的 error 关键词,不要反复 init,因为第一次失败留下的 etcd 数据会干扰后续操作。处理办法是kubeadm reset -f后清理/var/lib/etcd,再重新 init。

4.4 工作节点加入集群:join 命令的完整链

工作节点上需要先装好 kubelet、kubeadm、kubectl 三个二进制,还要让 kubelet 知道使用哪个 CRI。只把二进制放上去不够,kubelet 的 systemd unit 和配置文件必须就位。我一般会在工作节点上同样解压 tar.gz,然后把二进制复制到 /usr/local/bin,再把 kubelet 服务设置为开机自启。

# 仅在工作节点执行:拷贝二进制并启用 kubelet cp /opt/kubernetes-1.18.8/bin/kubelet /usr/local/bin/ cp /opt/kubernetes-1.18.8/bin/kubeadm /usr/local/bin/ systemctl enable --now kubelet

kubelet 启动后不一定能立刻选到 CRI,需要你手动写/etc/default/kubelet加上KUBELET_EXTRA_ARGS="--cri-socket=/run/containerd/containerd.sock"。然后在 master 上拿到的 kubeadm join 命令,把 token 和 hash 填进去,在节点上执行。如果 join 时报 6443 refused,别急着怀疑防火墙,先回想一下 controlPlaneEndpoint 对不对、负载均衡有没有建、证书 key 有没有带全。

# 工作节点上执行 join kubeadm join 192.168.10.10:6443 --token xxxx \ --discovery-token-ca-cert-hash sha256:yyyy \ --cri-socket /run/containerd/containerd.sock

join 之后至少等 30 秒再查节点状态,因为镜像拉取和组件启动都需要时间。kubectl get nodes如果看到工作节点是 NotReady,下一步看kubectl describe node和journalctl -u kubelet,这两个是排查的关键入口。

5. 离线部署 1.18.8 的五个高频翻车点:现象、原因、解决

5.1 校验失败:明明包能打开,sha256 却对不上

现象:sha256sum -c报 FAILED,但解压和复制都正常。原因:对方把打包和哈希打包成了两个不同文件,或者 tar.gz 是从网盘下载后被网盘自动改过格式。解决:用镜像站原始文件重新下载,或者在目标机器上用head -c 1024 kube1.18.8.tar.gz | hexdump和源站对比魔数。记住,哈希对不上就不要用,尤其是要推到生产集群的包,血泪经验告诉你,这种包大概率在某个镜像上缺层。

5.2 docker load 成功但 kubelet 仍然找不到镜像

现象:docker images能看到registry.internal:5000/kube-apiserver:v1.18.8,但kubeadm init一直报Failed to pull image。原因:如果你用的是 containerd,而不是 Docker,那 docker load 进去的镜像完全不会被 containerd 看到,两个运行时各有各的存储。解决:要么统一用 Docker,要么改用 containerd 的ctr -n=k8s.io images import导镜像。注意命名空间必须是k8s.io,否则 kubelet 还是无法识别。

# 用 containerd 导入镜像,注意必须带命名空间 ctr -n=k8s.io images import ./kube-apiserver.tar ctr -n=k8s.io images list | grep kube-apiserver

如果你之前用 docker load 导过,之后换了 containerd,那这些镜像相当于没有进入集群的视角。解决方法是把打包好的镜像 tar 重新用ctr -n=k8s.io导入,然后 restart kubelet。不要再相信 docker load 在当前场景里有用,这是 1.18.8 时代最常见的黑匣子之一。

5.3 kubeadm init 报 etcd 端口被占用

现象:第一遍 init 失败后,清理不彻底,第二遍直接报listen tcp :2379: bind: address already in use。原因:etcd 容器删了,但宿主机端口没释放,或者之前的静态 pod 还在。解决:执行kubeadm reset -f,然后检查 2379 和 2380 端口占用,必要时kill -9遗留进程。还要清理/var/lib/etcd、/etc/kubernetes、~/.kube,确保环境干净再重新 init。1.18.8 不像新版有--force重置,你得手动清干净。

5.4 join 时报 6443 refused,但防火墙没开

现象:节点 join 时输出couldn't find a server或 dial tcp 超时。原因:kube-apiserver 的静态 pod 没起来,或者 controlPlaneEndpoint 填的是不可达 IP。解决:在 master 上先kubectl get pods -n kube-system | grep kube-apiserver,如果是 ContainerCreating,用kubectl logs -n kube-system kube-apiserver-<hostname>看具体错误。很多情况下是 apiserver 的镜像 tag 在私有仓库里名字不对,导致拉取失败。还有一种情况是 join 时用 6443,但 master 上 port 没监听,netstat -lnp | grep 6443看一次就知道。

5.5 麒麟 v10 等国产化系统上依赖缺失

现象:二进制解压后执行kubeadm version报error while loading shared libraries: libc.so.6或者段错误。原因:tar.gz 里的二进制是在较新的 glibc 环境编译的,老系统 glibc 版本低于它需要的版本。解决:用ldd /usr/local/bin/kubeadm查看动态库依赖,如果系统 glibc 过低,需要单独使用官方发布的针对该系统的二进制包,或者用容器方式运行 kubelet。这是 tar.gz 安装模式在麒麟这类系统上绕不过去的坎,别硬扛编译参数,先确认你是在同版本或兼容系统上解包的。如果只是缺 libcrypto 或 libssl,可以尝试复制同版本库文件到 /usr/lib64,但要看清楚软链。

6. 部署完先别走:节点健康检查、插件补齐与版本固化

集群起来后,先验证kubectl get nodes全部 Ready,再检查核心插件。1.18.8 的 kubeadm init 只帮你把控制面组件部署完,不会自动装 CNI 插件、metrics-server、dashboard。没有 CNI,所有节点会一直 NotReady,没有 metrics-server,kubectl top用不了,所以离线包之外还要准备这几个插件的镜像和 yaml。常见做法是手里同时备好 Flannel/Calico 的 tar 包,在同一套私有仓库里推进去。

# 查看集群工作节点、deployment 和容器组运行状况 kubectl get nodes -o wide kubectl get pod -A -o wide # 如果 Flannel 镜像在私有仓库,直接应用其 yaml kubectl apply -f kube-flannel.yml

应用完 CNI 后,等一到两分钟,所有节点 Ready 才算真正成功。最后把你用的 kubeadm-config.yaml、镜像清单、版本号和私有仓库地址写到一个 README 里,放到 /opt/kubernetes-1.18.8/ 下,作为这次交付的基线。后续如果要做升级,至少还有版本对应关系可查。我见过太多团队半年后回来看部署文档,发现仓库地址已经换了、镜像 tag 也更新了,后悔药都没得吃。希望帮到你,动手的时候先把上面第 3 章和第 5 章过一遍,能省下不少试错时间。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 23:56:18

Jev模型实操教程:一小时接入Codex打造专属AI编程助手

你是不是也刷到过 Jev 这个词&#xff0c;但翻了半天内容&#xff0c;要么是零散截图&#xff0c;要么是“我已经跑通了”这种炫耀贴&#xff0c;根本没人告诉你中间那几步怎么连起来的。我花了周末一下午&#xff0c;把 Jev 模型从一个“听说过”的名字&#xff0c;变成自己电…

作者头像 李华
网站建设 2026/9/29 23:56:14

目标检测数据集实战:4500张杯子VOC+YOLO双格式训练全解

简介&#xff1a;面向目标检测模型训练的数据集&#xff0c;整合4500张杯子图像&#xff0c;并同时提供Pascal VOC与YOLO两种主流标注格式&#xff0c;适合熟悉labelImg标注流程、需要标准数据训练YOLO系列或Faster R-CNN等检测模型的开发者。全包共2000个文件&#xff0c;以19…

作者头像 李华
网站建设 2026/9/29 23:54:36

Qwen-Image-2.1 电商商品图提示词与本地部署实战全攻略

最近半个月我几乎把开源生图模型都重装了一遍&#xff0c;就为了给电商商品图找个能打的底座。一圈测下来&#xff0c;身边朋友问得最密集的果然还是 Qwen-Image-2.1 的商品图提示词怎么写&#xff0c;以及整合包到底怎么选——因为它的完成度确实比很多人想象中高&#xff0c;…

作者头像 李华
网站建设 2026/9/29 23:54:32

Kubernetes 上的 Agentic Runtime 编排:从 ax 到生产级落地实践

1. 从"ax"这个标题说起&#xff1a;一个被低估的运行时编排命题 第一次看到"ax"这个标题&#xff0c;加上 agentic、orchestration、runtime、Kubernetes 这几个关键词&#xff0c;我脑子里第一反应不是某个具体产品&#xff0c;而是一类正在快速成型的系统…

作者头像 李华
网站建设 2026/9/29 23:54:32

Winform窗体控件布局缩放自适应:快照-回放模型解决界面拉伸乱局

简介&#xff1a;面向C# Winform开发者的窗体与控件自适应缩放辅助类资源&#xff0c;解决窗体尺寸变化后内部控件难以按原布局自动调整的常见问题。源码提供AutoScaleHelper核心类及TextScale等配套实现&#xff0c;覆盖多数内置控件、自定义控件与动态添加控件的缩放需求&…

作者头像 李华
网站建设 2026/9/29 23:52:57

AI Agent知识获取管道:RAG稠密与稀疏嵌入混合检索实战

1. 为什么知识获取管道是 AI Agent 落地的第一道分水岭做 AI Agent 的人迟早会撞上同一堵墙&#xff1a;模型本身很聪明&#xff0c;但你问它公司内部的报销标准、上周刚更新的产品参数、某个客户的特殊约定&#xff0c;它要么一本正经地胡说&#xff0c;要么干脆说不知道。这不…

作者头像 李华