Vagrant share浅析
好吧,今天的文章只和程序有关,和人生无关。连续喝了几天大馇子粥,该上点清香逸人的咖啡了。
如果你不知道啥是虚拟机(vagrant是一款虚拟机管理软件),看到这里可以休息休息眼睛,明天的连载传记『途客们的旅行梦』再见。
TL;DR
最近vagrant 1.5升级力度空前,增加了很多新功能,其中最令人瞩目的当属 vagrant share
。啥子意思呢?就是把你的虚拟机share给地球另一端的人。这功能很高大上啊,简直是居家旅行,远程办公的必备武器。你正在做的web app出bug了,需要帮忙?没问题,亲,把虚拟机share一下。
➜ dockerbox vagrant share
==> default: Detecting network information for machine...
...
==> default: URL: http://cheerful-beaver-2087.vagrantshare.com
...
我的虚机里开放了3000端口,是个web app。share好以后,别人就可以使用这个链接:http://cheerful-beaver-2087.vagrantshare.com
,访问程序君正在调试开发的app了。(别试了,当您看到本文时,程序君已经把共享关闭喽)。
很神奇吧?(更有意思的vagrant connect有待你自己去发掘)
这是怎么做到的?
估计你有和程序君一样的问题。程序君开始捣鼓。
首先tcp dump抓包。
➜ appshare git:(master) ✗ tcpdump -i en0
内容很多,就不在这里呈现了。没有太多实质的内容,主要是下面几个步骤:
(1) DNS请求 vagrantcloud.com 获得两个IP: 107.23.21.165, 54.85.101.30
(2) 分别进行https握手(详细内容见知乎)
(3) 传输数据 blablabla(这不废话么)
郁闷的是vagrant考虑到数据安全性,全部采用https,所以无法窥探里面的究竟。
为什么不用Fiddler来偷窥?好吧,fillder基于.net,程序君不想在mac上装mono...
所以程序君只能靠脑子生猜这个功能是怎么实现的了。
我猜我猜...
可能的实现手段:
(1) 使用ssl V**。具体做法:
local http server --- sslV** client ===== SA --- cloud http server
当ssl V** tunnel建立成功后,localp http server和cloud http server间就跟局域网一样可以直接访问。从浏览器访问过来的数据,可以被proxy到local http server,而不用担心网络连接。
不过,vagrant share不是这么实现的。因为建立ssl V**后ifconfig
会看到新的tunnel interface。而vagrant share之后,没有新的interface。
(2) 使用tcp proxy。具体做法:
local http server --- local proxy --- cloud proxy ---- cloud http server
用户从url访问过来的http请求,被cloud http server负载到cloud proxy,然后cloud proxy再将其relay给local proxy,local proxy再relay给local http server;http响应反之。
这个想法比较靠谱。
试着用go简单实现了一下,主要是为了验证想法。结果证实了这个方案可行(我搭了个本机的环境):
local http server (8000) --- local proxy --- (8211) cloud proxy (8211) ---- cloud http server
由于我在测试,所以不需要放一个nginx在cloud http server侧,直接访问:http://192.241.1xx.xx:8211
(我的一台ditalocean服务器)即可。经过两层proxy,local http server的内容被转到浏览器上。当然,目前的代码有问题,local proxy和cloud proxy间只有一个tcp connection,遇到keep-alive的http connection就阻塞住了...然后,然后后续的connection的数据就过不去了(堵车),所以你看到的页面是这样(local http server跑的是我的博客):
哈,给你一个到处都能访问的url,你就可以访问我本机的某个web app了。
方案没有大问题,需要注意的是下面几点:
(1) cloud proxy监听一个端口(如8211),等待http server或者browser过来的http request。
(2) cloud proxy监听另一个端口(如8210),等待local proxy的连接。注意因为local proxy(跑在用户的机器上)没有确定的公网地址,所以cloud proxy只能被动等待连接。
(3) local proxy启动后就要和cloud proxy建立持续的tcp connection。当cloud proxy有数据到达时(http request),cloud proxy才建立和local http server的tcp连接,将http request转至local http server。
(4) 基于以上前提,cloud proxy要先运行起来,然后是local proxy。
另外,如果真要把这个东西做成像vagrant share一样(先不考虑https),则需要:
(1) 自动生成唯一且难以猜测的名字。如 easy-sheep-9048.share.tchen.me
。并且client proxy和cloud proxy能根据它找到二者之间的连接。
(2) 域名提供商能够支持泛域名解析(最好三级域名也支持),dnspod免费版支持二级。
(3) nginx server配置将泛域名作为http request的一个参数传递给cloud proxy,然后cloud proxy可以区分对应的是哪个share。
有空程序君再把它捣鼓好吧。
- Hibernate的缓存机制
- error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http:/
- 【Go 语言 redis内存数据库存储 demo】
- linux下基本操作记录mongodb
- ClassLoader究竟为何物?
- Oracle应用实战八(完结)——存储过程、函数+对象曹组
- 动态代理模式原理
- SQL可以正常用,但cmd启动不了mysql,报错[ERROR] unknown variable ;basedir=....问题
- Percona-toolkit的安装和配置(r8笔记第86天)
- 分布式服务框架 Zookeeper
- python--类方法、对象方法、静态方法
- Go语言内存分配器的实现
- Go 语言 数据库操作之链接数据库实现
- 对于tnsping的连接超时的功能补充(r9笔记第3天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法