通过VSCode远程连接到CentOS7/Ubuntu18等老系统
通过VSCode远程连接到CentOS7/Ubuntu18等老系统
背景
VSCode的远程连接插件Remote SSH一直以来是简单好用的远程工具。然而,2025年2月之后的版本在远程安装vscode-server时,预编译的server依赖glibc 2.28,这就要求Linux远程机的glibc版本应不低于2.28,进而导致CentOS 7(glibc版本2.17),Ubuntu 18(glibc版本为2.27)都无法再使用VSCode的Remote SSH插件远程。
本文介绍两种解决方案:一是使用老版本VSCode;二是打补丁方案。
1. 最简单方案:换老版本VSCode(<=1.85)
请参考知乎文章
2. 补丁方案
该方案的操作流程如下:编译Crosstool-ng工具,并设置环境变量;下载.config文件,编译glibc2.28;配置sysroot环境变量;下载/编译安装patchelf供VSCode调用;
编译Crosstool-ng工具
根据VSCode官方推荐,使用Crosstool-ng编译新版本的glibc、gcc等工具链。
在Ubuntu系统运行以下命令以安装依赖项:
sudo apt-get update
sudo apt-get install -y gcc g++ gperf bison flex texinfo help2man make libncurses5-dev \
python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip \
patch rsync meson ninja-build
而在CentOS系统需要使用yum install命令,不再赘述(注意CentOS与Ubuntu依赖库的名称也有所差异)。
然后下载Crosstool-ng
源码,解压、配置、编译、安装:
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.26.0.tar.bz2
tar -xjf crosstool-ng-1.26.0.tar.bz2
cd crosstool-ng-1.26.0 && ./configure --prefix=/crosstool-ng-1.26.0/out
make
sudo make install
后续使用ct-ng
命令之前,需要配置环境变量:
PATH=$PATH:/crosstool-ng-1.26.0/out/bin
方便起见,可以将这一句命令添加到~/.bashrc
中。
编译glibc2.28
完成Crosstool-ng
的编译安装和环境变量设置后,便可以在bash中调用ct-ng命令了。
为了编译glibc2.28工具链,还需要下载.config
配置文件。不同架构cpu应使用不同的配置文件,例如intel的现代cpu使用x86_64-gcc-8.5.0-glibc-2.28:
mkdir toolchain-dir
cd toolchain-dir
wget https://github.com/microsoft/vscode-linux-build-agent/blob/main/x86_64-gcc-8.5.0-glibc-2.28.config
ct-ng build
利用wget获取该文件可能会失败,建议手动去github下载这一文件,拷贝到toolchain-dir目录中。
ct-ng build
命令会自动寻找.config文件,根据其内容编译glibc和gcc。
清空环境变量LD_LIBRARY_PATH
在CentOS上使用scl的gcc工具集时或者用户自己为了开发时链接方便 设置了LD_LIBRARY_PATH
环境变量,此时使用ct-ng编译时会报错:
[ERROR] Don’t set LD_LIBRARY_PATH. It screws up the build.
因此,需要运行如下指令临时删除LD_LIBRARY_PATH
环境变量
unset LD_LIBRARY_PATH
CentOS平台的“小”问题
1.在CentOS 7系统中,可能出现如下错误:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lstdc++
Checking that gcc can statically link libstdc++
这是gcc找不到c/c++的标准静态库,无法完成静态链接测试导致的。
c/c++标准库真的不存在吗?运行命令locate libc.a
尝试查找,若命令行没有任何输出,说明c标准静态库确实不存在。因此,运行如下命令安装静态库可解决问题:
yum install glibc-static libstdc++-static
2.报错
error: C++ compiler not available
则需要安装g++编译器:
sudo yum install gcc-c++
3.报错critical programs are missing or too old: make
即make版本太老,需要编译更新make。查看INSTALL文件发现,使用crosstoolchain编译glibc要求make的最低版本为4.0:
而CentOS7自带的make
版本是3.8.2。因此,在运行ct-ng build
命令之前,需要更新CentOS7的make
。
更新命令:
wget https://ftp.gnu.org/gnu/make/make-4.0.tar.gz
tar -xzf make-4.0.tar.gz
cd make-4.0/
./config
./configure
make
sudo make install
完成后,关闭当前终端,开启新的终端,运行make --version
检查是否更新到最新版本。
- 报错找不到ncurse库:
sudo yum install ncurses-devel
- CentOS内核版本过旧
CentOS内核版本默认是3.10(2012年发布),而2025年以来,VSCode拒绝连接如此老旧的系统。因此有必要将其内核更新到5.x版本或更新。由于CentOS 7早已被结束支持,这里给出一种方案。
目前mirrors.coreix.net网站还提供CentOS 7的5.4版本内核下载,因此我们先从该网站下载内核的rpm包,然后依次安装它们:
cd Downloads/
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-5.4.278-1.el7.elrepo.x86_64.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-devel-5.4.278-1.el7.elrepo.x86_64.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-doc-5.4.278-1.el7.elrepo.noarch.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-headers-5.4.278-1.el7.elrepo.x86_64.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-tools-5.4.278-1.el7.elrepo.x86_64.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-tools-libs-5.4.278-1.el7.elrepo.x86_64.rpm
wget https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-tools-libs-devel-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-devel-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-headers-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-tools-libs-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-tools-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-tools-libs-devel-5.4.278-1.el7.elrepo.x86_64.rpm
sudo rpm -ivh kernel-lt-doc-5.4.278-1.el7.elrepo.noarch.rpm
更新内核后,运行命令rpm -qa | grep kernel
查看已安装内核版本:
运行命令sudo cat /etc/grub2.cfg | grep menuentry|awk -F "'" '$1=="menuentry " {print i++ " : " $2}'
查看内核序号,输出为:
0 : CentOS Linux (5.4.278-1.el7.elrepo.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-1160.119.1.el7.x86_64) 7 (Core)
2 : CentOS Linux (0-rescue-a82932c2dec3474eb46898bf0ef5e40d) 7 (Core)
然后根据序号将新内核设为默认启动内核:
grub2-set-default 0
最后重启电脑即可。运行uname -rs
可查看系统版本号。若输出为
Linux 5.4.278-1.el7.elrepo.x86_64
则表示更新成功。
编译安装patchelf
patchelf
是一个替换系统关键elf组件的工具,用于将上面ct-ng
编译好的gcc工具链和新的glibc设置为远程连接进程的默认配置。
远程连接时,VSCode检测到远程系统的GLIBC版本过低,会启用patchelf
,并查找数个环境变量(下节介绍),以尝试将系统默认的GLIBC替换成更新版本,以使远程连接正常运行。
在Ubuntu 18中,可以直接使用命令行安装patchelf
:
sudo apt-get install patchelf
安装完成后,运行命令检查patchelf版本:
patchelf --version
官方推荐使用0.18.0
以及更新版本,0.17.x
版本存在错误。
而CentOS 7中不存在patchelf的软件源,需要用户下载源码、手动编译:
cd ~
wget https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0.tar.gz
tar -zf patchelf-0.18.0.tar.gz
cd patchelf-0.18.0
./bootstrap.sh
./configure
make
sudo make install
patchelf的更多用法可以参考博客。
更多信息也可以访问patchelf的GitHub页面。
设置VSCode Server所需的sysroot环境变量
所谓的sysroot指的就是编译好的glibc库。按照上面数节的配置,编译的glibc2.28位于~/toolchain-dir
,而patchelf位于/usr/local/bin/
,因此这三个环境变量的配置为:
export VSCODE_SERVER_CUSTOM_GLIBC_LINKER=~/toolchain-dir/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2
export VSCODE_SERVER_CUSTOM_GLIBC_PATH=~/toolchain-dir/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib
export VSCODE_SERVER_PATCHELF_PATH=/usr/local/bin/patchelf
将这三条命令加到~/.bashrc
文件中。
如果编译时toolchain-dir不在$HOME
下,则需要用户自行查找ld-*.so.2的路径。默认情况在编译完成的toolchain-dir目录下,深入数层后有sysroot
子目录,如图所示:
VSCode所需的三个环境变量名和作用如表所示:
环境变量 | 作用 |
---|---|
VSCODE_SERVER_CUSTOM_GLIBC_LINKER | 利用ct-ng编译好的动态链接器ld-linux-x86-64.so.2 路径(将被传递给patchelf的–set-interpreter选项) |
VSCODE_SERVER_CUSTOM_GLIBC_PATH | 利用ct-ng编译好的glibc文件夹路径(将被传递给patchelf的–set-rpath选项) |
VSCODE_SERVER_PATCHELF_PATH | 编译好的patchelf可执行程序路径 |
在Remote SSH扩展中添加远程连接
在VSCode中使用Ctrl+Shift+P组合键,输入“Remote-SSH”,选择下图所示的选项:
根据实际情况配置SSH命令行,输入密码,建立连接;稍候VSCode在远程配置完毕,将弹出如下提示框:
点击“允许”,即可连接到远程系统。大功告成!
3.结语
连接后在VSCode顶部依然会出现提示信息“你已连接到不受Visual Studio Code支持的OS版本”,如下图所示:
也就是说,未来可能不再支持使用本文的方法来实现老系统远程连接,用户应当考虑将系统升级到较新的LTS版本。
4.参考
/usr/bin/ld: cannot find -lc while compiling
Can I run VS Code Server on older Linux distributions?