在旧版集群系统上运行远程 VS Code 的方案,借助容器绕过限制。
主要问题:如果本地 VS Code 版本高于 1.98,连接时可能出现“远程主机不符合 glibc 和 libstdc++ VS Code Server 先决条件”的报错。这与远程系统版本较旧有关。此前尝试过手动替换新版本组件,但稳定性不足,容易出现断联;而长期使用低版本 VS Code 又会影响新版插件的使用。
这里使用 Singularity 启动 VS Code Server。该方案基本解决了远程连接问题,但仍不适合直接在容器内提交计算任务脚本或查询任务状态。
方法:将 VS Code Server 自带的 node 可执行文件替换为一个 wrapper 脚本。VS Code 启动时先执行该 wrapper,再由 wrapper 进入 Singularity 容器,并调用容器环境中的实际 node 运行 VS Code Server。
连接方式:
1 srun --partition=cpu --nodelist=cpu07 --cpus-per-task=1 --pty bash
进入节点后,可以在 Remote-SSH 中连接对应节点并启动容器环境。终端中如需使用 conda,可先初始化 shell 环境:
注意:
Step 1 启用 node wrapper
remote.SSH.useExecServer = true 是 VS Code Remote-SSH 较新的启动方式。开启后,连接服务器时不再通过 node 启动 ,而是使用预编译的 Rust CLI 程序。该 CLI 会先检查系统版本;在 CentOS 7 环境中可能因 glibc 版本过旧而直接退出,并绕过前面配置的 node wrapper。
按下快捷键 Cmd + , 打开设置 。在上方搜索框输入:useExecServer
找到 Remote.SSH: Use Exec Server 这个选项,取消选中
Step 2 对齐版本
本地的 VS Code 是 1.109.5 (对应的 commit 是 0725862...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 COMMIT="072586267e68ece9a47aa43f8c108e0dcbf44622" cd ~/.vscode-server/bin/$COMMIT # 1. 删除此前下载失败或不完整的压缩包 rm -f vscode-server.tar.gz # 2. 使用对应 commit 的 URL 重新下载 echo "正在下载 1.109.5 核心..." curl -sL "https://update.code.visualstudio.com/commit:${COMMIT}/server-linux-x64/stable" -o vscode-server.tar.gz # 3. 解压 VS Code Server tar -zxf vscode-server.tar.gz --strip-components 1 rm vscode-server.tar.gz # 4. 替换 node 为 Singularity wrapper echo "正在写入 Singularity wrapper..." mv node node_real COMMIT="072586267e68ece9a47aa43f8c108e0dcbf44622" cd ~/.vscode-server/bin/$COMMIT cat << 'EOF' > node # !/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export XDG_RUNTIME_DIR=$HOME/.vscode-server/run-tmp mkdir -p $XDG_RUNTIME_DIR chmod 700 $XDG_RUNTIME_DIR # 使用环境变量减少 Singularity/Apptainer 输出 export SINGULARITY_SILENT=1 export APPTAINER_SILENT=1 # 避免使用部分旧版本 Singularity 不支持的 --quiet 参数 exec /software/singularity/bin/singularity exec \ --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ --bind $XDG_RUNTIME_DIR:/tmp \ --bind /etc/pki/tls/certs/ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt \ ~/software/ubuntu-dev.sif \ $ DIR/node_real "$@ " EOF echo "Singularity wrapper 已写入。"
解决代理网络问题。这里本地代理使用 V2RayN,因此端口设置为 10808。
1 RemoteForward 10808 127.0.0.1:10808
在脚本中添加代理设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 COMMIT="072586267e68ece9a47aa43f8c108e0dcbf44622" cd ~/.vscode-server/bin/$COMMIT cat << 'EOF' > node # !/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export XDG_RUNTIME_DIR=$HOME/.vscode-server/run-tmp mkdir -p $XDG_RUNTIME_DIR chmod 700 $XDG_RUNTIME_DIR export SINGULARITY_SILENT=1 export APPTAINER_SILENT=1 # ========== 代理环境变量注入 ========== # 指向通过 SSH RemoteForward 映射过来的本地端口 export http_proxy="http://127.0.0.1:10808" export https_proxy="http://127.0.0.1:10808" # 注意:必须排除本地回环地址,否则 VS Code 的底层 Socket 通信可能中断。 export no_proxy="localhost,127.0.0.1,::1,0.0.0.0" # ============================================== # 在 exec 命令中使用 --env 将代理参数带入 Ubuntu 容器 exec /software/singularity/bin/singularity exec \ --env http_proxy=$http_proxy \ --env https_proxy=$https_proxy \ --env no_proxy=$no_proxy \ --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ --bind $XDG_RUNTIME_DIR:/tmp \ --bind /etc/pki/tls/certs/ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt \ ~/software/ubuntu-dev.sif \ $ DIR/node_real "$@ " EOF echo "代理环境变量已写入。"
此外,VS Code Remote-SSH 会尝试使用 wget 检查后端服务端口。集群 CentOS 7 节点上的 wget 版本较旧,不支持 --no-config 参数,可能导致检查过程报错退出。可以在本地 VS Code 客户端中修改设置进行适配:
Cmd + , (Command + 逗号) 打开设置
搜索框输入:useCurlAndWgetConfigurationFiles
找到 Remote.SSH: Use Curl And Wget Configuration Files ,并将其选中。选中后,VS Code 不再向 wget 传递 --no-config 参数,更适合 CentOS 7 环境。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 COMMIT="072586267e68ece9a47aa43f8c108e0dcbf44622" cd ~/.vscode-server/bin/$COMMIT cat << 'EOF' > nodeDIR="$( cd "$( dirname "${BASH_SOURCE[0]} " ) " && pwd ) " export XDG_RUNTIME_DIR=$HOME /.vscode-server/run-tmpmkdir -p $XDG_RUNTIME_DIR chmod 700 $XDG_RUNTIME_DIR export SINGULARITY_SILENT=1export APPTAINER_SILENT=1export http_proxy="http://127.0.0.1:10808" export https_proxy="http://127.0.0.1:10808" export no_proxy="localhost,127.0.0.1,::1,0.0.0.0" exec /software/singularity/bin/singularity exec \ --env http_proxy=$http_proxy \ --env https_proxy=$https_proxy \ --env no_proxy=$no_proxy \ --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ --bind $XDG_RUNTIME_DIR :/tmp \ --bind /etc/pki/tls/certs/ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt \ ~/software/ubuntu-dev.sif \ $DIR /node_real "$@ " EOF echo "Node wrapper 已更新。"