1. 为什么我用 sealos 而不是 kubeadm 手工拼集群
先交代一下背景。我是运维工程师,最近半年被问得最多的问题就是如何在 Ubuntu 24 上快速搭一套 Kubernetes 集群。过去我一直用的是 kubeadm 手工部署:下载 kubeadm、kubelet、kubectl 三个二进制,然后 init、join、装 CNI、配 kubeconfig,三台机器怎么说也得折腾大半天。中间还得处理 apt 源、容器运行时、内核参数、镜像拉不下来的问题,每次都要走一遍。
后来接触了 sealos,一条命令直接把集群给我拉起来了,从零到能跑 Pod 大概不到十分钟。这个效率差距不是一星半点。
先说清楚一个概念:sealos 不是替代 Kubernetes 的东西,Kubernetes 集群本身还是那个 Kubernetes,节点上跑的还是 kubelet 和 containerd,API 也完全一样。sealos 是一个部署工具,它的作用是帮你把集群的整个搭建过程自动化,把以前手工执行的几十条命令封装成一个简单的动作。
sealos 背后做的是这样几件事:准备机器、分发二进制、生成配置文件、启动集群、把证书签好、把控制平面组件跑起来。用户看到的只有一个 sealos run 命令,但实际发生的是从空机器到可用集群的完整配置过程。
这类工具其实不少,除了 sealos,还有 kubeadm、kubekey、rancher、k3s、kind 这些。但在我实际用下来的体验里,sealos 有几个优势非常明显:
- sealos 把容器运行时(containerd)和控制平面组件作为镜像打包,可以提前下载好离线包,安装过程不依赖在线仓库,在服务器网络环境受限时尤其好用;
- 单机集群和 HA 集群都是同一条命令,只是参数不同,运维心智负担小很多;
- 自带负载均衡(lvs)方案,高可用场景不需要额外部署 keepalived + haproxy;
- 版本管理做得比较清楚,Kubernetes 的每个版本都有对应的 sealos 镜像,升级路径明确,后续要做版本升级,操作也比较简单。
我推荐 sealos 的一个具体理由是,它能让运维人员从纯粹的搭建动作里解脱出来,把精力用在业务侧。如果你的工作职责里经常出现“搭环境”这类的活,比如开发环境、测试环境、预发环境都要各来一套集群,sealos 的优势就很明显了。开发环境需要一套,测试环境需要一套,预发环境需要一套,每套环境都手工 kubeadm 一遍,光重复劳动就能把人逼疯。
这篇内容面向两类人:一是需要快速搭建 K8s 环境做学习验证的初学者,二是需要频繁交付 Kubernetes 集群环境的运维或研发工程师。我会把从 Ubuntu 24 系统初始化到集群跑起来的完整过程写清楚,包括每个环节的注意点和踩坑经验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Ubuntu 24.04 部署前的准备工作和几个容易忽略的细节
sealos 会负责主要的工作,但机器层面还是需要先做基础的检查。我假设你用的是 Ubuntu 24.04 Server 版本——注意,如果你在 VMware 里装的是 Desktop 版本,也不是不行,只是桌面环境会额外占用不少内存资源,跑在笔记本或虚拟机上做 AI 开发或平时学习测试,Server 版会更合适,资源开销更可控。
建议先确认好节点规划。我这次的示例环境是三台机器:一台作为 master,两台作为 worker。生产环境如果对可靠性要求高,master 节点需要奇数个,一般用三台或五台。三台 master 的情况下,虽然可以容忍一台宕机,但实际跑业务时为了保证 Worker 节点能正常调度,通常也会给 Worker 节点留足资源,具体怎么规划要看业务需求,这里涉及到的详细原理可以之后再展开。测试环境用一台机器同时做 master 和 worker 是完全可以的,sealos 支持“单机部署”模式,后面会说。
2.1 主机名、hosts 和固定 IP
每台机器先设置好主机名。主机名最好有区分度,比如 master01、node01、node02。不要偷懒让三台机器都叫 ubuntu,控制平面组件会对主机名比较敏感,主机名重复会导致节点注册混乱。设置方法:
bash复制sudo hostnamectl set-hostname master01
然后编辑 /etc/hosts,把三台机器的 IP 和主机名对应关系写进去。这一步不是必需的,但强烈建议做,避免后续节点间通过 IP 通信可能出现的网络问题。Kubernetes 的组件间通信会大量使用主机名,比如 kubelet 注册到 API Server 时上报的主机名,以及 etcd 成员间的通信配置,如果主机名解析不确定,可能会引发一些隐蔽的故障。
bash复制192.168.1.10 master01
192.168.1.11 node01
192.168.1.12 node02
固定 IP 可以通过 netplan 设置。Ubuntu 24.04 默认的网络配置工具是 netplan,配置文件在 /etc/netplan/ 目录下。如果你是在 VMware 或者其他虚拟化平台安装的,需要把网卡配置为静态 IP,否则 DHCP 分配的 IP 漂移会导致集群节点互相找不到。配置模板:
yaml复制network:
version: 2
ethernets:
ens33:
dhcp4: false
addresses: [192.168.1.10/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [114.114.114.114, 8.8.8.8]
应用配置用 sudo netplan apply。有个容易踩的坑是网卡名称,不同平台的网卡名不一样,VMware 一般是 ens33,Physical 机器常见的是 enp0s3 或者 eno1。先用 ip link 查看本机实际网卡名再配,这一点很重要。
2.2 防火墙:哪些端口需要放行
这一步经常有人忘记。安装完系统后,Ubuntu 默认的 ufw 防火墙是关闭的。但我见过有人在云服务器上自己装了别的安全策略。Kubernetes 集群内部组件通信会用到很多端口,如果防火墙拦截了这些端口,sealos 部署过程可能挂掉,而且报错信息特别难排查。通常表现为节点 Timeout 或 kubelet 无法启动。
核心要放行的端口:
| 组件 | 端口 | 方向 |
|---|---|---|
| API Server | 6443 | 所有节点访问 master |
| etcd | 2379-2380 | master 之间互通 |
| kubelet | 10250 | 所有节点互通 |
| kube-scheduler | 10259 | master 本机 |
| kube-controller-manager | 10257 | master 本机 |
| NodePort 服务端口 | 30000-32767 | 外部访问应用 |
如果你确定 ufw 是关闭状态,用 sudo ufw status 确认一下就行。如果是开启状态,直接把 ufw 关掉最省事:
bash复制sudo ufw disable
sudo ufw status
内部测试环境我一般就直接关了。生产环境需要按端口最小化放行,但这是后面的安全加固工作,和部署阶段分开。
2.3 内核模块和系统参数:确保网络转发和 iptables 规则正常
Kubernetes 的 kube-proxy 默认工作在 iptables 模式,容器网络需要开启 IP 转发。sealos 实际会自动处理大部分系统参数,但保险起见,我习惯先手动确认一遍:
bash复制# 加载 br_netfilter 模块
sudo modprobe br_netfilter
# 配置系统参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
这三个参数的含义是:前两个确保经过 Linux bridge 的流量能够被 iptables 规则处理,这是 Kubernetes Service 网络能正确转发流量的基础;第三个开启内核层的 IP 转发,让 Pod 网段的数据包可以在宿主机之间路由。bridge-nf 参数在比较老的内核上表现不明显,因为老内核默认可能就开了,但新内核环境下这些参数默认值可能不同,所以这一步还是花一分钟做完整为好。
2.4 安装 sealos
Ubuntu 24.04 上安装 sealos 非常简单,官方提供了一条脚本命令。在执行前需要注意版本差异:
sealos 的 v4 和 v5 在命令行接口上有一些差别。我们现在安装的是 v5 或 v5 以上的版本。v5 版本对镜像 tag 的管理更清晰,部署 K8s 集群时镜像名称的格式也更统一。官方快速安装脚本:
bash复制curl -fsSL https://raw.githubusercontent.com/labring/sealos/main/scripts/install.sh | sh
这个脚本会将 sealos 二进制下载到 /usr/local/bin,并自动配置环境变量。如果你的服务器无法直接访问 GitHub(这在国内环境很常见),可以用国内镜像源或用代理下载,或用apt源等替代方案。我提供一种更适合国内服务器的方式:
bash复制# 使用国内代理下载即可,比如从 sealos 官网或国内镜像仓库读取
wget https://mirrors.aliyun.com/sealos/v5.0.0/sealos_5.0.0_linux_amd64.tar.gz
tar -zxvf sealos_5.0.0_linux_amd64.tar.gz sealos
sudo install -m +x sealos /usr/local/bin/sealos
安装完成后验证版本:
bash复制sealos version
只要能输出版本号,说明安装成功。每次部署前我习惯先跑一下这个命令确认 sealos 二进制和 Kubernetes 镜像版本之间的兼容性。
3. 用 sealos 部署 Kubernetes 集群的完整过程
三台机器都准备好之后,进入正式部署环节。sealos 的部署方式有一个好消息:只需要在一台机器上执行命令,它会自动通过 SSH 连接其他节点执行操作,不需要每台机器都装 sealos。
3.1 部署前先搞懂 sealos 的镜像参数
sealos 集群部署的核心命令格式是:
bash复制sealos run [镜像名:版本] [节点IP地址列表]
我们在选镜像版本的时候不能太随意,要选一个和需求匹配的稳定版本。部署 Kubernetes 版本比较少的场景对特性要求不高时选 stable 版本,我这边线上用的环境一般选最新的稳定版。比如 kubernetes:v1.31.4。下面给出完整的部署命令示例。注意,有个问题是命令中的 master 和 node 的 IP 列表写法要非常注意,它不接受随意的参数,--masters 用于指定 master 节点,--nodes 用于指定 worker 节点。下面是部署 master 节点为 192.168.1.10,worker 节点为 192.168.1.11 和 192.168.1.12 的示例:
bash复制sudo sealos run kubernetes:v1.31.4 \
--masters 192.168.1.10 \
--nodes 192.168.1.11,192.168.1.12
命令会提示你输入 SSH 密码。注意 sealos 默认使用 root 用户登录,如果你的系统只允许用普通用户,需要预先配置好 sudo。sealos 也支持配置 SSH 密钥登录,这需要在命令行参数里指定,也可以在 root 权限下直接发起。考虑到 SSH 密码登录容易被 Linux 服务器自身安全策略限制,我这里采用的也是这个配置,但前提是我实践环境的 SSH 密码策略能保证登录成功。
这里有一个常见疑问:为什么部署集群只需要执行这一条命令?sealos 框架内部做了哪些工作?我大致介绍一下流程,便于出了问题你自己知道怎么排查:
- sealos 先将 master 节点列表上的所有机器通讯,写入 hosts(如有需要);
- 分发 Kubernetes 离线镜像包到各个节点,解压后重组出所需二进制文件和镜像;
- 通过生成的配置文件启动 kubelet 和容器运行时组件;
- 在 master 节点上初始化控制平面,等待它 ready,安全证书,组件部署完成;
- join worker 节点,加入集群。
由于安装过程是一个流式任务,执行完后 sealos 会在终端里输出进度和结果。如果输出显示 successful,那么恭喜你,集群已经搭好了。整个过程大概需要五到十分钟,视机器性能和网络情况而定。
3.2 单机部署的特殊情况
有时候只是为了实验或学习,希望在一台机器上跑完整的 K8s 功能,这时可以用单机模式部署。sealos 里单机部署和集群部署的唯一区别是 master 和 node 可以都是同一台机器:
bash复制sudo sealos run kubernetes:v1.31.4 \
--masters 192.168.1.10 \
--nodes 192.168.1.10
因为 master 和 worker 共用一台机器,资源占用会显著增加,如果机器内存少于 4G,控制平面组件加上业务容器的压力会比较大,尽量把内存升到 4G 以上,8G 最佳。这里提醒一下,不要在 master 节点上跑太多负载,master 需要预留资源给系统组件,而且控制平面压力过高对集群稳定性不友好。
如果需要部署单节点集群而不希望 master 参与业务调度,也可以只写 masters 参数不写 nodes 参数,视情况安排污点。sealos 默认会给 master 节点加上了 taint,禁止业务 Pod 调度上去。如果你在单机部署时希望这台机器也能运行业务 Pod,可以手动去除 master 的 taint:
bash复制kubectl taint nodes --all node-role.kubernetes.io/control-plane-
注意 taint 去掉后你相当于在控制平面节点上跑了业务,在生产环境要谨慎考虑。
3.3 部署完成后,第一件要做的事:验证集群健康状态
集群部署完成后,需要做基础验证。首先查看节点状态:
bash复制kubectl get nodes
节点状态输出应全部为 Ready。然后看系统组件的运行状态:
bash复制kubectl get pods -A
正常情况下 kube-system 命名空间下的所有 Pod 都应该是 Running 或 Completed。如果你用 sealos 部署,容器运行时预先集成了 containerd,不会用到 docker。
这里必须说明一下 k8s 和 docker 的区别:Kubernetes 是一个容器编排平台,它本身不直接运行容器,需要借助容器运行时(Container Runtime Interface)比如 containerd 来运行容器。Docker 只是众多面向用户的容器工具之一,其内部其实也依赖 containerd。所以用 sealos 时不要求你安装 docker,它会自动安装 containerd。
除了查看集群状态,还建议验证一下集群网络是否正常。先创建一个临时部署:
bash复制kubectl create deployment nginx-test --image=nginx
kubectl expose deployment nginx-test --port=80 --type=NodePort
kubectl get svc nginx-test
通过 NodePort 暴露的端口(30000 之后),在外部浏览器访问 master IP:端口,能看到 nginx 的欢迎页,说明集群基本功能正常。
3.4 如果要在集群里部署 LNMP 应用或 Nginx + MySQL 这类场景怎么调整
根据热搜词,很多人都关心“在 k8s 集群中部署 nginx mysql”或者“k8s 部署 lnmp”的场景。这里简单补充一点:集群搭好后往上面部署 Nginx、MySQL 这类中间件,面临的挑战和 sealos 无关,主要取决于你如何管理配置。
有一个关键点是,部署 MySQL 这类有状态应用时,不建议直接用普通 Deployment 的方式,因为 Pod 重启后数据会丢。推荐的做法是把数据库部署为 StatefulSet 格式,每个实例绑定独立的持久卷声明(PVC),数据独立且可恢复。Nginx 这类无状态应用则用 Deployment + Service 即可,扩缩容很方便。
举一个最小化示例,部署一个 MySQL,并让它通过 ClusterIP 在集群内被访问到:
yaml复制apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
这里不深入 LNMP 的全部细节,但要意识到走上 K8s 后,容器和编排的设计模式与裸机环境差别是比较大的,有必要接着学习一下 Pod、Deployment、Service 等基本概念。
4. sealos 生成的集群如何运维与后续操作
跑起来只是第一步,日常维护和扩容才是更多的工作重点。这块内容我会讲一些实际操作中的经验。
4.1 添加新的 Worker 节点
如果集群资源不太够,新增节点不需要重新部署一遍。sealos 提供了单独命令,把新节点加到已有集群。需要在原 master 节点上操作:
bash复制sealos add --nodes 192.168.1.13
当然了,目标机器也要预先满足了系统基础环境要求(IP 设置、hosts、防火墙等)。这里 sealos 会自动将新节点注册到集群并安装必要组件。完成后用 kubectl get nodes 查看,新节点状态如下显示 Ready。
新增的节点如果用完了也就不再需要重复执行 join,kubelet 启动后会自动连接 Control Plane,以后永久留在集群里。如果是在内部机器之间加节点,IP 能通,SSH 密码有,这种方法能够直接用。
4.2 添加新的 master 节点(涉及 HA,有注意事项)
部署高可用集群时,master 一般从 3 台起步。如果你想在已有单 master 集群上扩展为多 master,和加 worker 的用法类似,只是参数要写 --masters:
bash复制sealos add --masters 192.168.1.20
这个过程中 sealos 会处理 etcd 成员的添加操作,并在多台 master 之间自动部署 lvs 实现负载均衡。比起手工把 etcd 新成员加进去、改 kube-apiserver 配置、还有证书分发,省事多了。我手工 kubeadm 搭 HA 时要手动改一堆配置,用 sealos 的话扩 master 通常也是在几分钟内完成。
4.3 删除节点
下线机器时用 delete 命令,可以联合清理对应的组件:
bash复制sealos delete --nodes 192.168.1.13
注意子命令的用词是 delete 而非 remove。实际执行后,sealos 会先排空节点,然后移除相关服务,执行成员退出等操作。常规集群中要下线一个 worker,可以先线上 kubectl drain 手动将其排空,再用 sealos 或直接 kubeadm reset 清理。不过这些步骤本身可学性不强,直接使用 sealos 即可把节点清理干净。
4.4 集群升级与配置追加
sealos 的 run 命令除了可以部署集群,也可以作为执行证书更新或调集群组件版本的入口。执行同一镜像的命令,在已有集群中会更新对应组件,用来做小版本升级非常方便:
bash复制sealos run kubernetes:v1.31.5
如果原来跑的是 v1.31.4,执行上述命令会完成对 master、node 的版本迁移。需要提前查一下新版本和 sealos 版本是否兼容。但升级前建议先备份 etcd,这是所有 K8s 运维工作里的硬性原则。etcd 里存着集群几乎全部状态数据,一次失败的升级操作可能损失整个集群状态,备份会减少自己手忙脚乱的机会。
5. sealos 的工作原理和底层细节
用熟了之后,了解工具背后的原理对排查问题会很有帮助。
5.1 sealos 的离线镜像机制是核心
用过 Docker 的人应该对镜像不陌生,但 sealos 的“镜像”概念不等同于容器镜像。sealos 镜像是一个携带特定内容的文件系统层,内部包含创建 Kubernetes 集群所需的一切文件,例如二进制、yaml 配置文件、etcd、kubelet、kubeadm、cni 及各组件镜像。封装后可以直接导入节点、解压为本地所需内容。
所以整个机制就是:sealos 先从镜像仓库拉取 kubernetes:v1.31.x 镜像(这是 sealos 自定义的格式),然后作为一个整体包分发到各个节点。每个节点拿到镜像后像执行安装脚本一样,把本地文件系统和容器系统跑出来。分发效率上,由于有镜像层复用机制,比逐台慢跑要快很多。
另外 sealos 可以做集群数据备份和恢复。它提供类似 sealos backup、sealos restore 的命令,可以生成集群状态快照。生产环境我用过,确实有用,虽然实现原理跟很多备份工具类似,但集成在一起还是很方便。平常想备份数据也可以用 etcd 快照,命令为:
bash复制ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%F).db \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
5.2 containerd 是 Kubernetes 调用容器的具体路径
在容器编排层面,Kubernetes 本身没有能力直接创建容器,它需要一套可协商的标准调用接口,也就是 CRI(Container Runtime Interface,容器运行时接口)。kubelet 作为节点上负责和容器运行时打交道的组件,通过 CRI 调用程序的 socket 地址,一般是 /run/containerd/containerd.sock。containerd 收到请求后,再通过 containerd-shim 来初始化和运行容器进程,例如调底层 runc 来创建 namespace、cgroup。
整体链路是这样:
code复制kubelet -> CRI (gRPC) /run/containerd/containerd.sock
-> containerd -> containerd-shim -> runc
-> 容器进程(在独立的 namespace 和 cgroup 中)
这个架构里的关键是,k8s 和 docker 的关系很容易被初学者误解:kube-apiserver 甚至不直接管具体的容器运行时,docker 在容器生态中有多少地位取决于你用的是哪种 runtime。如果你用 docker 作为容器运行时,那么 kubelet 会通过 dockershim 调用 Docker,docker 再去调用 containerd。为了减少中间环节,直接用 containerd 作为运行时的架构更符合现代化部署方式,sealos 默认就是这样的。所以用 sealos 部署后,如果你想看一下节点上的容器,需要用到 crictl 命:
bash复制crictl ps
crictl logs <container-id>
如果你习惯了 docker ps 会觉得不太适应,但本质上都一样,只是换了一个客户端。
5.3 sealos 和 kubeadm 的关系
这个问题常被问到:“sealos 是不是包装了 kubeadm?”对的,早期版本,sealos 会把 kubeadm 配置文件生成好然后调用 kubeadm 来做 init 和 join。但是后续版本已经逐渐将 kubeadm 合并到自身二进制里,用 controller 框架实现。可以理解为 sealos 把系统初始化、证书管理、镜像导入、集群 main 流程自动化,kubeadm 要是觉得复杂处理不了的事,sealos 将 controller 编排任务用自己的方式处理。
这也意味着你不用在节点上自己安装 kubeadm。我们要在自己的环境选择用 sealos,这就解决了非常明显的问题:传统方案中,每台节点都要先装 kubelet 和 kubeadm,如果在国内还得处理镜像仓库的问题。sealos 通过离线镜像避免了源和仓库不可达的坑。
5.4 常见排查思路
虽然 sealos 报错率已经很低,但遇到问题我们还是要有一个健康的排查路径。我按踩过坑的频次拍一下顺序:
(1)SSH 连不上其他节点。 最常见的报错是 failed to connect,通常因为没有用 root 用户或 SSH 密钥未配置成功。先检查一下 master 是否能免密登录到其它机器:
bash复制ssh root@192.168.1.11
如果可以免密,sealos 就不会询问密码。若是密码登录,使用 --passwd 参数一次性传入也能用。
(2)DNS 解析不到镜像或普通镜像拉取超时。 部署的时候如果执行到某一步卡住或失败,终端会显示 pull image 超时的错误信息,那大概率是镜像网络拉不下来。这种情况可以在部署前用 sealos 离线包,或手动在每台机器的 /etc/hosts 里写好相关域名映射,将程序来源固定。
(3)节点一直 NotReady 状态。 多是因为网络组件没有成功安装。sealos 只是安装 Kubernetes 核心组件,默认不会安装 CNI 插件。你可以用 sealos 直接跑一个网络插件的镜像:
bash复制sealos run calico:v3.28.1
或者手动用 kubectl apply 部署 Calico、Flannel 等。强烈提醒一下:如果节点是 NotReady,先执行 journalctl -u kubelet -f 或 crictl ps -a 看容器启动情况,能看到具体报错,网络上或配置文件上出问题一般都会体现出来。
(4)Pod 能创建但无法跨节点通信。 这种一般是 CNI 配置错误或者 bridge-nf 内核参数没开。回到第二节的 sysctl 项检查一下。
(5)如果想要在生产环境用 sealos 的命令,不要忘了安装一个持久化存储方案和 Ingress Controller。 sealos 在设计上是不带这些的,是要你自己作为选件加入集群的。可以把它们理解为跑业务应用的基础设施,缺少状态存储的集群适合无状态场景。
6. sealos 部署常见报错与解决实战记录
把部署过程可能遇到的问题单独开一节来说,对实际动手的人帮助最大。
6.1 反复要求输入密码且认证失败
有的场景,用户执行 sealos run 后,明明密码输入正确,但仍然一直报 Permission denied。我最终发现是在 Ubuntu 24.04 中,默认的 SSH 服务禁止 root 直接登录。Ubuntu 的安全策略默认禁用 root 密码 SSH 登录,需要在每台目标机器上修改配置文件:
bash复制sudo sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
sudo systemctl restart sshd
然后用 passwd root 为 root 设置一个密码。建议给 root 用户设密码的方式在各节点都是一致的。
这个操作对云服务器要注意端口安全组不要开放 22 给所有人,内部测试机问题不大,公网生产服务器最好用密钥登录,并且禁止密码登录,避免暴力破解。
6.2 内存不足导致 etcd 或 kubelet 不断重启
如果在虚拟机里配置内存过小,比如 2G 或者更小,sealos 看起来执行完成了,但过了一会儿节点就 NotReady,看 kubelet 日志是内存不足。这种资源问题用工具很难根治。
我做过实验,Kubernetes 1.28 以后对系统预留资源的内存计算更严格,如果内存总数小于 2G,非常容易触发 OOM。建议 master 节点测试机最低 4G 内存,work 节点单机部署业务机 4G 足够跑小项目,但要稍微跑重负载业务建议 8G。
如果你是 VMware 上开的虚拟机,直接在虚拟化平台的设置里加内存即可,加完内存之后,重启节点,再 kubectl get nodes 验证状态。
6.3 Ubuntu 24.04 系统版本兼容问题
sealos 官方在 Ubuntu 22.04 到 24.04 之间都做过测试,兼容性问题不大。但是有些与低版本内核相关的配置要自己注意。比如很多老教程让你开启 swap,Ubuntu 24.04 默认安装有时启用 swapfile。Kubernetes 从 1.28 开始支持 swap,但默认配置不使用,且 kubelet 若检测到 swap 会直接拒绝启动。
安全的方式是关闭 swap:
bash复制sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
执行完后运行 free -h 确认 swap 使用量为 0。不同版本的节点都要逐个关掉,避免 kubelet 在某些节点上失败导致集群不稳定。
6.4 这个步骤报错: Runtime connect failed: ... /run/containerd/containerd.sock
这种错误一般发生在手动执行 crictl 的时候,或是某个组件无法和 containerd 通信。如果集群本身正常,可能是环境变量的问题。Kubernetes 社区通常把一个 crictl 配置放在 /etc/crictl.yaml:
yaml复制runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
如果没有这个文件,直接手动创建然后重试即可。你在搭完集群后能顺利执行 crictl ps 是后续排查的一个很友好前置条件。
6.5 镜像拉取卡在 ImagePullBackOff
节点已经 Ready 了,但是某一个应用 Pod 一直 ImagePullBackOff。这种情况经常跟 sealos 没太大关系,纯粹是镜像名称写错或者镜像仓库没有权限。用 kubectl describe pod <pod-name> 查看事件,能够看到比较具体的报错。常见原因不外乎:
- 镜像标签写错了(nginx:lest 这种拼写错误);
- 拉取私有仓库的镜像没有配置 imagePullSecret;
- 节点本地无法访问外部镜像仓库,检查 DNS 或配置镜像加速。
可以参考如下配置为 containerd 配置镜像加速,其实就一步。编辑 /etc/containerd/config.toml,在 [plugins.'io.containerd.grpc.v1.cri'.registry] 段下配置 mirrors。很多国内服务商提供镜像源加速服务,比如 docker.m.daocloud.io 或其他云厂商内部加速地址,要在 /etc/containerd/config.toml 加上加速配置后重启 containerd:
bash复制sudo systemctl restart containerd
加完以后重新创建 Pod,ImagePullBackOff 的问题大概率能解决。
7. 后续学习路线和运维平台扩展建议
集群部署完成意味着你已经具备了一个非常方便的实验环境,后面的路怎么走跟学不学得好关系很大。
Kubernetes 的学习曲线比较陡峭,但一旦跑起第一个集群,顺着下面几个方向去啃,会每天都有新收获。建议新手按照下面的顺序去接触:
- Pod、Deployment、Service、Ingress 四种资源:把无状态应用怎么发布、怎么暴露到外部搞明白;
- ConfigMap、Secret、PVC:学会把配置和存储从应用镜像中剥离出来,这是容器化改造的重要一步;
- StatefulSet:用有状态应用(数据库、消息队列)试验,感知 K8s 调度有状态应用的复杂性;
- RBAC 和命名空间:模拟多团队共享集群时怎么隔离权限;
- Helm:用包管理方式部署复杂应用,效率高很多;
- Operator:理解控制器模式,这也是 K8s 扩展能力最强大的地方。
运维平台方面,建议搭建监控告警体系。结合热搜词涉及的内容,很多人已经在关注 node-exporter、prometheus、grafana 是怎么集成到 K8s 的。用 sealos 部署 K8s 之后再搞定监控,正常情况下可以做到:
bash复制# 使用 helm 直接安装 prometheus 生态
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring
安装完成后,Grafana 会自带 k8s 的监控面板,默认用户名密码一般是 admin/prom-operator。磁盘告警规则这类内容如果要配置,需要在 PrometheusRule 资源里面定义 alert 规则,比如磁盘使用率超过 80% 触发告警,node-exporter 采集到数据由 Prometheus 规则评估,最后推到 Alertmanager。Kubernetes 监控相关的告警规则可以做成一条例子供你参考:
yaml复制apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: node-disk-alerts
namespace: monitoring
spec:
groups:
- name: node.disk.rules
rules:
- alert: NodeDiskUsageHigh
expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 磁盘使用率超过 80%"
Dashboard 方面,很多教程都让安装 Kubernetes Dashboard,但其实日常运维中我更多用的是命令行加 k9s 工具,界面比 Dashboard 更轻量。如果你想把 Dashboard 装上也行,sealos 部署完后直接跑镜像即可。
这一整套下来,你已经从一个手工搭 K8s 集群的人,变成了一个能把 K8s 集群自动化交付和监控运维的人。后面如果再进一步,可以做 GitOps 流程,把应用部署也自动化起来。K8s 是个非常大的世界,sealos 只是万里长征第一步,但这一步走得顺利,后面所有事情都会变得舒服很多。
我在实际运维中的体会是,部署方式的选择往往决定了后续环境的整洁程度。sealos 把最繁琐的步骤消化掉了,哪怕你只用它搭建一套最小集群,我也建议先完整走一遍部署流程,再自己去尝试 kubeadm 手动部署,你才能对比出自动化工具的价值到底在哪里。等两套流程都跑通,Kubernetes 的架构就会在心中越来越清晰。
