3月31日晚上 freeshell 升级内核通告

近一个月来 freeshell 经常有进程处于内核死锁状态,还出现了两次 kernel panic,严重影响 freeshell 服务的正常运行。我们准备在3月31日(周一)晚上把 freeshell 内核升级到 OpenVZ 官方发布的最新 RHEL-2.6.32 内核。(现在用的是 Debian squeeze 带的内核)

  • 时间:2014年3月31日 20:00 至 23:00
  • 预计时长:如果一切顺利,只需要重启一次机器,虚拟机停机 10~20 分钟(由于虚拟机启动是有顺序的)。如果遇到未知问题,虚拟机停机时间需要延长。
  • 影响:所有 freeshell 停机,控制面板的所有操作无效。

操作计划:

  1. 在 freeshell 首页挂上维护公告。
  2. 首先在一个节点上做实验:
    1. 备份 /etc。
    2. 添加 Debian wheezy 源,将主系统升级到 wheezy。
    3. 按照 官方文档 的说明,添加 OpenVZ 源(使用科大 mirrors 镜像)
    4. 安装 OpenVZ 内核和配置工具
    5. 检查 OpenVZ 配置文件中的路径(由于我们用的不是默认路径)和 grub 启动项
    6. 重启
    7. 检查虚拟机是否正常启动
  3. 第一个节点实验成功后再并行在其他节点上操作。

Update: 升级顺利结束。每个 freeshell 宕机时间大约是 15 分钟。升级过程中遇到一些小问题,都是之前维护的过程中留下垃圾导致的,现已清除。通过修改 sudoers 添加 “Defaults secure_path” 解决了 sudo path 问题。另外主机的 IPv6 路由在连上 OpenVPN 后有一些问题,已经解决。

新内核的版本是 2.6.32-openvz-042stab085.20-amd64,是 OpenVZ 官方最新发布的基于 RHEL-2.6.32 的内核。主机系统也升级到了 Debian 7.0 “wheezy”。

Freeshell 6、7号节点恢复

Freeshell 6号节点今天凌晨 4:07 宕机,7号节点昨天凌晨 4:37 宕机。这两台机器于今天 11:25 恢复。其中7号节点是操作不当导致必须强制重启,结果没有启动起来。6号节点是今天凌晨出现了 kernel panic,如下图所示。(kernel panic 原因未知)

IMG_20140328_091249

昨天中午12时机房同学对7号节点做了硬重启,今天上午9时机房同学对6号节点做了硬重启,但服务没有正常初始化。经查,问题是由于 /lib/modules/2.6.32-5-openvz-amd64/ 下的内核模块描述被破坏。这导致开机时的一连串反应:

  1. 由于 SSD 驱动未加载,7号节点上的 SSD 没有找到,/etc/fstab 中相应的 UUID 找不到,启动过程中进入了 maintenance shell,连网络都没有初始化,因此 ping 不通。
  2. 由于 tun 模块未加载,OpenVPN 服务没有启动。
  3. 由于 vzmon 模块未加载,OpenVZ 服务没有成功启动。
  4. 由于 conntrack 模块未加载,/etc/rc.local 中的 sysctl -p 执行失败(/proc 中对应的配置项不存在),rc.local 脚本退出,导致后续的网络路由命令没有执行。

内核模块描述为什么会被破坏呢?是因为我在写内核模块调试出问题的进程时,没有把内核模块放进 /lib/modules/2.6.32-5-openvz-amd64/,而是在当前目录下直接执行了 depmod `pwd`/module-name.ko,我的模块又没有依赖关系,能够 modprobe 成功。为了简单起见,我这些模块是通过 modprobe 参数来输入的,输出用 printk,执行完操作就马上 rmmod,包括 depmod 在内的操作都写在一个脚本里,因此当时没有发现问题。

事实上,我用的 depmod 命令已经把内核模块描述破坏了,依赖关系文件是空的(只有 header),模块列表文件只有我自己写的一个模块。正确的做法应该是把自己编译的 ko 文件放进 /lib/modules/2.6.32-5-openvz-amd64/,然后 depmod -a。修复方法也很简单,depmod -a 然后重启就行了。

除了6、7号节点,2、5号节点由于使用过我调试问题进程的内核模块,内核模块描述也被破坏了。这些节点如果重启,也会面临无法初始化服务的问题。

Freeshell HTTP proxy 40x, 50x 自定义错误页面

如下图所示,可以在控制面板的 HTTP Proxy 中设置。请注意 40x 和 50x 错误页面必须是完整的 URL,URL 中不支持中文和特殊字符。

Capture

40x 错误包括 400、403、404,50x 错误包括 500、502、503、504,其他类型错误仍然会返回默认 HTTP 错误页面。自定义错误页面采用 HTTP 302 跳转的方式。504 Gateway Timeout 的 TCP 连接超时是3秒,对学校内网来说应该够用了。

Freeshell 7号节点强制重启宕机

Freeshell 7号节点3月27日凌晨 4:40 宕机。技术细节如下。

7号节点有个虚拟机在 vzctl chkpnt –suspend 时卡死了。vzctl 和虚拟机内的一个 nginx worker 进程处于 Running 状态并各占用一个 CPU,导致8个核中的2个基本上一直处于内核态(因为没有关抢占,其他进程偶尔还是能用它们的)。其中 nginx worker 在 schedule() 里死循环。这比之前发现的内核死锁问题更恶劣,因为占了 1/4 的 CPU 资源。虚拟机内其他进程都处于 uninterruptible sleep 状态,这是正常的,因为 suspend 就是让进程进入 D 状态。估计是 vzctl 先给其他正在运行的进程发中断,让这些进程切换到 D 状态,此时 nginx 进程正在执行 schedule(),在只有自己一个进程可调度的时候出现了 bug 进入死循环,vzctl 只好等待这个进程进入 D 状态。

因为其他节点也有类似情况,我希望查清原因,就启动了之前写的用 strace 监控所有进程系统调用的脚本。脚本里有 ps aux,由于挂死的 nginx worker 进程的 process virtual memory 已经被锁住,ps aux 就进入 uninterruptible sleep 了。内层脚本用的是 timeout 命令,因此卡死的 ps aux 不会阻塞主程序的运行。又由于脚本尝试监控所有进程,而不死的 ps aux 被当作是新进程了,又有新的 ps aux 去“处理”它,就陷入了死循环,越来越多的 ps aux 被创建,直到 PID 空间(1~32767)耗尽。

随后一段时间当然无法执行任何命令,过了一会儿可能是某些正常的进程退出了,空余出几个 PID,于是新进程可以创建了。但由于 PID 空间是接近满的状态,一些需要较多子进程的服务已经不能启动,虚拟机重启后部分系统服务(如 ssh)也不能初始化。在尝试解开被锁住的内核信号量无果之后,必须强制重启了。

这种情况下 init 6 是不行的,因为有卡死的虚拟机,而 init 6 过程中会关闭所有虚拟机,关机过程会卡在那个永远关不掉的虚拟机上。因此只能用 magic sysrq 了:

echo 1 | sudo tee /proc/sys/kernel/sysrq
echo b | sudo tee /proc/sysrq-trigger

执行之后终端立即卡住不动了,ping 也在这时停止响应,证明 sysrq 立即生效了。不过不知道是由于什么原因,过了20分钟,还没有重启起来,ping 不通。要等白天去机房看了。

非常抱歉此事对 freeshell 7号节点用户带来的影响。

Freeshell 添加 Rescue/Copy/Move/Destroy 功能

由于未知内核 bug,最近一段时间有多个 freeshell 卡死。为此加入了 Rescue 功能。Rescue 的原理是把新建一个空的 freeshell,把数据复制进去,启动新 freeshell,再删除原有 freeshell 内的文件。Rescue 比较慢,仅仅是作为 last resort,能用 reboot 解决的问题还是 reboot 为好。

Capture

此外,有的用户辛辛苦苦在 freeshell 上“刷”了某个发行版或者搭建了一套开发环境,现在希望再建一个 freeshell 给其他项目使用。为此 freeshell 添加了 Copy 功能,可以把一个 freeshell 复制到任意一个物理节点上的新 freeshell。

有时由于其他人在跑高强度的计算,发现当前物理节点比较慢,怎么办?Move 功能可以把 freeshell 移动到任意物理节点。事实上 Rescue 的实现方式就是 Move 到自己所在节点。

最后,freeshell 不想用了,只能 reinstall 成空系统然后丢在那里白费磁盘空间吗?现在可以把它彻底 Destroy 掉了。由于这个操作比较危险,需要点击邮件中的确认链接才能执行。

如果您发现上述功能不可用或者行为异常,请及时联系我们。

Mirrors 遭遇拒绝服务攻击

3月20日 20:00 左右,mirrors.ustc.edu.cn 开始遭遇拒绝服务攻击,攻击强度不断加大,从3月21日凌晨 05:20 开始,造成 30 分钟左右的服务无法访问。攻击来源是一个电信IP,开了 181 个连接访问 rsync(202.141.160.110:873),峰值流量达到 110MB/s,不仅几乎占满了千兆网络,还给磁盘带来很高的负载,SSH 几乎无法登录。

解决方法是添加如下限速规则(来自 http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.ratelimit.single.html

$ sudo tc qdisc add dev eth0 root handle 1: cbq avpkt 1000 bandwidth 1000mbit
$ sudo tc class add dev eth0 parent 1: classid 1:1 cbq rate 100mbit allot 1500 prio 5 bounded isolated
$ sudo tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 183.60.244.74 flowid 1:1

其中第二行的 100mbit 表示限速 100Mbps,第三行的 IP 为攻击者 IP。

暂时没有找到自动对每个 IP 限速的方法。

学校网络故障导致 LUG 服务短暂中断

今天(2014年3月20日)下午 16 时,由于学校网络故障,电信出口中断约 10 分钟,移动出口也受到短暂影响。LUG 所有网络服务均受到此次事件的影响。据 BBS ustcnet 版,是教学行政楼内两台机器大量广播包侵袭校园网络核心设备,造成全校网络故障。

http://bbs2.ustc.edu.cn/cgi/bbstcon?board=USTCnet&file=M.1395306954.A