出于安全或性能等原因,公司将开发环境部署在了内网云环境中,内网云环境与外网完全隔离,且所有的开发环境资源(如数据库、Redis等)只能通过内网云环境访问,本地物理机无法直接访问这些测试资源,只能通过RDP协议间接访问内网云环境中的桌面,这给开发工作带来了极大的不便。为了能够直接在本地物理机进行开发,接下来将介绍4种远程开发的方法:

  1. 使用nginx反向代理持续暴露远程资源
  2. 使用ssh转发临时暴露资源
  3. 使用Microsoft的Visual-Studio-Code远程开发工具
  4. 使用Jetbrains的Projector或Gateway远程开发工具

本文中的远程开发指的是:通过本机访问远程资源的过程。其中,“本机”是指本地物理机(假定本地物理机的ip为172.8.8.8),“远程”是指内网云环境(假定远程主机的ip为172.6.6.6,操作系统为ubtunu,用户名为ubuntu)。

一、nginx反向代理

在远程环境配置nginx相关服务的反向代理策略,便可以在本机访问那些只能在远程环境访问的资源了。具体配置方式如下:

如果不加特殊说明,下述操作均在远程环境中进行!

  1. 安装nginx

    sudo apt install nginx
    
  2. 配置nginx

    sudo vim /etc/nginx/nginx.conf
    
    load_module /usr/lib/nginx/modules/ngx_stream_module.so;
    
    events {
    }
    
    http {
    
        server
        {
            listen 80;
            server_name http.resource.com;
            location / {
                proxy_pass http://http.resource.com:80;
            }
        }
    
        server
        {
            listen 443;
            server_name https.resource.com;
            ssl on;
            ssl_certificate /etc/nginx/nginx.crt; # sudo openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /etc/nginx/nginx.key -out /etc/nginx/nginx.crt
            ssl_certificate_key /etc/nginx/nginx.key;
            location / {
                proxy_pass https://https.resource.com:443;
            }
        }
    
    }
    
    stream
    {
        server
        {
            listen 6666;
            proxy_pass tcp.resource.com:6666;
        }
    
    }
    
  3. 启用nginx服务

    sudo systemctl start nginx
    sudo systemctl enable nginx
    
  4. 本机配置hosts

    sudo vim /etc/hosts
    
    172.6.6.6 http.resource.com
    172.6.6.6 https.resource.com
    172.6.6.6 tcp.resource.com
    
  5. 本机访问远程资源

    curl http://http.resource.com
    curl https://https.resource.com
    telnet tcp.resource.com 6666
    
  6. 其它可选配置:访问控制

    nginx支持通过allow和deny配置ip白名单和黑名单,达到访问控制的目的。

    sudo vim /etc/nginx/nginx.conf
    
    http {
        allow 172.8.8.8.; # 本机ip
        deny all;
        #...
    
        server {
            allow 172.8.8.8.;
            deny all;
            # ...
        }
    

    allow与deny分别表示白名单和黑名单,上述配置表示除了172.8.8.8能访问这台服务器外,其它的ip都不允许访问。其中,server会覆盖http级别的allow和deny配置。

    为了更进一步地控制,也可以使用系统的防火墙,如iptables、ufw等等。

  7. 其它可选配置:泛域名统一转发

    正常情况下,一个server只能配置一个域名的转发。泛域名统一转发支持相同域名前缀或后缀(如company.com)的所有域名,只需要使用一个server,就可以完成统一的转发,以简化server的配置。

    sudo vim /etc/nginx/nginx.conf
    
    server
    {
        listen 80;
        resolver 127.0.0.53; # 配置域名解析服务
        server_name *.company.com; # 泛域名
        location / {
            proxy_pass http://$host; # 直接转发到server_name对应的域名
        }
    }
    

    其等价于:

    {
        listen 80;
        server_name a.company.com; 
        location / {
            proxy_pass http://a.company.com;
        }
    }
    {
        listen 80;
        server_name b.company.com; 
        location / {
            proxy_pass http://b.company.com;
        }
    }
    {
        listen 80;
        server_name c.company.com; 
        location / {
            proxy_pass http://c.company.com;
        }
    }         
    

    可以看到,泛域名统一转发要简洁地多。假设nginx所在的主机已经有了a.company.com、b.company.com、c.company.com的dns记录(如果没有,在nginx所在的主机配置host即可),那么上述配置将直接支持所有相关域名的转发。随后,配置本机host:

    172.6.6.6 a.company.com
    172.6.6.6 b.company.com
    172.6.6.6 c.company.com
    

    本机访问即可自动转发到真正的*.company.com:

    curl http://a.company.com
    curl http://b.company.com
    curl http://c.company.com
    

二、ssh转发

ssh转发分为本地转发与远程转发两种方式:

  1. 本地转发:在本地开一个端口,并通过这个端口访问远程服务,适用于将远程资源转发到本地的情况(这里的远程资源包括远程主机自己的服务资源,也包括远程主机能够访问到的其它主机的服务资源)。
  2. 远程转发:在远程开一个端口,并通过这个端口访问本地服务,适用于将本地资源转发到远程的情况(这里的本地资源包括本地主机自己的服务资源,也包括本地主机能够访问到的其它主机的服务资源,如:外网资源等)。

(一)ssh本地转发

  1. 在本机启用本地转发

    ssh -L 8080:http.resource.com:80 ubuntu@172.6.6.6 -N
    

    -L表明启用ssh本地转发。这里将http.resource.com:80远程资源转发到了本机的8080端口。

  2. 在本机配置hosts

    sudo vim /etc/hosts
    
    127.0.0.1 http.resource.com
    
  3. 在本机访问远程资源

    curl http://http.resource.com:8080
    

(二)ssh远程转发

  1. 在本机启用远程转发

    ssh -R 8080:www.baidu.com:443 ubuntu@172.6.6.6 -N
    

    -R表明启用ssh远程转发。这里将www.baidu.com:443本机资源转发到了远程的8080端口。

  2. 在远程环境配置hosts

    sudo vim /etc/hosts
    
    127.0.0.1 www.baidu.com
    
  3. 在远程环境访问本地(外网)资源

    curl https://www.baidu.com:8080
    

三、vscode远程开发

Visual-Studio-Codevscode)可以通过Remote插件(主要是Remote-SSH插件)来进行远程开发。

  1. 安装Remote插件

    在本机vscode的扩展中搜索Remote,找到对应项安装即可。

  2. 在本机下载vscode-server

    正常情况下,首次使用Remote连接远程环境时,远程环境会自动下载服务端vscode,但由于当前的远程环境没有外网的网络策略,因此,需要本地下载服务端vscode之后传输到远程环境进行离线安装。

    export VSCODE_COMMIT_ID=$(code -v | sed -n '2p') # 如果vscode的commit_id获取失败,请打开vscode,点击帮助,再点击关于,手动获取commit_id
    wget https://update.code.visualstudio.com/commit:$VSCODE_COMMIT_ID/server-linux-x64/stable -O vscode-server-linux-x64-$VSCODE_COMMIT_ID.tar.gz # 下载vscode-server
    scp vscode-server-linux-x64-$VSCODE_COMMIT_ID.tar.gz ubuntu@172.6.6.6:/home/ubuntu # 上传vscode-server
    
  3. 在远程环境离线安装vscode-server

    export VSCODE_COMMIT_ID=$(ls ~/vscode-server-linux-x64-* | cut -d '-' -f 5 | cut -d '.' -f 1)
    mkdir -p ~/.vscode-server/bin/
    cd ~/.vscode-server/bin/
    mv ~/vscode-server-linux-x64-*.tar.gz .
    tar zxvf vscode-server-linux-x64-*.tar.gz
    mv vscode-server-linux-x64 $VSCODE_COMMIT_ID
    
  4. 在本机vscode中连接远程环境

    在vscode中点击远程资源管理器,在SSH Target项点击+,输入ssh ubuntu@172.6.6.6 -A,回车,选择/home/xxx/.ssh/conf,回车。在SSH Target下的172.6.6.6项点击右边图标,进入远程环境

    至此,后续所有开发操作均和本地vscode操作一致了,如果需要支持特定语言,则需要安装对应插件(如:java)。

四、jetbrains远程开发

Jetbrains旗下有两款远程开发方案:ProjetctorGateway

(一)Projetctor远程开发

  1. 在远程环境安装projetctor服务端

    docker pull jetbrains/projector-idea-c
    docker run --rm -p 8887:8887 -it jetbrains/projector-idea-c
    

    有三种方式安装projetctor服务端:python方式(projector-installer)、idea插件方式projector-server-plugin、docker方式(projector-docker),这里以docker方式为例。

    如果云环境无法访问docker仓库,可以使用ssh远程转发临时代理docker仓库

  2. 在本机连接projetctor服务

    有两种方式可以连接projetctor服务:

(二)Gateway远程开发

详见Gateway官方教程