K8s节点NotReady排查:重启后swap导致kubelet启动失败怎么办

重启之后发现集群里的节点全是 NotReady,第一反应肯定是去看 kubelet 的状态。systemctl status kubelet 打出来,发现服务根本没跑起来,一直在 restarting。再翻 journalctl 的日志,里面有一行非常眼熟:Running with swap on is not supported, please disable swap。那个瞬间,我就知道问题出在哪了:这台机器在关机之前 swap 是关掉的,但重启后系统又开始自动挂载 swap,kubelet 不认账,直接罢工。

这个场景在 Kubernetes 集群运维里太常见了,尤其是那种手动改了swapoff -a但没动/etc/fstab的节点。只要机器一重启,fstab 里的 swap 配置就会让系统重新把交换分区挂载起来。而 kubelet 在启动时检测到 swap 处于开启状态,就会拒绝启动。这篇文章把我实际排查和处理这个问题的完整思路写出来,从原理、临时修复、永久修复到验证,再到不同发行版下的差异化处理,希望能帮同样是刚接手集群的你少踩几个坑。

1. 重启后 swap 问题的现场与根因

1.1 kubelet 反复重启的报错现场

先说典型的报错现场。我那次的情况是:某台 worker 节点因为机房维护要重启,重启完以后,我用kubectl get nodes一看,节点状态是 NotReady。用kubectl describe node <node-name>看到的条件是KubeletNotReady,不少同事第一反应就是去看网络插件或者容器运行时,但其实很多时候问题就出在 kubelet 根本没起来。

更准确的判断方式是直接上节点看服务状态:

systemctl status kubelet

输出的前几行基本是:

Active: activating (auto-restart) (Result: exit-code) Process: 1234 ExecStart=/usr/bin/kubelet ... (code=exited, status=255)

然后你执行:

journalctl -u kubelet -n 50

日志里会出现类似这样的内容:

Failed to run kubelet: running with swap on is not supported, please disable swap! Or set --fail-swap-on=false to kubelet to allow running on swap.

只要看到这句,问题基本就锁定了。这句日志的意思是:kubelet 检测到系统开启 swap,默认不允许在这种环境下运行,除非你显式传入--fail-swap-on=false。默认情况下,它会直接拒绝启动,把这个开关关掉,才允许在开启 swap 的环境中运行。对于生产环境的集群来说,我建议默认保持关闭,也就是让 kubelet 继续拒绝 swap。

那为什么重启前明明关掉了 swap,重启后又会出现?原因就在/etc/fstab里。你执行swapoff -a只是把当前内存里的交换分区退出了,并没有修改系统的持久化配置。只要/etc/fstab里还写着 swap 那行,每次开机时 systemd 都会按照 fstab 的挂载表,把 swap 设备或 swap 文件重新激活。也就是说,你在重启前做的所有临时swapoff,重启后全部作废。这个“临时生效”和“永久生效”的区别,是理解这个问题的最关键点。

1.2 为什么 K8s 默认要求关闭 swap

既然要关 swap,那先搞清楚 Kubernetes 为什么这样设计。很多刚从传统 Linux 运维转过来的同学会觉得奇怪:服务器内存不够用的时候,swap 不是能兜底吗?为什么 K8s 反而要禁用它?

核心原因在于 Kubernetes 的调度和内存隔离模型。当一个 Node 上运行了很多 Pod 时,kubelet 通过 cgroups 为每个 Pod 设置内存限制,这个限制值来自 Pod 的 requests/limits 配置。调度器在做调度决策时,依据的是节点上可分配内存的总量,它假设 Pod 最多用到 limits 规定的数值,超过之后就会被 OOM Killer 选中杀掉,从而保护节点上其他 Pod 的内存使用。

但如果 swap 开着,情况就变了。一个内存超过 limits 的 Pod,它的内存页可以先被换到磁盘上,而不是立刻触发 OOM,Pod 不会像预期那样被清理。这就导致两个问题:一是调度器的内存假设不再成立,节点上实际的内存压力可能远超预期;二是 swap 的读写速度远低于内存,一旦疯狂换页,整个节点的性能都会大幅下降,而且很难定位到具体是哪个容器在拖慢系统。

用一个生活化的类比来解释:传统主机上 swap 相当于你有一个大仓库,内存满了就把暂时不用的东西搬到仓库里。Kubernetes 的内存模型更像是给每个房间(Pod)划了一块固定的储物空间,超了就腾空。如果你的房间里边放了一个无底洞柜子,超出的东西都堆到仓库去,整个大楼的物业就没法判断哪些房间超载了。

Kubernetes 从很早期开始就把“kubelet 不允许在 swap 开启的环境下运行”作为默认策略,一直延续到今天。虽然新版本已经陆续引入了一些 NodeSwap 相关特性,允许在可控条件下使用 swap,但默认策略始终是关闭,生产环境里我仍然建议严格保持 swap disabled。

2. 临时关闭和永久关闭的完整操作

2.1 临时关闭:swapoff -a 为什么只解决眼前问题

最快速让节点恢复的方法当然是先执行:

swapoff -a

这个命令的作用是立刻停用所有已经激活的 swap 设备。执行完以后,free -h的输出里 swap 的 Used 值会变成 0,而不会再占用空间。可以通过swapon --show来确认当前没有任何 swap 设备处于 active 状态,正常情况下这条命令没有输出,如果有输出就说明 swap 还在激活中。

然后重新启动 kubelet:

systemctl restart kubelet

这时候 kubelet 一般就能正常启动了,节点也会在几十秒后被标记为 Ready。

但是,我必须要强调:这一步救急可以,但它解决不了根本问题。你一旦哪天再重启机器,swap 又会因为 fstab 里的配置重新挂载,kubelet 又会死一遍。我在一个集群里就见过这种情况反复发生,值班的同学每次都是节点一重启就跑上去swapoff -a,后来被逼得写了一个开机自启脚本来执行这个命令。这种方案虽然能勉强维持,但是它绕过了问题根源,而且脚本执行时机如果晚于 kubelet 启动,还是会报错。真正的解法只有一个——从持久化配置里把 swap 灭掉。

2.2 永久关闭:修改 fstab 的三种可靠写法

要永久关闭 swap,核心操作就是处理/etc/fstab。fstab 是 Linux 系统开机时的挂载清单,里面每一行定义一个文件系统或交换分区的挂载方式。只要把 swap 那行移除或者注释掉,重启后系统就不会自动激活 swap 了。

在执行修改之前,强烈建议先备份原文件,这是一个不到一秒钟的操作,但能在你手滑的时候救你一命:

cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)

然后打开/etc/fstab:

vim /etc/fstab

在文件里通常会看到这样一行,不同系统下设备名可能不同:

/dev/mapper/centos-swap swap swap defaults 0 0

或者是:

UUID=xxxxx-xxxx-xxxx-xxxx swap swap defaults 0 0

或者是 Ubuntu 系统常见的 swapfile 行:

/swapfile none swap sw 0 0

把这一行直接删掉,或者在这一行的前面加一个#注释掉。我个人更倾向于直接注释,而不是删除,因为这样保留了一个还原的线索,万一后续你想重新启用 swap,把注释去掉就行,不用重新查设备的 UUID。

改完之后,为了让当前系统也保持关闭状态,再执行一次swapoff -a,然后用swapon --show确认没有激活的 swap 设备。

这里有几个需要注意的地方:

千万不要只看设备名。有些发行版的 swap 设备是用/dev/mapper/xxx-swap这种逻辑路径,也就是 LVM 逻辑卷。直接用设备名修改没有错,但如果系统有多个磁盘或者设备探测顺序发生变化,路径可能会不稳定。在 fstab 里最稳的写法是用 UUID,可以通过blkid命令获取:

blkid | grep swap

输出类似:

/dev/mapper/centos-swap: UUID="b3e5f2e1-...-..." TYPE="swap"

然后把这一行的UUID=写进 fstab。

还要当心一个比较低级的坑:有些人删 fstab 里的 swap 行时手滑,把根分区或者其他数据盘的那行也删了。重启之后系统直接进不了正常模式,只能进救援模式修复。所以每次改 fstab 前备份都是非常值得的操作。另外,修改 fstab 后建议先执行mount -a做一个模拟挂载测试,它会把 fstab 里所有配置重新挂载一遍,如果有语法错误或路径错误,大概率会在这一步暴露出来。

2.3 用 systemd 屏蔽 swap 设备,双保险

修改 fstab 是标准的永久关闭做法,但有些环境下,光改 fstab 还不够。比如某些云平台或安装了特殊初始化脚本的系统,开机后会有服务尝试自动挂载 swap 设备,或者 systemd 会根据设备文件自动生成.swap单元。这些情况下,即使 fstab 里没有 swap 行,重启后 swap 还是可能被重新激活。

一个额外的保险手段是用 systemd 的 mask 功能,屏蔽 swap 相关的单元文件,让系统完全忽略它们:

systemctl mask swap.target

这条命令会把swap.target单元链接到/dev/null,任何想启动 swap.target 的服务都会被无声地忽略。所以在 systemd 系统里,swap 相关的挂载操作就不会自动执行了。在一些使用 LVM 且存在多个逻辑卷的场景下,这个命令非常有用,它相当于从 init 层面把 swap 关掉,比单纯改 fstab 更接近“物理隔绝”的效果。

需要注意的是,systemctl mask并不能替代 fstab 的修改。如果 fstab 里明确写了 swap 行,systemd 开机时会生成对应的.swap单元,它的激活顺序可能与 swap.target 的屏蔽效果产生冲突,实际表现为重启后 swap 依然被挂上,或者出现启动时设备等待超时。所以在常规节点上,我建议先修改 fstab,再用 mask 作为辅助,两条腿走路,确保万无一失。

3. 重启后如何正确验证和恢复 kubelet

3.1 重启后检查 swap 状态的关键命令

既然是重启后出现的问题,那你处理完 fstab 之后肯定还希望做一次真正的验证:重启一次,确认 swap 不再出现,kubelet 能自动起来。在重启之前和重启之后,可以使用下面这套命令组合来快速检查:

检查当前内存和 swap 的使用情况:

free -h

重点看 Swap 这一栏,如果 Total 为 0,说明没有 swap 设备处于激活状态。

查看当前激活的 swap 设备:

swapon --show

没有输出就说明一切正常。如果想更明确地确认,可以用:

swapon -s

不过新版系统更推荐swapon --show。

查看 fstab 里是否还有 swap 行:

grep swap /etc/fstab

没有输出,或者所有匹配行都被注释掉了,说明持久化配置已经改干净了。

查看 systemd 中 swap 单元的状态:

systemctl status swap.target

如果是masked状态,说明被屏蔽生效了。我自己在验证时通常会把上面几条命令的结果全部确认一遍,然后才放心地让节点进入重启流程,因为一旦重启后发现问题,又要重新进入排查循环,一次能验证到位是最好的。

3.2 kubelet 启动顺序和节点状态恢复排查

节点重启完成后,我建议按照下面的顺序来排查,而不是一上来就开始敲命令。首先确认系统层面 swap 是关闭的,然后确认容器运行时是启动状态,最后再看 kubelet 是否运行正常。

先看容器运行时。现在的 K8s 集群大多使用 containerd 作为运行时,所以先确认它已经正常启动:

systemctl status containerd

如果 containerd 没起来,kubelet 即使自己启动了,也会一直报CRI v1 runtime API is not implemented或者连接不上 containerd 的错误,最终也表现为节点 NotReady。所以先把运行时服务拉起来。

然后再确认 kubelet 状态:

systemctl status kubelet journalctl -u kubelet -n 100 --no-pager

如果日志里没有出现 swap 相关的报错,而是正常显示连接的 API Server 地址、注册节点的信息,那就说明 kubelet 已经挺过去了。此时回到控制平面,重新执行:

kubectl get nodes

原本 NotReady 的节点会变成 Ready,可能需要等待几十秒到一两分钟,取决于网络插件和节点上已有 Pod 的恢复速度。

我还遇到过一种情况:节点显示 Ready,但上面之前运行的一些 Pod 一直处于 ContainerCreating 状态,查看 Events 后发现是磁盘或网络插件相关的报错。这种问题的原因往往不是 swap,而是节点重启过程中某些服务启动顺序不对或者挂载点失效。但为了排除 swap 的干扰,我仍然会先用free -h和grep swap /etc/fstab做一次快速确认,避免在错误的方向上花太多时间。

4. 不同发行版和版本场景下的差异化处理

4.1 CentOS 7 等旧系统上的设备名与 fstab 陷阱

CentOS 7 是很多生产集群还在跑的经典系统,这套系统有几个比较有特点的地方。默认安装时如果选择了带 swap 的磁盘分区,fstab 里很可能会看到类似这样的行:

/dev/mapper/centos-swap swap swap defaults 0 0

其中centos-swap是 LVM 逻辑卷的名称。修改的时候你会有两种选择:一种是直接注释这一行,另一种是把这里的硬件路径换成 UUID。在 CentOS 7 上,如果系统使用了 LVM,直接注释掉是最省事的,因为 LVM 逻辑卷的设备名一般比较稳定。但我见过某台机器上有多块磁盘,系统通过/dev/mapper/xxx-swap引用逻辑卷,一旦磁盘顺序发生变化,这个映射路径可能就会指到错误的地方去。所以最稳妥的方式依旧是blkid找出 swap 的 UUID,然后用 UUID 替换掉原来的路径。

CentOS 7 的另一个特点是默认的 init 系统是 systemd,它的.swap单元管理比较直接。如果 fstab 里注释掉了 swap 行,但你在机器上执行过mkswap或者某些安装脚本自动创建了/etc/systemd/system/swap.target.wants目录下的链接,重启后 swap 还是会被启用。所以遇到 CentOS 7 环境,我通常会把检查 systemd 下有没有残留的 swap 单元也纳入排查范围:

systemctl list-unit-files | grep swap

看看哪些 swap 相关单元的状态是 enabled,如果有,直接用systemctl disable或systemctl mask处理掉。

4.2 Ubuntu 上 /swapfile 的处理细节

Ubuntu 系统,尤其是云服务器和虚拟化环境里的 Ubuntu,默认经常使用 swapfile 而不是独立的 swap 分区。fstab 里一般是这一行:

/swapfile none swap sw 0 0

处理方式稍微有点不一样:你只需要注释掉这一行,然后用swapoff -a关掉当前 swap。但要注意,如果 swapfile 文件本身在根分区上,那么/swapfile这个文件一直占着磁盘空间。注释掉 fstab 后,文件不会被系统激活,但仍会占用磁盘空间,通常占用大小等于 swap 配置的内存大小,比如 2GB 的内存,就会占用 2GB 的/swapfile文件。

如果你确认这个节点永远不再需要 swap,可以把文件也删掉,腾出磁盘空间:

swapoff -a rm /swapfile

不过在删除之前要非常确定,一旦删掉,就只能在重新创建并重新启用的情况下才恢复。操作前先确认一下根分区的剩余空间,有些小磁盘的节点会因为这个文件空间不足而排不上 Pod。

Ubuntu 还有一种情况是使用 cloud-init 的云服务器,一些自定义的 cloud-init 配置可能会在开机时自动创建 swapfile。这种环境下你即使手动删了/swapfile并且注释了 fstab,下一次云服务器重启或者重新初始化时,swapfile 还是会被创建出来。解决办法是检查/etc/cloud/cloud.cfg里相关的配置,通常需要把swap: {filename: /swapfile, size: auto}这样的配置注释掉,或者使用cloud-init clean配合自定义脚本。不过这个偏向后文要讲的自动化运维范畴,手动节点上如果遇到这种问题,先搜一下 cloud-init 的日志:

grep -i swap /var/log/cloud-init.log

看看是不是 cloud-init 在背后搞的鬼。

4.3 新版 K8s 对 Swap 的策略变化,别一刀切

如果你接触的是比较新的 Kubernetes 版本,比如 1.28 及之后的版本,那你可能会看到 kubelet 的启动参数里多了--fail-swap-on=false这个选项的一些讨论。这个选项的作用是:允许 kubelet 在 swap 开启的环境中运行。为什么会有这个变化?因为社区认为在某些内存型应用场景下,完全禁止 swap 会让内存利用率变得很低,于是逐步引入了试点的 NodeSwap 特性。

在新版本中,如果你确实想用 swap,一般需要做三件事:开启节点的 Swap 特性门控、设置 kubelet 的--fail-swap-on=false、并且合理配置每个 QoS 等级的内存交换行为。但即使新版本允许了,我仍然不建议普通用户在生产环境里打开这个开关。原因很简单:swap 的启用会让内存使用率的监控和容量规划变得复杂,而且一旦节点内存压力过高,swap 抖动会带来非常难以排查的性能问题。

还有一种特殊情况是,有些集群管理员为了避免 swap 报错,直接在 kubelet 启动参数里加了--fail-swap-on=false,但它本质上只是让 kubelet 允许运行,并没有解决系统内存超卖时带来的风险。我见过有集群开着 swap 运行,平时没问题,一旦流量高峰,节点 load 飙到几十,Pod 全线卡顿。这种情况下排查来排查去,最后发现是 swap 在疯狂换页。所以面对这个选项,你要想清楚自己在做什么,而不是觉得“反正能跑就行”。

5. 常见问题速查与排错记录

5.1 问题速查表

这里把我在这个场景下遇到过的典型问题整理成一个速查表,方便你直接对号入座:

问题现象可能原因快速排查命令解决方式
kubelet 报错 running with swap onswap 设备在重启后被 fstab 重新挂载free -h、swapon --showswapoff -a后修改 fstab
swapoff -a 之后 swap 仍然占用有多个 swap 设备或 swap 文件cat /proc/swaps逐个 swapoff 对应的设备
重启后 swap 又出现fstab 没改干净,或 cloud-init 介入grep swap /etc/fstab注释掉 fstab 对应行,检查 cloud-init
修改 fstab 后系统无法启动误删了非 swap 的挂载行,或写错了 UUID进入救援模式检查 fstab用备份的 fstab.bak 恢复
kubelet 起不来但没有 swap 报错containerd 未启动或 cgroup 驱动不一致systemctl status containerd先启动运行时,检查 kubelet 的 cgroup-driver
节点 Ready 了但 Pod 一直 ContainerCreating网络插件或存储挂载问题kubectl describe pod查看 PVC、CNI 等事件

这个表格里的第一行和第二行是最常见的组合:节点上既有 swap 分区,又有 swap 文件,或者 LVM 里冗余挂载了两个 swap。执行一次swapoff -a确实会关闭所有激活的 swap,但如果某个 swap 设备在关闭之后又被某些服务快速重新挂载,你就会看到free -h里 Swap 的数值不为 0。这时候就需要逐个查看/proc/swaps,确定是哪个设备被重新激活。

5.2 三个我踩过的坑和对应的规避动作

第一个坑是改了 fstab 但没备份,然后整个节点启动失败。有一次我在一台测试节点上做永久关闭 swap,删掉 fstab 里的 swap 行时不小心多删掉了一行数据盘的挂载配置。重启后系统虽然没有进不了单用户,但数据盘没有自动挂载,导致 OpenEBS 这类依赖本地存储的组件直接挂掉。后来查了很久才发现是 fstab 被改坏了。从那以后,我养成了修改 fstab 前先cp备份的习惯,这个备份文件成了我的后悔药。

第二个坑是以为注释掉 fstab 就万事大吉,结果被 cloud-init 重新创建了 swapfile。某次在云平台上一台 Ubuntu 节点,我明明注释掉了/swapfile那一行,但节点重新初始化之后 swap 又出现了。后来查了 cloud-init 的日志,发现它的模块里配置了自动创建 swapfile,这个配置在/etc/cloud/cloud.cfg里,优先级比 fstab 更高。解决方案是要么改 cloud.cfg 里对应的 swap 配置,要么在初始化之后手动限定不启用该模块。如果你用的是云厂商的镜像,用私有镜像或者自定义用户数据脚本的时候,都要注意这个传承问题。

第三个坑是 kubelet 明明没有报 swap 相关错误,但节点依然 NotReady。后来发现这台机器的 kubelet 从默认的 cgroupfs 切换成了 systemd cgroup 驱动,而 containerd 还是 cgroupfs,导致两者不匹配。这个和 swap 没有关系,但我在排查重启问题时会遇到很多这种情况,尤其是节点重启后 containerd 先于 kubelet 启动时,驱动不匹配的报错会被日志淹没。所以看到节点 NotReady 时,先不要只盯着 swap 这一行,把 journalctl 输出的上下文完整看一遍,确认真正的失败原因。

6. 一键修复脚本和长期运维建议

6.1 带备份的一键禁用脚本

如果你管理的节点比较多,手动一个个改 fstab 会非常痛苦,而且很容易漏掉。我写了一个简单的脚本,把备份、禁用、验证这几个步骤串起来。你可以根据自己的环境调整,但总体思路是先把当前 swap 关掉,再注释掉 fstab 里的 swap 行,然后做一次验证。它是一个比较保守的修复脚本,因为多次执行也不会重复注释或者误删其他内容。

#!/bin/bash # 禁用 swap,包含备份和验证,适用于 CentOS 7+/Ubuntu 18.04+ # 使用方式: bash disable_swap.sh set -e # 1. 备份 fstab FSTAB=/etc/fstab BACKUP="${FSTAB}.bak.$(date +%Y%m%d%H%M%S)" cp "$FSTAB" "$BACKUP" echo "[INFO] fstab backup created: $BACKUP" # 2. 注释掉 fstab 中所有非注释的 swap 行 grep -q 'swap' "$FSTAB" || echo "[INFO] No swap entry in fstab, skip." sed -i.bak -E 's|^([^#].*[[:space:]]swap[[:space:]])|#\1|g' "$FSTAB" # 3. 关闭当前所有 swap 设备 swapoff -a 2>/dev/null || true echo "[INFO] swapoff -a executed" # 4. 验证 echo "[INFO] Current swap status:" swapon --show || true echo "[INFO] Swap lines in fstab:" grep swap "$FSTAB" || true # 5. 提示 echo "[INFO] Done. It is recommended to reboot to verify."

脚本里用到的 sed 命令会匹配 fstab 中以非#开头且包含swap的行,并在行首加上#。如果你 fstab 里的 swap 行写法比较特殊,比如使用none关键字,逻辑上也能覆盖,但建议先在自己的测试环境跑一遍再放到生产。

6.2 用配置管理工具固化这个改动

对于超过三台节点以上的集群,我真的建议把“禁用 swap”这一步放到初始化流程里,而不是在节点运行后手动修补。很多团队用 Ansible 管理节点初始化,那么你完全可以在 playbook 里加上这么一段任务:

- name: Disable swap immediately command: swapoff -a - name: Remove swap entry from fstab lineinfile: path: /etc/fstab regexp: '^.*\sswap\s+swap\s+defaults\s+0\s+0$' line: '# \g<0>' backrefs: yes - name: Mask swap.target systemd: name: swap.target masked: yes

这样新节点上线时就会自动完成禁用 swap 的设置。但要注意,不同发行版的 fstab swap 行格式不完全一样,比如 swapfile 那行和 LVM 那行就不一样,所以 Ansible 的 lineinfile 正则要根据你的系统来调整,不能只写一个通用版本就完事。比较好的做法是先在一个测试节点上跑一遍,确认所有节点类型的 fstab 都能被正确匹配。

另外还有一个建议是,加一个监控检查项。一个集群节点如果 swap 被意外启用,kubelet 在旧版本上会直接挂掉,但在新版本上如果你设置了 allow swap,节点可能不会马上暴露问题。所以可以部署一个 node_exporter 的 swap 相关告警,当节点出现 swap 时立刻通知值班人员。很多高可用集群的系统性风险,都是从这种看似不起眼的配置漂移开始的。

关于长期运维,我还有一个小小的体会:维护集群的时候,尽量让节点的初始状态可以重复构建,而不是用“这台机器改一个、那台机器改一个”的方式。比如当集群需要扩容时,新节点直接用平台镜像,配合初始化脚本完成 K8s 节点配置,里面就包含了禁用 swap 这一段。这样后续即使有人误操作改了 fstab,通过对比或者重新初始化也能很快恢复。你会发现,节点标准化在问题排查中带来的收益,远比配置时省下的那几分钟时间更值得。

回到 swap 这个问题上,它本身不复杂,但它揭示了一个运维真理:swapoff -a只是缓兵之计,真正要做的是一劳永逸地把持久化配置改干净,并且验证重启后不再复发。处理完再重启节点时,看到节点列表里所有节点都是 Ready,那个感觉还是很安心的。我最后一次处理这个场景的时候,还顺手在交接文档里写清楚了排查步骤,后面再有同事遇到,翻完文档十分钟就能处理完。这种能沉淀下来的经验,往往比一次性解决问题本身更有价值。

相关新闻

OpenClaw在Ubuntu 20.04上的容器化部署实战与避坑指南

OpenClaw在Ubuntu 20.04上的容器化部署实战与避坑指南

1. 写在最前面&#xff1a;为什么我决定写这篇部署笔记 先交代一下背景。我是在一台配置不算太高的 Ubuntu 20.04 服务器上折腾 OpenClaw&#xff08;就是我们常说的"龙虾"&#xff09;的&#xff0c;前前后后花了两三天才把整个环境跑稳。过程中踩的坑确实不少&…

2026/10/20 14:59:32 阅读更多 →
WiSparse实战:用权重感知的激活稀疏化加速LLM推理

WiSparse实战:用权重感知的激活稀疏化加速LLM推理

做LLM推理优化的朋友这两年基本都盯着一件事&#xff1a;内存带宽。尤其是decode阶段&#xff0c;每一个token都要把整个模型的权重和不断增长的KV cache读一遍&#xff0c;算力利用率经常连10%都不到。稀疏化一直被看作解药之一&#xff0c;但过去大家总觉得大模型里的SiLU/GE…

2026/10/20 14:59:32 阅读更多 →
分类任务实战指南:从数据准备到模型部署全流程解析

分类任务实战指南:从数据准备到模型部署全流程解析

分类任务是机器学习里最基础也最绕不开的一类问题。不管是图像识别、文本情感分析&#xff0c;还是用户流失预警、企业客户分群&#xff0c;绝大多数团队的第一个模型都是从分类任务开始的。这篇内容以我实际做过的一个模拟项目为主线&#xff0c;围绕分类任务从问题定义、数据…

2026/10/20 14:59:32 阅读更多 →

最新新闻

这6个底层技能,比学一堆工具更不容易过时

这6个底层技能,比学一堆工具更不容易过时

这6个“常用技能”&#xff0c;我一开始全理解错了。当时看项目标题“分享6个最常用的skill”&#xff0c;我第一反应是准备一份技术栈清单&#xff0c;甚至把某段时间特别火的几类工具关键词都列了出来。但和朋友聊完、又翻了几次项目正文之后才发现&#xff0c;真正的核心不是…

2026/10/20 17:34:07 阅读更多 →
工业控制系统安全工程师(CISP-ICSSE)全解析:报考条件、知识体系与职业价值

工业控制系统安全工程师(CISP-ICSSE)全解析:报考条件、知识体系与职业价值

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 17:34:07 阅读更多 →
Ruby重构机票电商平台:事务、缓存与高并发实战解析

Ruby重构机票电商平台:事务、缓存与高并发实战解析

简介&#xff1a;eyoo旅游机票电商平台重构版是一份基于Ruby技术栈的在线机票销售系统学习资源&#xff0c;适合希望掌握Ruby on Rails电商项目完整开发流程的开发者&#xff0c;用于研究业务建模、数据库关联、接口设计与部署方案。压缩包大小约2.62MB&#xff0c;当前标注文件…

2026/10/20 17:34:07 阅读更多 →
AI论文写作软件怎么用?专科生毕业论文从选题到答辩的实用指南

AI论文写作软件怎么用?专科生毕业论文从选题到答辩的实用指南

如果你现在手机相册里至少存了五张“学霸同款2026 TOP10 AI论文写作软件推荐图”&#xff0c;但论文还卡在“题目改了四遍都没定下来”&#xff0c;那这篇内容就是为你准备的。我不打算继续报一遍软件名字&#xff0c;因为真正决定你论文能不能顺利过关的&#xff0c;从来不是榜…

2026/10/20 17:34:07 阅读更多 →
2024最新Node.js下载安装与环境变量配置完整指南

2024最新Node.js下载安装与环境变量配置完整指南

如果你在前端、后端或者全栈开发这条路上待过一段时间&#xff0c;Node.js这个名字一定绕不开。它本质上是一个基于V8引擎的JavaScript运行时&#xff0c;把原本只能在浏览器里跑的JavaScript带到了操作系统层面。装上它之后&#xff0c;你可以用JavaScript写命令行工具、写后端…

2026/10/20 17:34:07 阅读更多 →
Ubuntu下PostgreSQL安装配置与Navicat连接指南

Ubuntu下PostgreSQL安装配置与Navicat连接指南

做后端开发或者数据相关工作的朋友&#xff0c;应该都经历过这么一幕&#xff1a;好不容易在 Ubuntu 上把 PostgreSQL 装好了&#xff0c;却发现命令行操作没问题&#xff0c;客户端工具却怎么都连不上&#xff1b;或者反过来&#xff0c;Navicat 装好了&#xff0c;连接时报一…

2026/10/20 17:33:06 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →