在旧 glibc 平台上运行 code-server

在旧 glibc 平台上运行 code-server

在旧 glibc 平台上运行 code-server

问题背景

由于工作需求,需要在 CentOS 7 上运行 code-server。最简单的是前往 coder/code-server 下载预编译的安装包。很不幸,直接运行报了如下类似的错误:

1
2
3
/lib64/libc.so.6: version `GLIBC_2.28' not found
/lib64/libm.so.6: version `GLIBC_2.27' not found
/lib64/libc.so.6: version `GLIBC_2.25' not found

很显然,这是由于 CentOS 7 的 glibc 版本过低导致的(参见 issue)。通过ldd --version可以得到 CentOS 7 的 glibc 版本为 2.17。为了解决问题,最简单的思路则是在 glibc 2.17 的环境下编译安装 code-server。

在 glibc 2.17 环境下编译安装 code-server 太过复杂了,你需要:

  • 一个为 glibc 2.17 编译的 node,参考 Node.js Unofficial Builds Project
  • 一个 gcc >= 12 且 glibc = 2.17 的容器环境。这个环境很苛刻!编译 gcc 相当费时间!
  • 按照 code-server 的文档对其进行编译;

并且有已知问题:

  • File Watcher 由于 SIGSEGV 无故退出;
  • 依赖高版本的 C++ 标准库;

因此我经过尝试,不建议你这么做。

灵光一现

经过一下午的思考,突然想到有一个哥们说过他尝试过升级系统的 glibc 但是把系统搞崩了,有没有什么办法可以让系统不被高版本的 glibc 影响,但是让 code-server 链接到高版本的 glibc 呢?诶,有的兄弟,有的。

我找到了这么一个工具:patchelf。顾名思义,他是用来 patch ELF 文件的(ELF 是 Linux 下的二进制格式),可以修改二进制文件的链接库、解释器、移除依赖、增加依赖等。

由于 code-server 整个都是基于 node.js 的,所以只需要我们把 code-server 所自带的 node 解释器给 patch 一下,让他链接到高版本的 glibc 即可。而 code-server 的 node 解释器在解压后也可以找到,在 lib/node 位置。

我们通过 ldd ./node 来看一下,能够得到类似于下面的输出:

1
2
3
4
5
6
7
8
9
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by node)
	linux-vdso.so.1 (0x00007ffe4cbd6000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6802109000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6801ca9000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f680190b000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f68016e8000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f68014c9000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f68010d8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f680230d000)

我们看到,node 链接到系统的 glibc (/lib/x86_64-linux-gnu/libc.so.6/lib64/ld-linux-x86-64.so.2)。

动手解决

编译 glibc

1
2
3
4
5
6
7
wget -c https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz
tar -zxvf glibc-2.28.tar.gz
mkdir glibc-2.28/build
cd glibc-2.28/build
../configure --prefix=/opt/glibc-2.28
make -j$(nproc)
sudo make install

请注意编译 glibc 对 make、gcc、binutils 等工具有最低版本号要求,请参考解压出来的 glibc 源代码里的 INSTALL 文件。

Patch Node 解释器

  1. 添加高版本 glibc 到 rpath:
1
patchelf --add-rpath /opt/glibc-2.28/lib node
  1. 修改解释器
1
patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 node

测试

运行 ./lib/node 看看正常不正常:

1
2
3
4
$ node
Welcome to Node.js v22.17.0.
Type ".help" for more information.
> 

看起来是对的!

再运行 ./bin/code-server 就可以顺利跑起来啦!

本文由作者按照 CC BY 4.0 进行授权

热门标签