使用 Visual Studio Code 进行远程 SSH
2019年7月25日,作者:Sana Ajani, @sana_ajani
Remote - SSH:轻松、流畅,如本地开发一般
如果你错过了,Visual Studio Code 最近发布了 远程开发扩展。这些远程扩展允许你在容器、远程机器或虚拟机 (VM)、或适用于 Linux 的 Windows 子系统 (WSL) 上进行开发,同时使用功能齐全的 VS Code 作为你的开发环境。
无限制:你不再受限于本地计算机
越来越多的开发者在大型复杂项目上工作,这些项目需要他们在专门的开发者虚拟机或服务器上进行工作,因为这些环境能提供比普通笔记本电脑更大的存储空间或计算能力。
然而,这种开发方式也带来了不少挑战
- 如果你使用远程访问软件(如 VNC),在编辑时你可能会感到延迟,因为你的用户界面不再是本地的。
- 如果你使用远程桌面协议 (RDP),管理多个连接可能会变得困难。
- 挂载远程文件系统和执行批量操作可能会很慢。
- 保持远程和本地环境同步很烦人,你经常会遇到在一个地方能正常工作,但在另一个地方却不行的问题。
- 使用 SSH 和 Vim 远程编辑文件意味着你无法再舒适地使用你首选的编码编辑器。
如果能打破本地机器的物理限制,同时又不放弃你惯用的工具,那该多好。现在,Remote - SSH 扩展 的魔力来了。
使用 Linux 进行远程开发
只要你的 Linux 虚拟机支持 SSH,它就可以托管在任何地方;在你的本地主机、本地部署环境、Azure 或任何其他云上。你也可以使用任何客户端——Windows、macOS 或 Linux。
注意:目前尚不支持 macOS 和 Windows SSH 主机。
在这篇博文中,我们将使用 Windows 客户端并以 Azure 上的 Linux 虚拟机为目标。
开始使用
开始前,你需要完成以下准备工作
- 安装一个与 OpenSSH 兼容的 SSH 客户端(不支持 PuTTY)。
- 安装 Visual Studio Code。
- 拥有一个 Azure 订阅(如果你没有 Azure 订阅,请在开始前创建一个免费帐户)。
创建一台虚拟机
如果你没有现成的 Linux 虚拟机,可以通过 Azure 门户创建一个新的虚拟机。在 Azure 门户中,搜索“虚拟机”,然后选择添加。在那里,你可以选择你的 Azure 订阅,并创建一个新的资源组(如果你还没有的话)。
现在你可以指定虚拟机的详细信息,比如名称、大小和基础镜像。本例中我们将选择 Ubuntu Server 18.04 LTS,但你也可以选择其他 Linux 发行版的最新版本,并查看我们支持的 SSH 服务器列表。
设置 SSH
登录虚拟机有多种身份验证方法,包括 SSH 公/私钥对或用户名和密码。我们强烈建议使用基于密钥的身份验证,这样你每次连接时就无需输入密码。如果你在 Windows 上并且已经使用 PuTTYgen 创建了密钥,你可以重用它们。
如果你没有 SSH 密钥对,请打开 bash shell 或命令行并输入
ssh-keygen -t ed25519
这将生成 SSH 密钥。在接下来的提示中按 Enter 键,将密钥保存在默认位置。
然后系统会提示你输入一个安全的密码短语,但你可以将其留空。
将 SSH 密钥添加到你的虚拟机
在上一步中,我们生成了一个 SSH 密钥对。我们将复制 id_ed25519.pub 文件的内容,将其中的公钥粘贴到我们的虚拟机设置中。你还需要允许你的虚拟机接受入站 SSH 流量。
使用 Azure 虚拟机的一个很酷的功能是能够启用自动关机(因为说实话,我们都忘了关掉虚拟机……)。如果你进入管理选项卡,你可以设置每天关闭虚拟机的时间。
选择审阅并创建,Azure 就会为你部署虚拟机!
使用 Remote - SSH 连接
现在我们已经介绍了如何创建 SSH 主机,让我们连接到它吧!
VS Code 的 Remote - SSH 扩展 允许你直接在 VS Code 内部使用 SSH 连接到远程机器或虚拟机。如果你还没有安装 Remote - SSH 扩展,可以在扩展视图 (Ctrl + Shift + X) 中搜索“remote ssh”。
你会注意到状态栏左下角有一个指示器。这个指示器告诉你 VS Code 当前运行的上下文(本地或远程)。点击该指示器会弹出一系列远程扩展命令。
选择 Remote-SSH: Connect to Host 命令,并通过输入虚拟机的连接信息来连接到主机,格式如下:user@hostname
。
user
是你将 SSH 公钥添加到虚拟机时设置的用户名。对于 hostname
,返回到 Azure 门户,在我们创建的虚拟机的概述窗格中,复制公共 IP 地址。
在连接信息文本框中设置用户和主机名。
VS Code 现在会打开一个新窗口(实例)。然后你会看到一个通知,提示“VS Code Server”正在 SSH 主机上初始化。一旦 VS Code Server 安装在远程主机上,它就可以运行扩展并与你的本地 VS Code 实例通信。
通过查看状态栏中的指示器,你就会知道你已经连接到了你的虚拟机。现在它显示的是我们虚拟机的主机名!
Remote - SSH 扩展还会在你的活动栏上增加一个新图标,点击它将打开 SSH 资源管理器。在这里你可以配置你的 SSH 连接。例如,你可以保存你最常连接的主机,并从这里访问它们,而无需每次都输入用户和主机名。
一旦连接到你的 SSH 主机,你就可以与远程机器上的文件和文件夹进行交互。如果你打开集成终端,你会发现你正在一个 bash shell 中工作,而你此时还在 Windows 系统上。等等,我们已经连接到我们的虚拟机了?这也太容易了。这正是重点所在。这些扩展让远程开发感觉轻松、流畅,而且……嗯,不像是远程的。😃
你可以使用 bash shell 浏览虚拟机上的文件系统。用 mkdir demo
创建一个名为“demo”的新文件夹,然后可以通过文件 > 打开文件夹来浏览和打开远程主目录中的文件夹。
你还可以专门在远程 SSH 主机上安装扩展。影响 UI 的扩展,如主题和代码片段,会安装在本地,而其余的扩展则需要安装在远程 SSH 主机上。你会注意到,当你打开扩展视图时,有两个部分,一个是本地机器上的扩展,另一个是远程主机上的扩展。即使你从不同的客户端通过 SSH 连接到你的远程机器,你的远程扩展和设置都将保持不变。当你去安装一个扩展时,VS Code 会自动将其安装在正确的上下文中。
Hello World
让我们在虚拟机上部署一个基本的“Hello World” Python 应用。我们将使用一个流行的 Python Web 框架,名为 Flask。在你的 bash shell 中,运行以下命令。
sudo apt install python3-flask
在你之前创建的“Demo”文件夹中,创建一个名为 app.py
的新文件(Ctrl + N),包含一个基本的 Hello World Flask 应用程序。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello Remote World! :)"
if __name__ == "__main__":
app.run()
一旦 VS Code 将文件语言识别为 Python,如果远程机器上尚未安装Microsoft Python 扩展,你会看到一条推荐安装的通知。
选择安装,重新加载 VS Code,然后你就会在我们的远程机器上看到 VS Code 的 IntelliSense 和语法高亮了。
要运行该应用,请按 F5,并选择 Flask 调试配置。在 Python 调试控制台中,你会看到该应用正在 localhost 的 5000 端口上运行。然而,这里的 localhost 当前指的是远程服务器,而不是你的本地机器。为了能够在你的本地机器上浏览这个 Web 应用,我们将利用另一个名为端口转发的功能。
为了能够访问远程机器上一个可能未公开的端口,我们需要在本地机器上的一个端口和服务器之间建立一个连接或隧道。在应用仍在运行的情况下,打开 SSH 资源管理器,找到已转发的端口视图。点击转发端口链接,并指明我们要转发 5000 端口。
将连接命名为“browser”
服务器现在会将 5000 端口上的流量转发到我们的本地机器。当你浏览 https://:5000 时,你就能看到正在运行的 Web 应用了。
现在,真正的问题是……我们能在远程机器上通过 VS Code 进行调试吗?当然可以!在应用仍在运行的情况下,在返回字符串 "Hello Remote World" 的那一行设置一个断点,然后点击调试控件中的重启按钮。在浏览器中刷新页面,你就会命中那个断点!你获得了与本地开发完全相同的 VS Code 体验,包括编辑、调试以及你所有的设置和扩展。😊
要切换回本地机器进行本地开发,可以通过文件 > 关闭远程连接来关闭远程连接。
使用 Remote - SSH 扩展,你可以在虚拟机上工作,并享用 VS Code 在你远程机器上的所有生产力功能和扩展。无论你的代码托管在哪里,你都能获得在 VS Code 中所熟知和喜爱的全功能开发体验。
如果你想了解更多关于 VS Code 远程开发的信息,可以阅读我们宣布远程开发的博文。你也可以尝试其他的远程扩展,如 Dev Containers 和 WSL,并阅读我们完整的远程开发文档。
远程编码愉快!
Sana Ajani,VS Code 项目经理 @sana_ajani