作为长期从事数据科学相关工作的人,作者很喜欢便捷的工作环境,并为此探索出来一些小技巧。通过这些技巧,可以将日常一些重复性或者枯燥的简单工作变得「自动化」,使计算机的工作环境更加友好。
过去几年里,我一直从事数据科学/研究项目,本科就做了一些与这个行业相关的工作,现在是研究生在读,也在做这方面的研究。作为一个喜欢便捷环境的人,我总是喜欢改进我的工作方式,将日常的枯燥过程变得「自动化」。在这篇文章中,我将描述如何使环境更便于使用。
我使用的设置包含以下组件:
- 个人电脑(Linux 发行版)
- 网关
- 远程服务器
由于我研究的项目计算量巨大,笔记本电脑无法负担。因此,我需要这些机器辅助我。出于安全原因,远程服务器无法直接访问,这意味着它们只能由网关机器访问。
连接服务器的基本方法是首先将 ssh 连接到网关,然后将 ssh 连接到服务器,每次连接时都需要输入用户名和密码。输入一遍又一遍是相当麻烦的。现在我将介绍如何使用单个命令轻松连接到两个服务器。
充分利用 SSH
关于 SSH
SSH是一种安全协议,允许用户控制他们连接的服务器。使用 ssh 连接到远程服务器的常用方法是使用以下命令:ssh user@host,然后获得一个密码提示符。在这篇文章中,我不会详细介绍 ssh 的工作原理,只是利用 ssh 基本的使用知识。
无需密码即可连接
首先创建一个认证密钥,并将公共密钥传输到我们想连接的服务器。我们从设置连接开始——从笔记本电脑到网关。
我们将使用一个名为 ssh-copy 的小软件。它为我们完成所有工作,我们需要做的就是在终端中键入以下命令:
- ssh-keygen -t rsa # create an SSH key, if needed.
- ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
- Linux 用户应该已经安装了这个软件。
- Mac 用户需要通过命令 brew install ssh-copy-id 安装 ssh-copy 工具。
ssh-copy-id 命令将 SSH 密钥复制到服务器,如果需要,创建相应的 文件夹,将公钥作为授权密钥添加到服务器的.ssh / authorized_keys 文件中。
如果由于某种原因这不起作用,只需复制粘贴以下命令,这基本就是 ssh-copy 的作用:
打开终端并运行以下步骤:
- 生成一对认证密钥。系统将要求你输入任意密码。ssh-keygen -t rsa
- 在远程计算机上创建一个 文件夹(如果已存在则无需创建)ssh user@host mkdir -p .ssh
- 将之前生成的公钥添加到远程计算机。cat .ssh/id_rsa.pub | ssh user@host 'cat >> .ssh/authorized_keys'
OK!从现在开始,你无需密码即可轻松访问服务器。
- ssh user@host
要从网关连接服务器,遵循相同的步骤(如果尚未配置)。
方便的 SSH
现在要做的是进阶版。与每次 ssh 都使用完整主机名+用户名不同,我们可以使它更方便——无论是网关或代理机器。
在本地计算机的~/.ssh/config 文件下插入以下内容:
- Host gate
- HostName [gateway.name]
- User [user]
- Host work1
- HostName [machine.name]
- user [user]
- ProxyCommand ssh gate nc %h %p
还有一个有用的配置参数名为「IdentityFile」,它在处理多个公钥/私钥对时非常有用。假设你除了个人账户外,有一个 github 的工作帐户。那你就需要另一个公钥-私钥对,但你还是需要一个方便的接口。以下是在配置文件中进行设置的示例:
- Host company-github
- User git
- HostName company.github.com
- IdentityFile ~/.ssh/github.comp.key
每个 ssh 连接将使用匹配的密钥进行连接。
为了使每个服务器轻松连接,我们可以以类似的方式添加所有远程服务器。
现在,只需要简单的命令 ssh gate 或 ssh work1,就可以直接连接到网关或 work1 服务器,无需任何密码或其它连接。
隧道(Tunneling)
现在我们可以方便地访问远程服务器,然后可以使用隧道来实现对计算机中服务器资源的无缝访问。这样,我们可以在远程机器(具有大量内存)上运行 Jupyter notebook,并在浏览器上与它进行交互。它可以实现如下功能:
- 关闭计算机,并保持 notebook 在服务器上运行。
- 从另一台计算机也可以打开和访问同一 notebook。
- 保持模型可在远程服务器上加载。即加载一次即可访问(或直到管理员重启)。
例如,如果我们想在端口 9100 上打开服务器 work1 上的 notebook,可以使用以下命令打开到端口 9200 上的计算机的隧道:
- *ssh* *-N* *-f* *-L* *localhost*:9200:localhost:9100 *work1*
有趣的隧道
现在你已经了解如何设置隧道,你可以一直使用这个技巧(至少我一直这样做)。现在以 Jupyter notebook 和 Tensorboard 为例做一个演示。Tensorboard 服务器不会消耗很多资源,但 notebooks 有时会。由于不同的项目使用的机器不同(为平衡负载),因此会使用不同的隧道,所以我有时不记得哪个端口用于什么应用,更不用说在哪个服务器上了。
最终,我们转向自己的机器,控制的变量是端口号,而这些数字很快会被遗忘。我最近找到了一部分解决方案。我没有在 localhost:xxxx 上打开应用程序,而是生成了新的域名,这些域名只转发到 localhost 主机。这虽然没有解决端口问题,但现在每个应用程序都有自己的名称,没有混淆,在使用一两次后,现代浏览器就会记住端口,所以你只需记住你为每个程序起的名称即可。
要进行域转发,请执行以下操作:
- 使用 sudo [vim|nano|...] /etc/hosts 打开/etc/hosts 文件
- 你应该在某处(可能在顶部)发现这一行:127.0.0.1 localhost
- 复制该行,使用你为应用程序取的名字替换 localhost 的名称(例如,tensorboard)。
现在你可以在 tensorboard:8100 上找到 tensorboard 应用。
但端口问题仍然没有解决,欢迎提出建议。
更多便捷技巧
保持 SSH 打开
如果你已经使用隧道一段时间,你可能发现如果闲置几分钟后,隧道往往在不工作时都会断开连接。如果你同时在处理好几件事,而没有一直使用隧道,那这个重复连接的工作真的很烦人。通过在 ssh 配置文件中添加一行简单语句,这个问题就可以很容易解决。这样,每隔 x 秒,一个'唤醒(sign-of-life)'信号会被发送到服务器上。在本地计算机上,编辑 /etc/ssh/ssh_config 文件(带有 sudo)并在 Host *行后输入以下行:
- ServerAliveInterval 120
这适用于所有 ssh 连接。如果不想所有的 ssh 都保持连接,则可以通过给~/.ssh/config 配置文件添加相同的行来仅连接特定的 ssh。配置如下:
- Host gate
- HostName gateway.name
- User user
- IdentityFile ~/.ssh/gateway
- ServerAliveInterval 120
Autossh
现在,隧道在不工作时也不会关闭,事情看起来很顺利。但当你准备睡觉(人总要休息啊)时,你就会暂停/休眠你的电脑(不是关机)。第二天,你想重新开始工作,你在本地计算机上准备打开隧道时发现,...... 连接已关闭,你需要重新打开它。这也让人心累不是吗?幸运的是,这也有解决方案!
关于 autossh:http://www.harding.motd.ca/autossh/
这个绝妙的程序将保证你的 ssh 连接一直开启,除非关闭计算机。只要没有关机,ssh 就一直是连接着的。例如,你可以将计算机置于休眠状态,断开 Wifi 等连接,但一旦重新联机,此程序将重新为你连接 ssh。
通过运行以下行来安装 autossh:
- sudo apt-*get* install autossh
现在运行以下命令:
- *autossh* *-M* 20000 *-N* *-f* *-L* *localhost*:9201:localhost:9100 *work1*
这与我们之前看到的命令非常相似,除了命令名称(duh)和 -M 20000 标志(这是显示器所在的端口)。
IntelliJ 集成
在 Pycharm 专业版中,有一个很好的功能,即可以连接远程服务器并直接在上面工作。你可以在自己的计算机上编写代码,在远程服务器上运行代码,或者在远程服务器上完全同步整个存储库。
interlliJ 界面会不时变化,但主题不变。我将介绍特定版本 - V. 2018.1.4 的步骤。
- 进入 Pycharm 的设置界面
- 构建,执行,部署 - >部署
- 单击绿色+,创建新的部署设置
- 输入相关信息(名称、主机、端口(通常为 22)、根路径和用户名)
现在右键点击项目文件夹,在部署键下,你可以上传、下载项目或使其与远程位置同步(可以设置快捷键)。
使用远程解释器:
- 进入项目设置栏
- 在项目解释器标记下(在项目解释器选项附近,有一个小齿轮按钮)。单击它,然后点击「添加」。
- 在左侧菜单中,单击 SSH 解释器
- 单击「现有服务器配置」选项,使用我们之前创建的部署配置。
- 选择远程解释器(例如 anaconda / python)
- ... 全部完成