如果你也在维护测试环境,大概率经历过这种场景:申请了一台 4C8G 的虚机,准备在上面起一套 Kubernetes 给开发联调用。用 kubeadm 从零开始,初始化、装 CNI、调 kubelet 参数,一套流程下来最快也要半小时,一旦碰上版本兼容问题,一个下午就没了。后来我换成 Sealos,单节点部署测试环境这件事被压缩到十分钟以内,而且重建、清理都异常简单。
这篇文章就把我实际操作的完整过程写出来,包括测试环境为什么适合用 Sealos 单节点、动手前要准备什么、完整部署步骤,以及最让人头疼的 sealos 拉取失败问题该怎么排查。无论你是刚接触 Kubernetes 的新手,还是被测试环境搭建反复折磨的运维/开发,照着走一遍应该都能跑起来。
1. 为什么单节点测试环境我选了 Sealos
1.1 从 kubeadm 到 Sealos:测试环境搭建的痛
在换到 Sealos 之前,我维护测试环境的方式是 kubeadm。过程大概是:先准备好几台机器,装好容器运行时,然后手工初始化第一个 master 节点,等 kubeadm init 跑完,再处理 kubeconfig、安装 CNI 插件。这套流程本身没有问题,生产环境我也赞成用 kubeadm 精细控制。但放在测试环境,它有几个非常恼人的痛点。
首先是重复劳动。开发提了个"给我一套能跑服务网格的环境",你得把之前做过一遍的事情原封不动再做一遍,而期间你还要去查 kubeadm 某个版本对应的 etcd 版本、kubelet 版本、CNI 版本,这种表格看多了真的会烦。其次是隐蔽的版本兼容问题。Kubernetes 每个小版本都可能有 API 变更,kubeadm 不一定踩坑,但 kubelet 与容器运行时之间的 cgroup driver 不一致、内核参数不对、swap 没关,都是测试环境最常见的翻车点。最难受的是,这些问题出现的时间点往往是你已经在快速敲命令、脑子里已经想好下一步的时候,突然被一个报错打断,整个节奏全没了。
Sealos 解决的就是这个场景。它把 Kubernetes 依赖的 kubeadm、kubelet、kubectl、etcd、pause 镜像、CoreDNS、CNI 插件全部打包成容器镜像,通过镜像仓库分发。你做单节点部署时,本质上是在执行一条命令:拉取打包好的镜像,然后 Sealos 自己完成检测系统、生成证书、初始化控制面、安装 CNI 这一整套流程。对你来说,原本二三十个步骤变成了一次性操作。
1.2 Sealos 到底做了什么
用个生活化的比喻:Sealos 像是"装机版 Kubernetes 镜像"。普通方式搭集群,等于你自己去电脑城买散件再组装——每一颗螺丝(证书、kubeconfig、组件参数)都要亲手拧。Sealos 则是把整套已经配置好的系统做成了一键恢复盘,你只需要选择装哪个版本、装在哪台机器上,剩下的交给它。
单节点部署时,Sealos 内部做的事情大概是:通过 SSH 连接目标机器,检查操作系统、磁盘、网络状态,准备好容器运行时,把 Kubernetes 控制面组件以静态 Pod 的方式跑起来,然后安装 CNI 插件、CoreDNS 等附加组件。整个过程是幂等的,失败了可以 reset 后再跑,这在测试环境里特别重要,你可以毫无心理负担地反复折腾。
这里也说明一下,Sealos 并不是只能单节点。它支持多 master 高可用,也支持在已有集群上扩容节点。但单节点模式有一个天然优势:不需要考虑负载均衡、不需要管 etcd 集群一致性,所有组件跑在同一台机器上,对资源占用最小,非常适合开发联调、功能验证、CI 流水线这类场景。我就把测试环境的默认形态定成了单节点,简单直接。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手之前:一台合格的测试机要满足什么
2.1 硬件和系统版本要求
先看硬件。单节点 Sealos 集群,控制面和业务 Pod 都挤在一台机器上,配置不能太低。我实测下来的经验是:最低 2C4G 能起,但是跑几个应用就会感觉到压力,尤其是 etcd 和 kubelet 本身就要吃内存;申请 4C8G 用起来才比较从容,至少能同时跑上五六个测试应用不带喘气的。磁盘方面,系统盘 50G 起步,镜像和容器日志的消耗比想象中快。
| 项目 | 最低配置 | 推荐配置 | 说明 |
|---|---|---|---|
| CPU | 2 核 | 4 核 | 控制面组件至少占 1 核 |
| 内存 | 4 GB | 8 GB | etcd + apiserver + 业务 Pod |
| 系统盘 | 20 GB | 50 GB | 镜像、容器日志、本地存储 |
| 网络 | 任意内网 | 千兆网卡 | 单节点对带宽要求不高 |
操作系统这块,Ubuntu 20.04/22.04、CentOS 7.9、Rocky Linux 8/9 我都在测试环境用过,没有遇到问题。要注意的是 CentOS 7.9 默认内核版本偏旧,建议先把内核升级到 5.x 再跑 Kubernetes,否则可能遇到一些奇怪的兼容性问题。其他发行版只要内核在 4.18 以上,基本都能跑。
2.2 系统基础配置:这几步别偷懒
在真正执行 sealos 部署之前,有几项系统配置建议提前做好,不然部署到一半报错,排查成本更高。
第一,关 swap。Kubernetes 对 swap 的态度很明确,kubelet 默认不允许 swap 存在。执行 swapoff -a,并把 /etc/fstab 里的 swap 行注释掉,确保重启后也不会重新挂载。
第二,配置主机名和 hosts。测试机建议设置一个固定主机名,比如 k8s-test-01,然后在 /etc/hosts 里写上本机 IP 和主机名的映射。Sealos 在初始化时会用到主机名做证书和节点注册,如果 hosts 解析有问题,可能会出现节点一直 NotReady。
第三,时间同步。控制面组件对时间偏差很敏感,测试环境虽然没有生产要求那么苛刻,但最好还是配一下 chrony 或者 systemd-timesyncd,保证时间准确。
第四,防火墙和端口。测试环境我建议直接关闭 firewalld 或 ufw,省得排查端口问题。如果你的网络策略不允许关防火墙,至少要放行这些端口:6443(kube-apiserver)、2379/2380(etcd)、10250(kubelet)、10256(kube-proxy)。
提示:单节点部署时,Sealos 会通过 SSH 连接本机,所以确保 SSH 服务是启动状态,并且当前用户能正常通过 SSH 连接自己。这个问题很多人忽略,后面会展开说。
2.3 准备 SSH 免密
这一步看起来不起眼,但实际部署失败里有一小半是栽在这里。Sealos 执行部署时,需要 SSH 到目标节点,即使用户当前就在那台机器上操作,它走的也是 SSH 通道,而不是直接在本机执行命令。
为了让流程顺畅,我建议提前生成 SSH 密钥并把公钥加到 authorized_keys 里。操作很简单:
bash复制ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
然后验证一下能否免密连到本机:
bash复制ssh localhost hostname
能正常返回主机名,SSH 这块就准备好了。如果 Sealos 执行时提示 SSH 认证失败,优先检查这一步,别去怀疑集群配置。另外,如果你是 root 用户操作,确认 /root/.ssh 的权限也是对的,SSH 对权限要求很敏感。
3. 单节点集群搭建全流程:从安装 sealos 到集群 Ready
3.1 安装 sealos 二进制
Sealos 的安装方式很简单,官方提供了一键安装脚本。我在国内环境实测下来,执行:
bash复制curl -sfL https://mirror.sealos.io/install.sh | sh
装完检查版本:
bash复制sealos version
能正常打印版本号就说明装好了,sealos 会被放到 /usr/local/bin 下。如果这个脚本因为网络问题拉不下来,也可以去 GitHub Releases 页面手动下载对应架构的二进制包,解压后放到 PATH 里即可。这里顺带提一句,Sealos 的命令行语法在不同大版本之间有些差异,我下面写的是当前 4.x 版本的行为,如果你用的是 5.x,记得对照官方文档微调参数。
3.2 确认要部署的 Kubernetes 版本
Sealos 把 Kubernetes 发行版做成了容器镜像,镜像标签就是版本号。执行下面的命令可以看本地已有的镜像,也可以查看 Sealos 镜像仓库里有哪些可用版本:
bash复制sealos images ls
测试环境我推荐选择比较稳定、社区使用量大的版本,比如 v1.25.x 或 v1.26.x,不要一上来就尝鲜最新版,也没必要死守旧版。这些版本经过大量验证,配套的 CNI 插件兼容性也更好。你可以在 labsealos.io 的镜像仓库页面查一下具体的标签是否存在,避免命令敲到一半发现版本号不对。
提示:Sealos 的镜像标签格式是
kubernetes:v1.26.5,其中包含的不只是 Kubernetes 核心组件,还预置了 pause、etcd、CoreDNS、calico 等依赖,所以单个镜像的体积不小,拉取时需要耐心。
3.3 执行单节点部署
这是整个流程的核心指令。单节点部署不需要像多节点那样列出 master 和 node 列表,直接用 --single 参数即可:
bash复制sealos run kubernetes:v1.26.5 --single
有些场景下机器存在多块网卡,比如既有内网又有公共网络接口,为了确保集群内部通信走正确的网段,更稳妥的方式是显式指定本机 IP:
bash复制sealos run kubernetes:v1.26.5 --masters 192.168.1.10 --single
如果 SSH 端口不是默认的 22,或者你要用密码认证,可以加上对应的参数:
bash复制sealos run kubernetes:v1.26.5 --masters 192.168.1.10 --single -p '你的密码' --ssh-port 22
执行之后,Sealos 会经历:解析镜像、拉取镜像、连接节点、准备容器运行时、初始化集群、安装 CNI 和 CoreDNS。整个过程耗时一般在五到十分钟,取决于镜像拉取速度和机器性能。期间会输出大量日志,看到最后出现类似 cluster installed successfully 的提示,就说明集群已经初始化完成。
部署完成后,我记得特别清楚,第一次跑通的时候整个人是有点懵的,因为 kubeadm 那套流程至少要手动配置十几项,而 Sealos 真的就是一条命令。
3.4 去掉 Master 污点,让 Pod 能跑起来
这里有一个单节点集群特别容易踩的坑。Kubernetes 默认会给 master 节点打上污点,普通 Pod 不会调度到 master 上。多节点集群无所谓,业务 Pod 可以放到 worker 节点;但单节点集群只有一个 master,如果你不处理污点,后面部署任何应用都会卡在 Pending 状态。
Sealos 单节点模式在某些版本里会自动处理污点,但你最好不要依赖这个行为,部署完先检查一下:
bash复制kubectl get nodes -o wide
kubectl describe node <节点名> | grep -i taint
如果看到 node-role.kubernetes.io/master:NoSchedule 这样的污点,执行下面的命令清除它:
bash复制kubectl taint nodes --all node-role.kubernetes.io/master-
注意:不同版本 Kubernetes 的污点 key 可能略有不同,新版本里可能是 node-role.kubernetes.io/control-plane。所以稳妥的做法是 kubectl describe node 看一下实际污点内容再操作。
去掉污点之后,单节点集群才算真正可用,业务 Pod 可以正常调度到这台唯一的节点上。
4. 拉取失败是测试环境第一坑:完整排查链路
4.1 先读报错信息,别急着跑路
网上搜 Sealos 相关的问题,出现频率最高的就是"sealos 拉取失败"。我自己的经验是,这个问题 80% 出在镜像拉取环节,而且报错信息五花八门,有 timeout、connection refused、manifest unknown、dial tcp ... i/o timeout 等等。很多人一看到英文报错就慌了,直接复制粘贴去搜索,结果搜出来的方案不一定对症。
我的建议是,先冷静下来,把报错最后几行完整读一遍。Sealos 的日志做得还算清晰,报错原因基本都会出现在末尾:
- 如果包含
Timeout、dial tcp、connection refused,大概率是网络或镜像仓库地址的问题; - 如果包含
not found、manifest unknown,大概率是镜像标签不存在或仓库里没有这个版本; - 如果包含
no space left on device,那就是磁盘空间不足,跟网络无关。
把报错归类之后再动手,排查效率会高很多。下面是我整理出来的四条排查路径,按概率从高到低排列。
4.2 排查路径一:镜像名与版本确认
拉取失败最容易被忽略的原因是:你的命令里写的镜像标签根本不存在。Sealos 的镜像仓库地址是 labsealos.io,它里面的镜像标签遵循固定的命名规则。你写 kubernetes:v1.26.5,仓库里得有这个标签才行。
我遇到过一次,同事把版本号写成了 v1.26.10,搜半天没有这个版本,最后发现官方只发布到 v1.26.4。这个错误很常见,因为 Kubernetes 的 patch 版本发布节奏快,不是每个 patch 都会被 Sealos 镜像仓库及时收录。
排查方法很简单:去 labsealos.io 的镜像仓库页面搜索下,或者看看 Sealos 官方发布说明里列出的版本列表。确认镜像标签存在之后再重试,别一上来就怀疑网络。
4.3 排查路径二:磁盘空间与文件系统
镜像拉取到一半失败,除了网络中断,另一个高频原因是磁盘满了。Sealos 镜像本身很大,加上拉取过程中临时文件,几十 GB 的空间很快就能被占满。尤其是那些跑过 Docker 又跑 containerd 的机器,/var/lib 下可能残留大量旧数据。
排查命令:
bash复制df -h
df -i
第一个命令看磁盘剩余量,第二个命令看 inode 是否耗尽。inode 耗尽是个隐蔽问题,df -h 看空间还有不少,但实际文件系统已经无法创建新文件了,拉取镜像自然失败。
如果确定是磁盘问题,清理掉无用的镜像和日志再重试。测试环境比较无所谓的做法是直接 sealos reset 后重新跑,但注意 reset 之前确认没有需要保留的数据。
4.4 排查路径三:网络与镜像加速
排除掉版本和磁盘问题后,剩下的大部分拉取失败都与网络有关。Sealos 默认的镜像仓库部署在境外或者访问链路上不稳定,国内机器拉取时经常超时。这个问题在测试环境特别明显,因为很多测试机网段出去绕绕绕,延迟高得离谱。
解决思路有几种。第一种是给 Sealos 配置一个可以正常访问的镜像仓库地址,通过环境变量或者配置文件切换。第二种是在局域网内部先部署一个镜像缓存或离线镜像仓库,Sealos 支持通过本地离线包的方式安装,这样部署时不再依赖外部网络。第三种是提前把所需镜像 sealos pull 到本地,然后用 sealos run --pkg-url 指定本地包。
提示:我这里提到的"镜像加速"是指配置容器镜像仓库加速服务,属于国内云厂商的标准能力,和特殊网络工具没有任何关系。你在实际操作时,优先考虑使用云服务商提供的镜像仓库加速地址,或者走公司内网的私有仓库。
4.5 排查路径四:残留状态清理
前三条路径都排查过了,还是失败?那很可能是之前部署失败留下了残留状态。Sealos 虽然宣称幂等,但如果上一次初始化进行到一半,比如证书已经生成、etcd 已经写入数据,这时中断,下一次执行可能因为状态不一致而失败。
我处理这种问题的标准动作是:
bash复制sealos reset
reset 会尝试清理已部署的集群状态。如果 reset 本身也跑不完,那就手动清理关键目录:
bash复制rm -rf /etc/kubernetes /var/lib/etcd /var/lib/kubelet
rm -rf /etc/cni /opt/cni
systemctl stop kubelet 2>/dev/null
清理完再重新执行部署命令。这条路径我几乎每次都能通过它收尾。
5. 一次单节点部署的完整救火记录
5.1 现象与第一反应
写到现在,光列排查路径还是有点抽象。我分享一次具体的救火过程,发生在给开发团队搭建一套带监控的测试环境时。
当时机器配置是 4C8G,系统 Ubuntu 22.04,命令执行:
bash复制sealos run kubernetes:v1.26.5 --masters 192.168.50.10 --single
命令跑起来后,日志卡在拉取镜像阶段,大概过了一分多钟,报 dial tcp ... i/o timeout。我的第一反应不是找网络问题,而是先确认镜像版本:
bash复制sealos images ls
确认 kubernetes:v1.26.5 在本地没有缓存,需要从远程拉取。然后测试仓库连通性:
bash复制curl -I https://labsealos.io
结果发现连接非常慢,偶尔超时。到这里基本定性:镜像仓库访问不稳定。
5.2 逐层定位:从 SSH 到 etcd 到 kubelet
我当时的解决思路是切换到一个可达的镜像仓库地址,重新跑部署。但为了排查更彻底,我同时检查了其他可能干扰的环节:
- SSH 链路是否正常:
ssh localhost echo ok,确认没问题; - 磁盘空间:
df -h,看到磁盘剩余 30GB,排除空间因素; - 残留状态:
ls /etc/kubernetes,发现目录不存在,说明没有历史部署干扰。
但即便确认了这些问题,重新用新的仓库地址部署后,又遇到了新的报错:kubelet 启动后节点状态一直是 NotReady。这次我没急着清理,而是先看 kubelet 日志:
bash复制journalctl -u kubelet -f
日志里看到 etcd 容器反复重启,进一步看 etcd 日志,发现是证书等待导致的:kubelet 或控制面组件在等待 etcd 的证书文件生成,而生成证书的步骤因为之前的超时没有完成。这个问题的根因还是第一次拉取镜像失败时留下了半成品状态。
5.3 修复与恢复
明确了根因之后,修复就变得很简单。先彻底清掉残留状态:
bash复制sealos reset
rm -rf /etc/kubernetes /var/lib/etcd /var/lib/kubelet
然后换用一个稳定的镜像仓库地址,重新执行部署命令:
bash复制sealos run kubernetes:v1.26.5 --masters 192.168.50.10 --single
这次镜像拉取顺畅很多,几分钟后集群初始化完成。再看节点状态:
bash复制kubectl get nodes
输出显示 Ready,救火成功。整个过程最有价值的一步其实是"把拉取失败和节点 NotReady 两件事拆开看"。第一次失败是网络问题,第二次失败是残留状态问题,如果混在一起找原因,很容易陷入死循环。
6. 集群就绪后:测试环境怎么用才顺手
6.1 快速验证的几组命令
集群 Ready 之后,我用这几组命令做常规体检,建议你也养成习惯:
bash复制kubectl get nodes -o wide
kubectl get pods -A
kubectl get svc -A
kubectl cluster-info
第一组看节点状态和 IP,第二组看所有命名空间的 Pod 是否 Running,第三组看服务是否正常创建,第四组确认集群控制面地址。如果都是正常输出,集群基本就是健康的。重点看一下 kube-system 命名空间里的 CoreDNS、calico、kube-proxy 是否 Ready,这几个组件有问题会直接影响后续应用部署。
6.2 部署一个测试应用
验证集群能不能用,最快的方式是部署一个简单的 nginx:
bash复制kubectl create deployment nginx --image=nginx:latest
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc nginx
拿到 NodePort 端口后,浏览器或 curl 访问:
bash复制curl http://192.168.50.10:3xxxx
看到 nginx 欢迎页,说明集群的网络、kube-proxy、Pod 调度全链路都是通的。这一步建议在每套新环境搭建完成后都做一遍,确认不是"看着 Ready 实际不可用"。
注意测试环境的镜像拉取同样可能遇到网络问题。你可以在部署前把常用的测试镜像 docker pull 或 ctr -n k8s.io pull 到本地,也可以给 containerd 配置镜像加速。我直接把测试环境常用的镜像列表固化到一个脚本里,随时重建环境后一键预热。
6.3 测试环境的备份与重置策略
测试环境最忌讳的是"像生产环境一样精心维护"。我的原则是:数据不重要,能快速重建最重要。所以我不做复杂的备份,而是做了两件事。
第一,把整个部署过程沉淀成一份可重复执行的脚本。包括系统配置、sealos 安装、部署命令、污点清理、镜像预热。下次需要一套新环境时,跑一次脚本,十分钟后就能交付。
第二,维护好应用部署的编排文件(Deployment、Service、ConfigMap 等),用 Git 管理。集群坏了就直接 sealos reset 重建,应用的 YAML 在 Git 里,重新 apply 一遍即可,不需要手工恢复。
这样做的收益是巨大的。开发来要环境,你不用想着"我这套环境里还有谁的数据、不能随便动",而是直接说"给我十分钟,我给你一套全新的"。真正做到随时能重建、坏了不心疼。
测试环境里我最常执行的管理命令是:
bash复制sealos reset
每次测试完,或者环境变得乱七八糟,直接 reset 回到干净状态,然后重新部署。这个流程在 kubeadm 时代是不可想象的,现在变成了日常操作。最后再分享一个小技巧,Sealos 装好的集群里,容器运行时的 crictl 命令也可以用,调试 Pod 拉镜像失败时很有用,别只盯着 kubectl。
