Cloud Foundry中vmc tunnel与caldecott原理
在Cloud 中,用户可以vmc -创建一个 ,但是常规情况下,用户不能手动地进一步对 进行设计。以MySQL为例,用户可以创建一个MySQL ,但是一般情况下,用户不能直接对整个MySQL的进行设计,或者进行增删改查的操作。对于MySQL 的内部操作,都是由部署在Cloud 上的app应用程序来完成的。
为了可以使得用户在Cloud 外部,对该用户创建的 进行设计或者增删改查的操作,Cloud 的指令客户端vmc通过vmc 指令来实现。以MySQL为例,vmc 最直接的功能就是:允许用户在Cloud 外部的MySQL 对MySQL node上的 进行设计或者增删改查的操作。
该文档主要基于Cloud v1版本,vmc版本为0.3.18 。
以下是具体实现流程:
上图为vmc与Cloud 的Cloud ,DEA,MySQL node等组件的交互图。该图的应用背景为:已经创建完一个MySQL ,需要通过vmc 来完成用户对该MySQL 的内部操作。以下为vmc 指令执行过程中所涉及的操作。
步骤1:用户通过vmc向Cloud 部署一个app应用。vmc获取app应用的配置信息,并与该应用的程序代码发送给Cloud 的Cloud 。
步骤2:Cloud 接受到用户的vmc请求后,成功在DEA上部署应用,并启动该应用。
步骤3:vmc发送绑定请求给Cloud ,将应用与需要执行内部操作的MySQL 进行绑定。
步骤4:Cloud 将该MySQL 的与该应用的脚本,程序代码放在一起重新打包,并在DEA中启动。
以上4个步骤均为简单的vmc push以及vmc bind-操作,了解的Cloud 应用部署的开发者一定不会感到陌生。
以下是vmc如何通过应用与MySQL 进行交互。在介绍实现机制之前,先来了解一下这个应用程序的功能与框架。
应用
首先该应用是一个框架的应用。在功能上,主要分为两个部分:第一,接收vmc发送来的http请求,并从该应用的环境变量中获取绑定的 的信息,并将这些 的返回给vmc;第二,接受vmc的 发送来的建立请求,本身作为一个 建立与 的连接之后,将发送来的内容再发给mysql 。以下为应用程序的大部分ruby代码:
# add vcap specific stuff to Caldecott
class VcapHttpTunnel < Caldecott::Server::HttpTunnelget '/info' do{ "version" => '0.0.4' }.to_jsonenddef self.get_tunnelssuperendget '/services' doservices_env = ENV['VMC_SERVICES']return "no services env" if services_env.nil? or services_env.empty?services_envendget '/services/:service' do |service_name|services_env = ENV['VMC_SERVICES']not_found if services_env.nil?services = JSON.parse(services_env)service = services.find { |s| s["name"] == service_name }not_found if service.nil?service["options"].to_jsonend
endVcapHttpTunnel.run!(:port => port, :auth_token => ENV["CALDECOTT_AUTH"])
紧接着步骤4,vmc通过应用操作MySQL :
步骤5:vmc通过请求,向索取已绑定 的信息。
步骤6:从环境变量中读取的,并将其返回给vmc。
步骤7:vmc在用户的机器上开辟一个端口,并使用该端口,的url, 的host以及port来创建一条。创建的发起者为::,该连接的接受者为::,也就是部署在DEA上的应用的第二个功能,如以上代码继承部分与最后一行。其中vmc端的创建连接代码如下:
def start_tunnel(local_port, conn_info, auth)@local_tunnel_thread = Thread.new doCaldecott::Client.start({:local_port => local_port,:tun_url => tunnel_url,:dst_host => conn_info['hostname'],:dst_port => conn_info['port'],:log_file => STDOUT,:log_level => ENV["VMC_TUNNEL_DEBUG"] || "ERROR",:auth_token => auth,:quiet => true})endat_exit { @local_tunnel_thread.kill }
end
步骤8:应用作为一个::,建立一条与MySQL 的。
以上的8个步骤,实现了Cloud 的外部用户通过vmc与部署在Cloud 上的应用建立与MySQL 的连接。
完成了以上的操作,当用户执行mysql指令时,执行“mysql --=TCP --host= --port=10000 --user= --= ”。其中10000为本机与创建的端口号,所以该请求会通过::发给应用中的::,而::又会将请求发给MySQL ,最后由MySQL 解析执行并返回结果。