十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

离线环境Antigravity SSH连接失败排查:server部署与防误删指南

离线环境Antigravity SSH连接失败排查:server部署与防误删指南 先把这次的问题情况说清楚。我这边有一台内网开发机系统是银河麒麟纯离线、没有外网通路。我往这台机器上部署 Antigravity客户端装在 Windows 笔记本上打算用 SSH 连到服务器上写代码。第一次连接失败时报错停在 Downloading server 这一步再仔细一看之前手动拷过去的离线安装包已经被系统的临时文件清理任务带走了。这个问题我在麒麟 Linux 和 Ubuntu 上各验证了一遍把排查过程和最终方案完整记录在下面。文章偏向实操适合所有在内网或离线环境里用 Antigravity 这类 IDE 连接远程主机的朋友参考尤其是踩过“手动传包”这种坑的人。1. 先复盘现场内网 SSH 失败的真实表现不只是“连不上”1.1 三种典型现象别被表象带偏内网环境里 SSH 连接失败的现场通常不是单一报错而是好几类问题混在一起。我遇到的第一种现象是密码输完后直接被拒绝或者密钥加载后仍然提示 Permission denied。这种最容易被误判为“SSH 配置坏了”其实很多情况下是远端账号的家目录权限、sshd_config 里的认证方式开关出了问题。第二种现象更隐蔽界面上没有立刻报错而是进入了一个“下载服务端”的进度状态然后卡在某个百分比最后超时。Antigravity 这类基于 VS Code 生态的 IDE连上远程主机后会检查远程端有没有对应的 server 程序如果没有就会尝试在远程主机上下载。内网机器访问不了公网这一步必然失败。表面上看起来像是“SSH 连接失败”实际上 SSH 通道已经建立了只是后续的 server 部署环节断了。第三种现象是在某些情况下连接窗口已经打开看起来像是连上了但右下角弹出一堆扩展错误或者侧边栏的扩展列表全部变灰。这种多和“扩展归属”有关我后面单独说。1.2 形如“此扩展在远程扩展主机中被禁用”的提示不是连接故障搜热词里有一条很典型“此扩展在此工作区中被禁用因为其被定义为在远程扩展主机中运行。请在 ssh: ying 中安装”。第一次看到这个提示的人很容易误判成连接出问题实际上这只是扩展的安装位置放错了。Antigravity 和 VS Code 一样扩展分为 UI 扩展和工作区扩展。UI 扩展运行在本地窗口比如主题、图标、部分快捷键增强类插件工作区扩展运行在远程主机上。如果你把某个扩展只装到了本地但这个扩展声明了自己的 extensionKind 包含 workspace在远程工作区环境下它就会被禁用并提示去远程安装。解决办法也简单在扩展面板里找到该扩展点击“在 SSH: 主机名中安装”或者点击提示里对应的安装按钮。安装完成后重载窗口即可。这个提示不影响 SSH 本身更不需要去改远程 server 配置。1.3 为什么内网环境更容易集中爆发外网环境下很多问题会被“自动下载”“自动更新”掩盖掉。在没有外网通路的机器上这些自动动作全部变成失败点。我统计了一下内网环境下最容易踩的位置有三个第一远程主机需要下载 server 但下载不了第二IDE 自身或扩展尝试访问更新源连接超时影响体验第三手动拷贝到远程的安装包被管理员脚本或临时清理任务误删导致“之前明明能用突然又要求下载”。后一个问题最气人因为它不报错只是在下一次连接时重新走“检测 server → 发现缺失 → 尝试下载 → 下载失败”的流程表面看像是 SSH 连接失败其实根子早就不在 SSH 上了。2. 根因拆解Antigravity 连接远程主机到底在后台等什么2.1 远程开发模型客户端只负责界面真正的代码服务跑在远端Antigravity 的远程开发模型和 VS Code Remote-SSH 是同一套思路本地客户端是一个“瘦客户端”负责渲染界面、接收输入远程主机上运行一个独立的 server 进程负责文件读取、语法解析、执行终端命令、跑语言服务。也就是说SSH 连接建立之后IDE 还要在远程主机上“启动一个后台服务”这个服务没有起来编辑器就只有一个空壳。这套模型的优势很明显本地不需要装 SDK、不需要拷贝代码远程主机上有完整环境。但在离线内网环境劣势同样明显远程 server 程序必须预先存在而且版本还要和客户端匹配。否则 IDE 会认为“服务端不存在或版本不对”然后触发自动安装流程。2.2 server 的获取顺序远程下载、本地缓存传输、手动放置对于 server 的获取我观察到的顺序是这样连接时客户端先读取远程主机上固定目录中的 server 信息文件比如~/.antigravity-server/bin/commit-id/下是否存在对应二进制。如果目录存在且完整直接启动这个 server。如果不存在客户端尝试在远程主机上直接下载对应版本的压缩包。远程下载失败时部分版本会尝试从本地缓存目录获取 server 包并传输到远端。以上都失败连接就会中止并报错。这里最关键的是第二步和第四步。手动放置安装包本质上就是用“人工”的方式完成第三、四步本该做的事把对应版本的 server 解压到约定目录让客户端检测通过。2.3 离线环境的断点在“下载”这一步内网机器的网络策略五花八门但核心特征都一样访问不了公网上的下载地址。于是问题集中在 2.2 的第三步。很多用户会手动下载一个 server 压缩包传到远程主机随便放在/home/xxx/下载/或者/tmp目录。这个做法本身没错但只做了一半——还需要解压到指定目录并且保证目录名是 commit ID。更常见的坑是下载目录或/tmp被系统定期清理。我遇到的那次就是把安装包放在/tmp/antigravity-server-linux-x64.tar.gz第二次连接时文件没了。表面看是“安装包被误删”实则是/tmp目录的生命周期本来就不长很多 Linux 发行版会通过 systemd-tmpfiles 定期清理。2.4 commit 不匹配带来的连锁反应提交 IDcommit ID是 server 匹配的关键。Antigravity 客户端每次发布版本都会对应一个固定的 commit ID远程 server 目录必须以这个 commit ID 命名。如果你手动放置的包版本和客户端版本不一致哪怕文件完全正常IDE 还是会认为“没有匹配的 server”继续尝试重新下载。我甚至遇到过一种情况第一次连接成功后来客户端自动升级了一个小版本commit 变了远程目录里的旧 server 立刻“失效”连接又开始卡在下载。离线环境里版本漂移是非常容易复发的问题后面的方案里我会专门提到怎么锁版本。3. 从报错到“包被误删”的完整排查链路3.1 第一步用 ssh -vvv 验证基础连通性排除账号和网络问题任何 SSH 连接问题都应该先绕过 IDE 直接验证。这一步很重要它能快速区分问题在“网络/账号层”还是“IDE 层”。我在本机终端执行ssh -vvv dev192.168.100.20 -p 22-vvv会输出详细握手过程。重点关注三处第一是否经过密钥交换并成功认证第二是否出现Permission denied (publickey,password)第三连接是否在 TCP 层就超时。如果直接命令行 SSH 能登上说明账号、网络、sshd 配置都没问题问题定位到 Antigravity 的远程 server 部署层。如果命令行 SSH 也登不上查下面几项远程主机的 sshd 服务状态systemctl status sshd认证方式是否开启检查/etc/ssh/sshd_config中的PasswordAuthentication、PubkeyAuthentication、AllowUsers防火墙和 SELinuxsudo firewall-cmd --list-all、getenforce这步的目的是缩小范围避免在 IDE 报错里反复猜测。3.2 第二步查看 Antigravity 的远程连接日志定位卡在哪个阶段基础连通没问题后再次用 IDE 连接然后立刻打开“查看 → 输出”在下拉框里选择“远程 - SSH”Remote-SSH。日志会一帧一帧打出来。离线环境里最有代表性的日志是这种[INFO] Remote server is not a recognized server platform [INFO] Downloading VS Code Server [ERROR] Failed to download https://update.code.visualstudio.com/commit:xxxx/...看到Downloading VS Code Server基本就实锤了SSH 本身建连成功但远程主机上没有可用的 server且在线下载失败。如果日志比较长可以搜索几个关键词error、failed、download、permission denied。日志目录一般位于~/.config/Antigravity/logs/Windows 下在%APPDATA%\Antigravity\logs可以直接打开文件搜索。3.3 第三步检查远程主机的 server 目录发现“案发地点”确定是 server 缺失后我立刻登进远程主机查看ls -la ~/.antigravity-server/bin/ ls -la /tmp/antigravity-server*.tar.gz第一看目录是否存在、里面是空目录还是根本没有第二看之前手动传的包还在不在。当时的结果很典型/tmp下的安装包消失了~/.antigravity-server/bin/也完全没有对应 commit 目录只残留了一个空壳目录。这时候我怀疑是清理任务干的于是去查系统里有哪些定时清理逻辑systemctl list-timers | grep -i tmp cat /usr/lib/tmpfiles.d/tmp.conf果然systemd-tmpfiles-clean.timer 在运行默认会清理/tmp中超过一定时间的文件。我的安装包放了几天没动就被当成临时垃圾清掉了。3.4 第四步用 lsof 确认进程是否还占用已删除文件还有一种更隐蔽的情况安装包虽然被删但远程 server 进程还在运行因为你第一次启动成功后进程没有退出文件被删但仍在内存中运行。这时候表面上连接“还能用”但一旦进程重启或者 IDE 强制重启 server就彻底连不上了。我习惯用下面的命令检查lsof L1 | grep antigravityL1会列出“文件已被删除但仍被进程打开”的记录。如果看到类似node (deleted)的条目说明 server 二进制还在被占用但文件系统中已经没了。这种状态下即使不重连也建议尽快处理否则服务器一重启连抢救的机会都没有。4. 离线内网环境的三条可行方案均在麒麟 Linux 和 Ubuntu 上验证过4.1 方案一手动放置 server 到固定目录并彻底脱离在线下载依赖这是所有方案里最稳的也是我推荐作为首选的做法。核心逻辑就一句话把对应 commit 的 server 解压到客户端约定的目录让 IDE 检查时直接通过跳过下载环节。具体操作分为几步。先在可联网或已有缓存的机器上找一份与 Antigravity 客户端版本完全匹配的antigravity-server-linux-x64.tar.gz。commit ID 怎么看在 IDE 的“关于”页面里能看到版本和 commit或者在连接失败日志里也能看到 URL 里带 commit 参数。然后把这个包传到远程主机注意不要放到/tmp和用户“下载”目录建议专门建一个离线资源目录sudo mkdir -p /opt/antigravity-offline sudo mv antigravity-server-linux-x64.tar.gz /opt/antigravity-offline/ sudo chmod 555 /opt/antigravity-offline/antigravity-server-linux-x64.tar.gz接着在目标用户目录下创建 server 目录并解压mkdir -p ~/.antigravity-server/bin/commit-id tar -xzf /opt/antigravity-offline/antigravity-server-linux-x64.tar.gz -C ~/.antigravity-server/bin/commit-id --strip-components1 chmod -R 755 ~/.antigravity-server/bin/commit-id--strip-components1是用来去掉压缩包内层的一级目录。很多 server 包解压后顶层目录是bin/、out/这种结构如果不加这个参数会把文件解压到多一层目录里导致 IDE 找不到二进制。最后回到本地 IDE重连远程主机。连接时的日志里应该会显示“server 已存在”或直接进入启动阶段不再触发下载。4.2 方案二开启允许本地 server 传输让客户端把缓存直接推上去如果你的远程主机没有外网但本地客户端环境相对自由比如能访问软件仓库或内网构件库可以考虑这个方案设置remote.SSH.allowLocalServerDownload为true让客户端在远程下载失败时把本地已经缓存的 server 包传输到远程。在 Antigravity 设置中搜索Remote.SSH找到Remote.SSH: Allow Local Server Download勾选启用。这个配置在连接失败后重新发起连接时生效日志里会出现类似Uploading server package的记录。这个方案的优点是省去了手动解压和放置的步骤对不熟悉 Linux 目录结构的用户更友好。但没有“本地缓存”的话还是不生效而且传输大包时对网络质量有要求。作为主力方案不够稳我通常把它当作手动放置失败时的备用手段。4.3 方案三整体搬移已初始化好的 server 目录适配批量开发机内网环境里经常有一批相同系统的机器。与其每台都手动解压安装包不如找一台已经成功连上 Antigravity 的机器把整个~/.antigravity-server目录打包再部署到其他机器。tar -czf antigravity-server-backup.tar.gz -C ~ .antigravity-server目标机器上执行tar -xzf antigravity-server-backup.tar.gz -C ~ chmod -R 755 ~/.antigravity-server这个方法特别适合“模板克隆 批量装开发机”的场景。唯一要注意的是这些机器的架构要一致x64 对 x64ARM 对 ARM而且客户端版本必须一致。如果有一台机器的客户端升级了 commit其他机器也要跟着同步否则照样连不上。4.4 SSH config 层的辅助手段别名、跳板机、密钥权限远程 server 问题解决后SSH 配置本身也可能存在隐患。我习惯把连接信息整理到~/.ssh/config里而不是每次在 IDE 连接面板手输 IP。Host dev-ai HostName 192.168.100.20 User dev Port 22 IdentityFile ~/.ssh/antigravity_ed25519 ServerAliveInterval 30 ServerAliveCountMax 3ServerAliveInterval能在长连接空闲时发送心跳包避免内网防火墙把空闲连接切断。如果开发机在更隔离的网段需要通过跳板机才能到达则加上ProxyJumpProxyJump jump-user10.0.0.5密钥文件的权限也要注意太宽松会被拒绝chmod 600 ~/.ssh/antigravity_ed255195. 安装包“被删”之后怎么办恢复手段与防误删四板斧5.1 先判断删到了哪一层回收站、/tmp 清理还是进程占用手动安装包被删这件事恢复之前要先判断是怎么被删的。不同的删除方式对应不同的恢复路径顺序上我建议这样查看是否有回收站如果是在图形界面里删除的Linux 下一般会进入~/.local/share/Trash/files可以ls看看。看是否被tmpfiles清理前面说过/tmp默认会被 systemd-tmpfiles 定期清理这种删除通常无法从回收站恢复只能重新拷贝。看进程是否仍占用文件用lsof L1检查如果 node 进程还开着被删除的文件可以尝试从/proc恢复。这里最容易踩的坑是“盲目重下”。离线环境根本没有下载源与其浪费时间不如先花两分钟确认删除方式把恢复路径锁定。5.2 从 /proc 里捞回被删除但仍被占用的文件当你发现 server 进程还在运行而二进制文件已经被删掉时可以先别重启任何东西。Linux 的/proc/pid/fd/目录里保存了进程打开的文件描述符只要文件被进程持有即使磁盘上已经删了也能把内容捞回来。操作方法lsof L1 | grep antigravity-server从输出中拿到进程号和文件描述符编号比如 pid 是 12345fd 是 7cat /proc/12345/fd/7 /home/dev/antigravity-server-recovered.tar.gz然后用file命令验证恢复出来的文件类型file /home/dev/antigravity-server-recovered.tar.gz如果是 gzip 压缩数据说明恢复成功。这个技巧在 Linux 服务器上适用麒麟系统同样支持。但注意如果进程已经退出这个路径就不行了。5.3 彻底没了的情况下从同配置机器导出最省事如果回收站没有、/proc也捞不回来那么最后一个可行路径是从另一台“同系统、同架构、同版本 IDE”的机器上导出。用 4.3 的整体搬移方案直接打包一个~/.antigravity-server目录传过去。这比重新找安装包、核对 commit 更直接。还有一种情况是内网有软件仓库或共享文件服务器那就把 server 安装包放到共享目录提供给大家按需拷贝。我建议在共享目录里同时放一个文本文件记录客户端版本、commit ID、服务器架构和上传日期防止别人拿错包又卡在版本不匹配上。5.4 防误删四板斧固定目录、只读权限、清理白名单、sha256 校验经历过一次“包被删”的折腾后我把防误删做成了固定的四步操作后面再也没复发第一固定目录。安装包统一放在/opt/antigravity-offline/不放在/tmp、/home下的下载文件夹、以及任何名字里带“temp”“cache”的目录。第二只读权限。解压后的 server 目录和压缩包都设置成chmod 555或chmod 444最大程度避免手滑rm -rf和普通清理脚本误伤。第三清理白名单。内网机器上如果有自开发清理脚本要让它们跳过/opt和用户主目录。我见过很多脚本直接用find / -type f -mtime N -delete这种写法在全盘清理时几乎必然会误删重要文件。第四记录 sha256。下载完安装包后立刻算一次哈希存档到内网文档sha256sum /opt/antigravity-offline/antigravity-server-linux-x64.tar.gz以后每次排查“是不是包坏了”先跑一次哈希对比存档结果就能快速区分是文件损坏还是目录缺失。这个习惯让我省了很多不必要的反复拷贝。6. 实测记录与复发预警验证清单和几个容易复发的细节6.1 一次完整连接的验证步骤与预期结果解决完 server 缺失问题后我建议按下面的顺序做一次完整验证而不是直接“看能不能打开窗口”就完事。第一步验证远程主机上的 server 目录ls -la ~/.antigravity-server/bin/预期结果存在以 commit ID 命名的目录里面有server.sh或node等可执行文件。第二步从远程主机手动启动 server 进程可选~/.antigravity-server/bin/commit-id/server.sh --print-status如果 server 能正常返回状态信息说明这个目录本身就是可用的。第三步在本地 IDE 发起连接打开“远程 - SSH”日志预期看到 server 启动成功的记录而不是Downloading VS Code Server。第四步在远程窗口中打开终端执行pwd确认落在远程主机的当前用户目录下再执行uname -a确认系统架构。这里随手验证架构很重要如果架构不匹配之前可能还有隐藏问题。6.2 高频率复发的三个细节磁盘满、权限变化、版本漂移排障过程中我发现了三个特别容易让人再踩坑的细节。第一个是磁盘空间。server 解压后占用 200MB 以上如果/目录剩余空间不足解压到一半失败IDE 日志里可能只报“无法启动 server”或“连接被关闭”。检查方式df -h ~第二个是权限变化。/opt下的包如果被root掌控普通用户可能无法读取导致 IDE 检测失败。解决方式是确保chmod 755至少覆盖到目录本身并注意配置了 ACL 权限setfacl的目录也可能导致访问异常。第三个是版本漂移。Antigravity 客户端一旦升级commit ID 就变旧 server 目录失效。离线环境下升级等于主动制造故障。建议关闭 IDE 的自动更新或者在内网环境固定使用某个经过验证的版本升级前先在测试机验证。6.3 一个小技巧把 server 状态检查做成别名脚本最后分享一个我一直在用的小技巧。频繁排查时我每次都要敲几条命令去看 server 状态干脆写了一个 shell 函数放进~/.bashrcantg-status() { echo Antigravity server commit 目录 ls -la ~/.antigravity-server/bin/ 2/dev/null || echo no server dir echo 相关进程 pgrep -af antigravity-server|vscode-server || echo no server process echo 离线安装包 ls -lh /opt/antigravity-offline/ 2/dev/null || echo no offline package dir }之后每次连接前先执行antg-status一眼就能看出三件事server 目录在不在、进程有没有活着、离线包是否还在。这套“连接前自查”的流程帮我避开了很多次“连不上才发现文件早没了”的被动局面。
返回列表