抢救 VPS 服务器
涛叔昨天晚上例行更新 VPS,更新后重启,重启后失联了😂博客、梯子、ChatGPT全部失效。今天早上折腾了一番终于给抢救回来了。记录一下抢救过程,供大家参考。
我的系统是 Ubuntu 22.04,原则上用新不用旧,所以我会时常运行 apt-get update/upgrade。因为更新比较频繁,所以每次有更新的时候需要更新的包都比较少。但昨天有异常,系统提示有一大片包需要变更1我没仔细看就按下了回车。因为有新版内核,所以我习惯性重启系统。然后就 ping 不通了。
首先我怀疑是服务商的问题,因为 Ubuntu 也算比较稳定的发行版,之前没碰到过升级系统出问题的情况。而且已经是半夜,我索性给服务商提了工单然后就睡觉了,等一手。
早上醒来发现问题依然存在。而且白天工作确实依赖梯子和 ChatGPT,所以等不及官方处理了。
我先在后台尝试使用 VNC Console,但发现 root 密码忘记了。也可能是没有设置。平时我都用 SSH 密钥登录,个人用户使用 sudo 也不需要输入密码,所以从来没有设置过 root 密码。
好在管理后台提供重置密码的功能。我重置了几次,都不生效2。于是我取消原来的工单,新提一个紧急工单,问为什么不能改 root 密码。但远水不解近渴,不能干等着。
后台无法重置那就想办法在 VPN 终端里重置。
首先在终端内重启系统(按 ctrl+alt+del),然后不停按 Shift 键,系统就会显示 GRUB 引导菜单。这个时候输入字母 e 就会打开类似 Nano 的编辑器,可以个性 GRUB 的启动配置。
找到启动 Linux 内核的配置(以 linux /boot/
开头的那行)并在最后面追加 init=/bin/bash
3。再按ctrl+x
或者F10
完成启动,系统会直接打开 bash 界面。
这个时候根文件系统处理只读模式,需要重新挂载为读写模式:
mount -o remount,rw /
最后运行passwd
命令修改 root 用户密码。完成后重启系统就能登录了。
理论很丰满,现实很骨感。我在自己的 VPS 试了很多次,都无法正常进入 bash 界面,每次都提示登录。感觉像是前面的修改没有生效。
仔细观察 GRUB 引导配置发现它有两个分支:
# ...
if [ "${initrdfail}" = 1 ]; then
echo 'GRUB_FORCE_PARTUUID set, initrdless boot failed. Attempting with initrd.'
linux /boot/vmlinuz-5.19.0-42-generic root=PARTUUID=XXX ro net.ifnames=0 biosdevname=0 console=tty1 console=ttyS0
initrd /boot/initrd.img-5.19.0-42-generic
else
echo 'GRUB_FORCE_PARTUUID set, attempting initrdless boot.'
linux /boot/vmlinuz-5.19.0-42-generic root=PARTUUID=XXX ro net.ifnames=0 biosdevname=0 console=tty1 console=ttyS0 panic=-1
fi
initrdfail
我只改了一个分支,可能导致不成功。两个分支都改了,还是不行。再仔细看,发现 VPS 每次启动的时候都会闪两次启动画面,应该是启动了两次。再看上面的引导配置,不难发现问题。
原来是 GRUB 会先尝试以不加载 initrd 镜像的方式直接启动一次,也就是 else 分支,如果不成功能再才加载。我们改的配置只在第一次启动生效,到第二次的时候还是用原来的配置引导。
所以我强行把 if 分支的 "${initrdfail}"
改为 "1"
,让 GRUB 直接直第一个分支。这次就打开 bash 界面了✌️
重置密码后重新启动,顺利登录系统。查看网络状态发现连ip
这个命令都没有了。应该是昨天升级的过程中删除了。又试了一下,发现ifconfig
命令还在,谢天谢地。
执行ifconfig
查看网络配置,只有一个回环网卡,压根就没有 eth0!我瞬间就慌了。不会是新内核不支持虚拟机的网卡或者升级的过程将驱动卸载了吧。如果真没有网,不但不能从外界下载数据,就连虚拟机内的数据也无法备份。
我首先怀疑可能是内核版本的问题。于是重启系统,使用老版内核启动,发现问题依旧。然后尝试查看 dmesg 日志,发现一个内核报错:
[ 4.245199] unchecked MSR access error: RDMSR from 0xda0 at rIP: 0xffffffffb7c9f598 (native_read_msr+0x8/0x50)
[ 4.245218] Call Trace:
[ 4.245220] <TASK>
[ 4.245222] kvm_arch_hardware_setup+0x1d7/0x240 [kvm]
[ 4.245252] kvm_init+0xb0/0x420 [kvm]
[ 4.245272] ? svm_hardware_setup+0x78a/0x78a [kvm_amd]
[ 4.245279] svm_init+0x26/0x34 [kvm_amd]
[ 4.245283] do_one_initcall+0x49/0x230
[ 4.245289] ? kmem_cache_alloc_trace+0x1a6/0x330
[ 4.245294] do_init_module+0x52/0x220
[ 4.245299] load_module+0xb56/0xd40
[ 4.245301] ? security_kernel_post_read_file+0x5c/0x80
[ 4.245306] ? kernel_read_file+0x245/0x2a0
[ 4.245311] __do_sys_finit_module+0xcc/0x150
[ 4.245312] ? __do_sys_finit_module+0xcc/0x150
[ 4.245314] __x64_sys_finit_module+0x18/0x30
[ 4.245315] do_syscall_64+0x5c/0x90
[ 4.245325] ? do_syscall_64+0x69/0x90
[ 4.245326] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 4.245333] RIP: 0033:0x7f6ae0d1ea3d
但我用老内核也有这个报错,感觉问题不在这里。 于是我有查看设备信息:
lspci |grep -i ETH
06:12.0 Ethernet controller: Red Hat, Inc. Virtio network device
发现系统能识别虚拟机网卡,问题不大。
ifconfig 没展示网卡信息可能是因为没有激活。使用ifconfig -a
尝试查看所有网卡,确实有输出 eth0。
这就好说了,我用 ifconfig 激活网卡并手工设置 IP 地址:
ifconfig eth0 up
ifconfig eth0 XXX.XXX.XXX.XX
ifconfig eth0 netmask 255.255.255.0
route add default gw XXX.XXX.XXX.XXX
让我一个常年使用 iproute2 的用户输入 ifconfig/route 命令直是煎熬😩但比没有强。
设置完成后就有网了,ping 8.8.8.8 通了。
然后尝试重新安装 iproute2 包,提示无法访问。这肯定是 DNS 解析失败了。手工修改 /etc/resolv.conf
文件添加:
nameserver 8.8.8.8
现在就可以正常安装了😄装好 iproute2 后重启系统,发现问题没有解决。可能还有别的包没有装。我印象中 VPS 都需要安装 cloud-init 组合。我的 VPS 管理后台中重置密码的页面也有如下提示:
Attention needed
To modify the settings in this section, it is necessary to properly install and run the Cloud-Init component within the instance.
于是我尝试执行apt-get install cloud-init
,还真有这个包。装好后重启,一切恢复正常了㊗️
以上就是整个抢救过程,希望能帮到大家。