赞
踩
本文将介绍“局域网下远程ide式开发”、“公网下远程ide式开发”、“局域网下远程容器的ide式开发”、“公网下远程容器的ide式开发”这四种开发流程,让你无论在工位上还是在家中,都可以像打开本地ide那样进行远程的项目开发。
最方便、最开始的开发方式当然是在本地ide中,比如初学者在Windows电脑上使用pycharm来学习python、深度学习,或者使用devc++、visual studio等来编写c++项目。在本地ide中,可以浏览文件夹、查看文本和图片等,进一步还可以运行调试python、C++等项目。这样的开发过程称为“ide式开发”,初学者会觉得这些都是理所当然的。
但是随着能力的提升、需求的扩大,我们需要使用Linux系统来进行开发,甚至是纯服务器形式的linux,连显示屏都没有。此时我们会初步接触ssh,连上linux服务器的终端,然后通过敲命令的方式来执行一些程序的运行,查看结果。注意只连终端是不可能进行代码编写、调试等步骤的,更别说看图片啥的。此时的做法应为在本地机写好代码,再通过ftp传输到服务器上运行。不过这也算入门linux中的项目开发了。
但是这种方式太low了,就不能实现windows里ide式开发的效果吗?可以的!借助强大的vscode的remote-ssh插件,同样是ssh连接服务器的22端口,却可以实现ide式开发,这样就可以愉快的点来点去和调试代码了。想实现这个功能请搜索“vscode远程连接linux”,或“vscode remote-ssh连接linux”等教程。
在这个环节,我们应该对ssh的原理、公钥私钥的概念与使用有所了解,还需要了解sshd_config中各项配置的含义。
再进一步,我们会有居家办公的需求,比如现在疫情比较频繁,在家里没有了公司wifi,脱离了局域网环境,我们是无法像以前那样连接linux服务器的,因为ip是内网中的,而我们处在家中的话还去连那个ip,肯定就不对了。此时需要借助“端口转发”,或者说“内网穿透”工具来把处在公司内网的linux服务器的22端口暴露在公网环境中。对于计算机网络不太好的同学来说不论是理解还是实现这一功能都是比较困难的。
所谓内网穿透,就是借助处在公网中的服务器作为中介,让公司的linux服务器和家里的windows电脑都连接上公网服务器,windows向中介发送“sudo apt install vim”命令,中介就把这句话转发给公司linux服务器,公司linux服务器就会执行这个命令,然后返回“successfully installed vim.”信息给中介,然后中介再把这条信息传递给windows电脑,于是整体效果就是win端输入sudo apt install vim,接着显示successfully installed vim.这就是内网穿透。在内网穿透基础上,通过vscode的remote-ssh配置一下,就能实现公网下远程ide式开发。
内网穿透要注意的细节是比较多的,为了方便大家实现,也为了以后自己在新设备上复现,我做一些详细的说明。
整个内网穿透流程如下
在具体实施上,有3个环节要做:
1、购买并设置好拥有公网ip的阿里云服务器,在控制台的安全组中(并非在服务器内部,而是在阿里云控制台中)开放相应端口
2、在阿里云服务器上安装ssh, 安装frp,完成frps.ini的配置,开启防火墙,开放相应端口,frps服务添加至自启动并开启
3、在公司内网服务器上安装frp,完成frpc.ini的配置,开放相应端口,开启ssh,frpc服务添加至自启动并开启。
具体说明:
我买的是1核2g cpu,1Mbps带宽,100G容量的ecs.n4.small服务器,1年84元,服务器会提供一个公网ip(无论在哪个网络环境下都可以凭借公网ip访问云服务器,假设此ip为89.67.45.200)。在阿里云控制台的安全组的出和入里面添加服务端的反向代理监听端口(7000),映射端口(6000),为了后续的别的设备的端口转发,可以多开几个端口
具体可参考这里
apt install openssh-server
systemctl start firewalld
firewall-cmd --add-port=7000/tcp --permanent
firewall-cmd --add-port=6000/tcp --permanent
firewall-cmd --add-port=6001/tcp --permanent
firewall-cmd --reload
mkdir /root/apps && cd /root/apps
wget https://github.com/fatedier/frp/releases/download/v0.34.3/frp_0.34.3_linux_amd64.tar.gz
tar -xvf frp_0.34.3_linux_amd64.tar.gz
cd frp_0.34.3_linux_amd64
将frps.ini内容改为
[common]
bind_addr = 0.0.0.0
bind_port = 7000
token = 1234
frps表示server端的frp,同理frpc表示client端的frp。
其中bind_port表示监听端口。一个中介服务器可以同时完成多个设备的端口转发,但是监听端口只能有一个。
token表示密码,别的设备想让中介转发端口,得有这个密码
将sysytemd下的frps.service内容改为
[Unit]
Description=Frp Server Service
After=network.target
[Service]
Restart=on-failure
RestartSec=5s
ExecStart=/root/apps/frp_0.34.3_linux_amd64/frps -c /root/apps/frp_0.34.3_linux_amd64/frps.ini
[Install]
WantedBy=multi-user.target
然后执行
cp ./systemd/frps.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable frps
systemctl start frps
这样的话中介就配置好了
apt install openssh-server
mkdir /home/user/apps && cd /home/user/apps
wget https://github.com/fatedier/frp/releases/download/v0.34.3/frp_0.34.3_linux_amd64.tar.gz
tar -xvf frp_0.34.3_linux_amd64.tar.gz
cd frp_0.34.3_linux_amd64
将frpc.ini内容改为
[common]
server_addr = 89.67.45.200
server_port = 7000
token=1234
[linux_in_company]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
server_addr表示中介的公网ip,server_port 是中介的监听端口,linux_in_company是这台linux服务器在中介那里的命名,如果有多个设备要用中介来转发端口,这个命名不可以重复
local_port 表示Linux服务器中要转发出去的端口,22表示终端
remote_port 是中介上的映射端口。win电脑访问中介的6000端口就能起到访问Linux服务器22端口的效果
然后做自启动,修改systemd下的frpc.service
[Unit]
Description=Frp Client Service
After=network.target
Wants=network.target
[Service]
Restart=on-failure
RestartSec=5s
ExecStart=/home/user/apps/frp_0.34.3_linux_amd64/frpc -c /home/user/apps/frp_0.34.3_linux_amd64/frpc.ini
ExecReload=/home/user/apps/frp_0.34.3_linux_amd64/frpc reload -c /home/user/apps/frp_0.34.3_linux_amd64/frpc.ini
[Install]
WantedBy=multi-user.target
再
cp ./systemd/frpc.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable frpc
systemctl start frpc
到这一步就很简单了。
ssh user@89.67.45.200 -p 6000即可,想登root就改成ssh root@89.67.45.200 -p 6000,后面相应的输root的密码即可。有时记得sudo的密码却忘了su的密码咋整?sudo passwd root重置root密码即可
此外,还可以通过密钥对来进行免密登陆,这里不做赘述
随着能力的进一步提升,我们不得不面临越来越困难、复杂的环境配置过程,比如cuda,tesnorrt的安装与更换版本等。很多时候,目的是C,但是为了做C要先把A和B这两个配置环境的环节给踩一遍,随着这种情况的增多,我们就会发现原先简单的linux服务器变得越来越庞大复杂,里面配置了各种各样的环境,复杂到,尝试更新显卡驱动失败了,导致很多东西都得跟着完蛋,最后连pytorch模型都跑不起来。
所以,我们直接在服务器本体上进行各种环境的配置与项目的开发有两个缺点:其一是耗时间,有的东西的确没必要搞这么清楚,如果有现成的直接用当然最好;其二是环境间容易相互影响产生依赖,一个出问题了其他都得完蛋。
在这种问题的驱动下,容器内的项目开发流程应运而生:我们打开Linux服务器,并不直接在其上面进行环境配置与代码编写调试,而是再在linux中创建容器并进入,在容器中去进行开发。一进容器,各种需要的环境已经为你准备好了,比如英伟达官方的pytorch容器,里面就配好了cuda,cudnn,pytorch,tensorrt等等,这就为我们节省了大量宝贵的时间。再者,在容器里面不管你怎么折腾,只要别把挂载文件夹里的东西乱删,那都没事,丝毫不影响容器外部的linux服务器。不小心把容器搞坏了,再run一个,一切照常。
而想要实现远程容器的ide式开发也很简单,只要在创建容器时增加端口映射即可,比如docker run … -p 6666:22 …,然后在容器中安装好ssh,开启服务,这样的话访问linux服务器(称为host)中的6666端口就等同于访问容器的22端口了。
所以只需把“1.1 局域网下远程ide式开发”中的ssh指令的用户名改为root,端口改为6666,即可在vscode中通过局域网来实现远程容器的ide式开发。
有了“1.2 公网下远程ide式开发”和“2.1 局域网下远程容器的ide式开发”的基础,公网下远程容器的ide式开发就变得非常简单:在公司linux服务器中的frpc.ini中增加一个端口转发请求,把6666端口转发到中介的6001端口,这样的话ssh root@89.67.45.200 -p 6001就会先转到linux服务器的6666端口,再转到容器的22端口,成功在家中进行公司服务器中容器的ide开发
不过要注意,ssh连之前要先在linux服务器中运行该容器,并通过/etc/init.d/ssh start开启ssh服务。这个环节可以使用容器的初始脚本来完成,首先在linux服务器上找个地方写一个脚本~/code/start.sh
#! /bin/bash
if [ -f "/etc/init.d/ssh" ]; then
echo "ssh OK"
/etc/init.d/ssh start
else
echo "ssh not installed. Start intallation."
/code/install_ssh.sh
fi
/bin/bash
然后chmod 777 ~/code/start.sh
其中安装ssh的脚本如下,没个容器情况不同,所以仅供参考
#! /bin/bash
cd /
echo -e "deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse\n" >> sources.list
cp sources.list /etc/apt/sources.list
apt update
apt install -y --allow-downgrades openssh-client=1:7.2p2-4ubuntu2.10
apt install -y openssh-server
echo "ssh installed. Now you need to configure it."
然后chmod 777 ~/code/install_ssh.sh
接下来创建容器!
docker run --gpus all -it -p 6666:22 --name trt -v ~/code:/code nvcr.io/nvidia/tensorrt:21.10-py3 /bin/bash /code/start.sh
我来详细解读一下这条指令:
run就是从镜像创建容器,–gpus all就是把host的所有gpu都开放使用权利,-it就是以交互模式运行容器并为其分配一个终端命令行,-p 6666:22就是把容器的终端端口22映射到host的6666端口,–name trt就是给这个容器命名为trt,-v ~ /code:/code就是把host的~/code文件夹挂载到容器中的/code文件夹。nvcr.io/nvidia/tensorrt:21.10-py3就是镜像的名字,/bin/bash /code/start.sh表示一创建容器就用bash执行这条start.sh脚本,而且start.sh脚本末尾还有一行“/bin/bash”就是说执行完安装或开启ssh脚本后,执行bash,留着终端这个程序,不然容器会自动退出。
这样就可以做到一开启容器,就能自动开启ssh啦
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。