资讯动态

GPU服务器远程开发实战:SSH免密、VSCode/PyCharm与端口转发

发布时间:2026/9/13 14:23:15 来源:尧图企业网站定制
先说一个大多数人的误区拿到一台带GPU的服务器很多人的第一反应是赶紧装驱动、装CUDA、跑个测试样例等真正要开始写代码训练模型的时候才发现每天在终端里敲命令的效率低得让人崩溃。远程连接服务器这件事真正的难点从来不是“连上”而是连上之后能不能把整套深度学习实验环境用出本地开发机的感觉。这篇是系列第六篇前面几篇已经把服务器初始化、GPU驱动、CUDA这些基础讲完了这篇专门聊远程连接的完整工作流从SSH免密、VSCode远程开发、PyCharm远程解释器到VNC桌面、端口转发、Docker容器接入最后再给一份我在多台服务器之间切换多年后固定下来的配置参考。1. 能SSH连上离“能干活”还差一整套工作流1.1 服务器的日常不是连上就完事我第一次接触远程服务器的时候觉得SSH连上就算完事了ssh userhost输入密码然后开始在终端里用vim改代码。但实际跑一次深度学习训练就会发现这种“能用”和“好用”之间隔着巨大的鸿沟。你大概率会遇到这些场景改一行代码要在本地编辑器和服务器之间反复切换文件同步全靠scp手动传训练起来想在浏览器里看TensorBoard结果不知道端口怎么映射出来断一次SSH连接跑了一半的训练进程直接没了想用Jupyter Notebook做交互式调试又不知道远程Jupyter怎么配才安全。这些问题的本质是你需要的不只是一个“能敲命令的终端”而是一套能让远程服务器像本地机器一样工作的开发环境。1.2 把目标定为“像用本地电脑一样用服务器”所以这篇讲的远程连接不是单指某个工具而是指一个组合SSH负责连接和文件传输VSCode或PyCharm负责代码编辑和调试tmux负责长任务保活端口转发负责把远程的Web服务带回本地浏览器VNC负责在实在需要图形界面时顶上去Docker负责把实验环境隔离和复现。我在实际工作中最多同时维护五台服务器公司GPU机、实验室工作站、两台云主机、一台用来跑数据预处理的老机器如果每一台都用“密码裸SSHvim”的方式去操作光记住各个机器上的环境差异就够头疼的。把这些工具串起来之后每台服务器在本地看起来就是一个VSCode窗口或一个SSH别名切换成本降到最低。这也是为什么我一直强调搭建远程实验环境的核心不是安装某个软件而是把连接、编码、执行、可视化这几件事串成一条顺畅的流水线。2. SSH免密与多主机管理先把连接这一层磨利2.1 生成密钥并下发公钥每一次远程操作的第一步都是SSH连接。密码登录最大的问题不是慢而是没法写进脚本和自动化工具里而且每次连接都要输入一遍断线重连更烦。所以第一件事就是改成密钥登录。在本地机器上执行ssh-keygen -t ed25519 -C your-email-or-comment选ed25519而不是RSA是因为它的密钥更短、生成速度快、安全性高于同长度RSA。一路回车把密钥保存在~/.ssh/id_ed25519就好如果你已经有密钥想单独生成一把专门给服务器的可以在提示输入文件名时改成~/.ssh/id_ed25519_server。然后下发公钥ssh-copy-id -i ~/.ssh/id_ed25519.pub userserver_ip这条命令会自动把你的公钥追加到服务器上~/.ssh/authorized_keys文件里并设置好权限。没有ssh-copy-id的Windows用户也可以用一条手动命令替代cat ~/.ssh/id_ed25519.pub | ssh userserver_ip mkdir -p ~/.ssh chmod 700 ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys2.2 SSH config给每台服务器起个“外号”密钥配置好之后每次连接还是得敲完整用户名和IP记性不好的时候还要翻笔记查端口。我强烈建议把SSH config用起来编辑本地~/.ssh/config文件Host gpu01 HostName 192.168.31.101 User ubuntu Port 22 IdentityFile ~/.ssh/id_ed25519_server ServerAliveInterval 60 ServerAliveCountMax 3这样之后连接只需要ssh gpu01scp也直接scp test.py gpu01:/home/ubuntu/简单清晰。ServerAliveInterval 60是心跳包每60秒发一个保活信号避免一段时间没操作就被运营商或服务器掐断连接。多台机器就多写几个Host块每台机器还能顺手写上不一样的用户名、端口、密钥文件。2.3 密钥登录失效的权限细节密钥登录配好之后偶尔会遇到“明明公钥放进去了还是提示输密码”的问题九成出在权限上。服务器上的~/.ssh目录必须是700authorized_keys文件必须是600~目录本身不能对组和其他用户有写权限。用下面这三行一次修完chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod go-w ~另外一个经常被忽略的点是StrictModes。服务器上/etc/ssh/sshd_config如果开了这个选项sshd会严格检查文件属主和权限只要发现公钥文件对别的用户可写就直接拒绝密钥登录而不会告诉你具体原因。排查时用sudo grep -i strictmodes /etc/ssh/sshd_config看一眼必要时改成StrictModes no再重启sshd服务。3. VSCode Remote-SSH把远程主机变成开发工作台3.1 Remote-SSH的运作机制VSCode Remote-SSH这个插件本质上是“在远程机器上装一个服务端在本地VSCode里操作这个服务端”。当你通过远程窗口连接服务器时VSCode会在服务器的~/.vscode-server目录下自动下载安装一套服务端组件本地的编辑器界面、快捷键、终端面板都直接操作远端的文件系统和解释器。这就意味着你在本地写的每一行代码实际落在服务器上Python解释器用的是服务器上的conda环境跑起来就是调用服务器的GPU。理解了这一层你就明白为什么Remote-SSH连接失败时常见报错是“Can’t find a valid VSCode Server”或连接后卡在下载界面。这是因为服务器无法访问VSCode的服务端下载源或者在~/.vscode-server目录没有写权限。解决办法是手动把服务端下好放进对应目录或者换成一台网络通畅的服务器下载好再传过去权限问题就直接chown一下home目录归属。3.2 配置过程及几个会卡住人的地方配置很简单本地装好VSCode安装Remote - SSH插件按F1输入“Remote-SSH: Connect to Host”选择或新建SSH配置。插件会读取~/.ssh/config里已有的Host条目所以前面配置好的gpu01到这里可以直接选非常顺滑。真正容易卡住的是下面几个细节第一本地是Windows的话VSCode默认使用Windows自带的OpenSSH客户端而不是Git Bash里的ssh。如果~/.ssh/config路径写错或者密钥放在Git Bash的目录下VSCode就找不到。最稳的办法是在VSCode的设置里找到“Remote.SSH: Path”指定你希望使用的ssh客户端路径同时把config文件路径也固定下来。第二连接后经常遇到“无法解析主机名”的报错十有八九是SSH config里Host和HostName两个字段混在一起或者config文件格式不对。注意Host是别名可以随便起HostName才是真正的IP或域名。第三远程端的Python解释器选择。VSCode打开远程文件夹后按CtrlShiftP搜索“Python: Select Interpreter”选服务器上对应conda虚拟环境里的python可执行文件。这一步不做VSCode会默认用服务器系统Python很可能跟你的实验环境不一致跑起来报ModuleNotFoundError。3.3 配合扩展与端口转发Remote-SSH连接后VSCode左下角会显示远程主机名。这时候本地装的扩展并不会全部在远程生效比如Python扩展需要在远程端安装VSCode会提示你Install in SSH: gpu01。我自己常用的组合是Python、Pylance、Jupyter、GitLens外加一个Remote-SSH配套的端口转发面板。端口转发特别值得专门说训练脚本里启动TensorBoard后TensorBoard默认监听服务器6006端口。你不可能跑到服务器上用浏览器打开所以需要把服务器的6006端口转发回本地。在VSCode的“端口”面板里添加6006本地浏览器直接访问http://localhost:6006就能看到远程的TensorBoard页面。这个功能的底层就是SSH本地端口转发VSCode帮你把命令行封装成了可视化操作。等你在服务器上跑了多个训练任务一次要看多个面板的时候端口转发的价值会体现得淋漓尽致。4. PyCharm远程解释器与自动部署惯性最大的IDE方案4.1 为什么还需要PyCharm很多人从入门深度学习开始就用的PyCharm习惯了它的Project视图、调试器和重构功能切换到VSCode总感觉少了点东西。PyCharm Professional版提供了完整的远程开发方案远程解释器加自动部署代码本地编辑执行和调试都在服务器上体验非常接近本地开发。先说一个可能打消很多人念头的现实远程解释器功能只有Professional版才有Community版不支持。如果你用的是Community版要么考虑VSCode方案要么就用下面的SFTP映射方式手动同步文件。4.2 配置步骤SFTP部署 远程解释器PyCharm远程开发的配置分两步这两步都做对才算完整。第一步配置部署Deployment。在菜单“Tools - Deployment - Configuration”里新建一个SFTP服务器填上服务器IP、用户名、密码或密钥在“Mappings”标签页里设置本地项目目录和服务器上的部署目录。设置完成之后右键项目根目录选“Upload to”代码就能同步到服务器。第二步配置远程解释器。在“File - Settings - Project: xxx - Python Interpreter”里点“Add Interpreter”选“On SSH”输入连接信息后PyCharm会列出服务器上的Python解释器路径可以直接指向conda环境的/home/user/miniconda3/envs/dl/bin/python。配置好后PyCharm会把本地代码同步到服务器然后调用远程解释器执行。PyCharm这里有个细节如果你用的是conda环境最好在远端把环境创建好再关联不要让PyCharm自动创建虚拟环境。自动创建的venv往往缺少系统依赖而且路径很长容易在后续装包时出问题。4.3 路径映射与文件同步的坑用PyCharm远程开发最经常出问题的不是配置过程而是“本地改了一段代码服务器上没同步跑的还是旧代码”。我会在“Deployment - Options”里把“Upload changed files automatically”改为“On explicit save”这样每次CtrlS保存代码就会自动上传。但这里有个隐患自动上传是覆盖式的如果你的训练脚本会写输出文件到项目目录比如保存模型权重、日志这些文件也会被回传到本地或者本地文件反过来覆盖服务器上的结果。我的习惯是训练产出统一写到项目之外的/home/user/experiments目录或者用.gitignore把输出目录加入PyCharm的部署排除列表避免服务器和本地互相覆盖。另一个坑是本地和服务器路径不一致。比如本地代码里写死了/home/user/project/data但服务器部署目录是/opt/proj/data运行时会直接报文件找不到。跨平台路径问题在团队协作里更常见大家一起用同一套相对路径规范或者统一约定部署目录能省下大量排查时间。5. 要图形界面Windows远程连Ubuntu的VNC方案5.1 什么场景值得装桌面说实话90%的深度学习实验用不到图形界面但总有例外。比如你要用matplotlib画个复杂图、要跑一个需要GUI交互的数据标注工具、或者在演示代码给组里同事看的时候一个桌面环境比一堆命令行截图直观得多。这时候VNC就是最实用的方案。VNCVirtual Network Computing的思路是在Ubuntu服务器上启动一个桌面会话Windows端用VNC客户端连上去看到的就是一个完整的Ubuntu桌面。它不像SSH那样只能敲命令而是真正图形化的远程桌面。5.2 TigerVNC XFCE的安装与启动桌面环境我强烈推荐XFCE而不是GNOME或KDE。原因很简单深度学习服务器的GPU宝贵得很没人愿意为了一个桌面环境多耗几百MB显存跑动画特效。XFCE轻量、稳定、资源占用低作为服务器桌面够用了。安装过程sudo apt update sudo apt install xfce4 xfce4-goodies tigervnc-standalone-server tigervnc-common然后设置VNC密码并启动vncpasswd vncserver -localhost no -geometry 1920x1080 -depth 24 :1这条命令会在服务器的5901端口即display :1对应的端口启动一个VNC服务。第一次启动时会自动生成配置文件并提示启动桌面环境。注意如果启动后连接进去看到的是灰屏而不是桌面多半是~/.vnc/xstartup文件没有执行桌面启动命令。编辑这个文件#!/bin/sh startxfce4 然后chmod x ~/.vnc/xstartup重启vncserver -kill :1再vncserver -localhost no :1。Windows端推荐用TigerVNC Viewer或RealVNC Viewer连接地址填服务器IP:5901输入密码就能看到Ubuntu桌面了。5.3 不裸奔用SSH隧道保护VNCVNC本身是明文协议直接在公网暴露5901端口等于把服务器桌面裸奔在网络上相当危险。我从来不会在生产环境服务器上直接开放VNC端口而是配合SSH隧道使用。先在服务器上启动VNC时用-localhost yes模式让VNC只监听本机vncserver -localhost yes :1然后本地Windows终端执行ssh -L 5901:localhost:5901 userserver_ip这条命令把本地5901端口和服务器5901端口通过SSH隧道连起来VNC Viewer连localhost:5901流量全程走SSH加密隧道不暴露额外端口。即使你在公网服务器上也只需要SSH这一个入口。6. 把Jupyter和TensorBoard带回本地端口转发与容器环境6.1 一条ssh -L搞定Web服务转发远程训练最常用的两个Web服务是Jupyter Notebook和TensorBoard它们都监听在服务器的某个端口上。把这些端口安全地“映射”到本地靠的就是SSH端口转发。TensorBoard的经典组合ssh -L 16006:localhost:6006 userserver_ip tensorboard --logdir ./logs --port 6006然后本地浏览器访问http://localhost:16006看到的实际上是服务器6006端口的TensorBoard页面。我特意把本地端口改成16006而不是直接6006是因为本机很可能有别的服务占用6006整数偏移一下省得端口冲突。Jupyter也是同理但要注意远程Jupyter配置jupyter notebook --no-browser --port8888 --ip0.0.0.0然后本地ssh -L 18888:localhost:8888浏览器打开http://localhost:18888。6.2 远程Jupyter的安全配置Jupyter默认的身份验证是token很多人嫌麻烦干脆--NotebookApp.token关掉认证这等于把服务器的计算资源向全网开放是相当危险的。我的做法是先用jupyter server password设一个密码然后配合SSH隧道让Jupyter即使监听所有网卡也不怕被外部扫描到。给远程Jupyter做端口转发时有个注意点服务器上如果同时有多个实验环境每个conda环境需要各自的Jupyter内核ipykernel否则用A环境启动Jupyter之后只能创建A环境的Notebook切不了内核。可以在对应conda环境里执行conda install ipykernel python -m ipykernel install --user --name dl_env --display-name Py3 (dl_env)这样Jupyter界面的“New”菜单里就能选择不同的内核环境。6.3 Docker容器里的深度学习环境怎么远程接现在越来越多的团队用Docker来管理深度学习环境因为不同项目依赖的PyTorch版本、CUDA版本经常冲突容器天然把环境隔离了。远程连接这一层Docker化之后会多出一个端口映射的问题。启动容器时指定GPU和端口映射docker run -it --gpus all --shm-size16g \ -p 8888:8888 -p 6006:6006 \ -v /data/projects:/workspace \ --name dl_env \ nvcr.io/nvidia/pytorch:23.08-py3 \ bash如果那时已经挂了一个端口映射到宿主机比如8888映射到了宿主机8888那在服务器本地访问localhost:8888就能进容器里的Jupyter再配合ssh -L把宿主机的8888转发到本地浏览器整条链就通了。容器内训练还有个容易踩的坑容器默认的共享内存是64MBPyTorch的DataLoader多线程加载数据时经常报“Bus error”或“Cannot allocate memory”所以启动参数里加--shm-size16g会省掉很多莫名其妙的崩溃。7. 一次SSH连接失败的完整排查链路7.1 复现“连不上”时的第一直觉远程连接这块我最常收到的求助就是“昨天还连得上今天突然连不上了”。遇到这个问题我的习惯不是立刻去找服务器管理员重启sshd而是按下面的顺序一条条验证。先在本地终端跑ssh -v userserver_ip-v参数会打印完整的连接调试信息。重点看两个地方一是有没有输出Connection established这代表TCP层通了二是看卡在哪个阶段比如卡在Authentications that can continue后面说明认证有问题卡在Connecting to host长时间不动说明网络不通。如果ssh -v显示Connection timed out基本是网络层问题。这时在本地先ping一下服务器能ping通再去检查端口nc -zv server_ip 2222端口不通要么是防火墙挡了要么是sshd服务没起。7.2 服务器端逐项检查如果你有别的办法登录服务器比如云控制台VNC那就进服务器里检查下面几项。先看sshd服务状态systemctl status sshd sudo systemctl restart sshdUbuntu 20.04以上默认用的是ssh服务名CentOS上用sshd具体用哪个名字可以用systemctl list-units | grep ssh查一下。看端口监听ss -tlnp | grep 22没有输出就说明sshd没监听可能服务挂了或者配置文件改了端口。看防火墙sudo ufw status如果UFW是active并且22端口不在规则里直接sudo ufw allow 22/tcp放行。云服务器还要记得去控制台的安全组里看22端口是否在入方向规则里这个排查点经常被人忽略。7.3 最常见的三类根因根据我的经验SSH连接失败九成是这三类原因第一密钥权限或属主问题导致publickey认证失败。这类报错往往是Permission denied (publickey)服务器端/var/log/auth.log里有明确提示。修复方法就是前面说过的chmod三件套。第二本地known_hosts记录了旧的主机指纹服务器重装系统或换了IP之后指纹对不上SSH会直接警告并拒绝连接。这种情况删掉~/.ssh/known_hosts里对应那行就行或者用ssh-keygen -R server_ip命令把旧记录清掉。第三云服务器安全组把22端口限制了或者只允许某些来源IP访问。国内腾讯云、阿里云控制台都有安全组规则排查顺序排在本地防火墙之前。实际上很多“连不上”的问题根源都在安全组或防火墙而不是服务器自身故障。先通一层层排查链路能少走很多弯路。8. 固定下来之后我的远程环境配置参考8.1 一份开箱即用的SSH config模板经过多台服务器反复折腾我目前的~/.ssh/config长这样新机器拿来直接用Host gpu01 HostName 192.168.31.101 User ubuntu Port 22 IdentityFile ~/.ssh/id_ed25519_gpu01 ServerAliveInterval 60 ServerAliveCountMax 3 Host gpu02 HostName 172.16.10.22 User root Port 22 IdentityFile ~/.ssh/id_ed25519 ProxyJump gpu01gpu02这台处于内网需要通过gpu01跳板机转发所以写了ProxyJump gpu01。这个配置在日常使用里太常用了比如公司内网的GPU机、实验室跳板后的工作站都会用到。VSCode Remote-SSH会自动识别这些配置连接时直接选别名就行。8.2 长任务与断线处理就算加了ServerAliveInterval心跳SSH连接在长时间训练时还是有断掉的概率。一个训练跑三个小时断线后终端进程被挂掉所有进度归零这种事我在早期踩过好多次。后来养成了习惯所有长任务一律在tmux里跑。tmux new -s train python train.py断线后重新连上tmux attach -t train就能回到原来的会话训练进程还活着。配合Anaconda环境我习惯在tmux窗口里先conda activate一下对应的环境再跑训练命令。多实验并行的时候每个实验一个tmux会话名字起清楚比如train-bert-finetune、train-yolo-v8管理起来一目了然。8.3 实践下来的经验与偏好说到最终固定下来的工作流我现在大多数时候用VSCode Remote-SSH写代码和调试用tmux跑长训练用端口转发看TensorBoard只有需要GUI工具的时候才开VNC。PyCharm主要在重构代码、做大型项目调试的时候打开因为它对复杂项目结构的支持确实比VSCode成熟。还有个小习惯想推荐给大家服务器端顺手把时间同步配置好很多训练日志、时间戳对比、模型保存都依赖准确的系统时间。在Ubuntu上执行sudo apt install chrony sudo systemctl enable --now chrony就能保持系统时间自动同步训练日志里的时间戳再也不会出现“两个实验时间对不上”的情况。最后想说的是工具这东西适合自己手感的才是最好的。有人觉得VSCode轻巧好用有人离不开PyCharm的调试器还有人全程终端tmux也跑得很顺畅。关键是先把SSH免密、端口转发、tmux保活这几件最通用的事做扎实它们无论你用什么编辑器、什么IDE都绕不开也确实能提升每天面对服务器时的幸福指数。如果你现在还在“密码登录vim编辑scp传文件”的阶段不妨花一个下午按这篇的顺序把这些配置一遍再回去跑实验你会发现原来远程开发也可以这么顺手。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价