在容器终端里成功的下载,只能真实反映该终端的环境。它说明不了编辑器进程、扩展安装器,也说明不了扩展随后拉取的二进制文件。在这三者之间复制代理变量,会把一次失败的请求变成一下午的无关改动。

两种环境通常只在一个点上不同。找到这个点,比读两遍代理文档更快。

失败请求由哪个进程发出

一次安装过程中可能有三类请求失败,而它们各有自己的网络身份。编辑器先向 Marketplace 索取元数据和包 URL,然后下载安装包。之后扩展宿主才会运行代码,去拉取语言服务器或自带的二进制。坏在哪一步,决定了哪个进程需要代理,而错误界面很少点明这一步。

终端能用,只证明容器能上网,不证明编辑器能上网。去扩展日志里找它最后尝试的 URL。那里出现的主机名,能确定是哪个进程、适用哪条策略。

本地编辑器与远程容器是两个环境

在远程工作区里,扩展运行在它类型声明的那一侧。界面扩展留在本地编辑器,工作区扩展在容器里运行。在一边设的代理,另一边看不到;而重建会用配置文件重建容器环境,而不是用你在 shell 里导出的变量。这条分界解释了为什么同一个扩展在笔记本上装得上,在同一个项目里走 SSH 却失败。

动手之前先读安装位置。当日志报告的是远程安装时,起作用的是容器环境。

把代理放在请求发起的地方

对确实需要 HTTP 代理的 Dev Container,变量应写进容器配置,这样重建才能复现。下面的片段就是为该环境设置。占位地址代表你自己的网关,排除项不是可有可无的填充。

"containerEnv": {
  "HTTP_PROXY": "http://proxy.corp.example:8080",
  "HTTPS_PROXY": "http://proxy.corp.example:8080",
  "NO_PROXY": "localhost,127.0.0.1,.internal.example"
}

变量名描述的是目标协议,所以 HTTPS_PROXY 的值完全可以以 http 开头。通过受支持的重建路径应用改动,并保留排除项,因为拦截内部主机的代理会弄坏容器依赖的服务。

把信任失败与可达性分开

能连上、随后返回证书校验错误的代理,比直接拒绝连接的代理走到了更靠后的一步。前一种失败需要把组织批准的信任材料装进发起请求的环境。后一种需要可达的地址和端口。把两者当成一个问题,得到的修法对两者都不管用。

关闭校验,或者用提权方式运行编辑器,都不是缺代理、缺信任链的修法。两者都是把显眼的错误换成无声的错误。之后再试同一个扩展,记下下一个失败的 URL。

env | grep -iE '^(http|https|no)_proxy='
code --install-extension ms-python.python --force

记下这个 URL 是工作区哪一侧产生的。一行写明步骤、主机和侧别的小注,比一份别人改过的设置清单更有价值,因为下一个人能复现的正是这条注释。

相关文章