在Cloud Foundry中,用戶可以vmc create-service創建一個service instance,但是常規情況下,用戶不能手動地進一步對service instance進行設計。以MySQL爲例,用戶可以創建一個MySQL instance,但是一般情況下,用戶不能直接對整個MySQL的database進行schema設計,或者進行增刪改查的操作。對於MySQL service instance的內部操作,都是由部署在Cloud Foundry上的app應用程序來完成的。
爲了可以使得用戶在Cloud Foundry外部,對該用戶創建的service instance進行schema設計或者增刪改查的操作,Cloud Foundry的指令客戶端vmc通過vmc tunnel指令來實現。以MySQL爲例,vmc tunnel最直接的功能就是:允許用戶在Cloud Foundry外部的MySQL client對MySQL node上的service instance進行schema設計或者增刪改查的操作。
該文檔主要基於Cloud Foundry v1版本,vmc版本爲0.3.18 。
以下是具體實現流程:
上圖爲vmc與Cloud Foundry的Cloud Controller,DEA,MySQL node等組件的交互圖。該圖的應用背景爲:已經創建完一個MySQL instance,需要通過vmc tunnel來完成用戶對該MySQL instance的內部操作。以下爲vmc tunnel指令執行過程中所涉及的操作。
步驟1:用戶通過vmc向Cloud Foundry部署一個app應用caldecott。vmc獲取app應用的配置信息,並與該應用的程序代碼發送給Cloud Foundry的Cloud Controller。
步驟2:Cloud Controller接受到用戶的vmc請求後,成功在DEA上部署應用caldecott,並啓動該應用。
步驟3:vmc發送綁定請求給Cloud Controller,將caldecott應用與需要執行內部操作的MySQL instance進行綁定。
步驟4:Cloud Controller將該MySQL instance的credentials與該應用的腳本,程序代碼放在一起重新打包,並在DEA中啓動。
以上4個步驟均爲簡單的vmc push以及vmc bind-service操作,瞭解的Cloud Foundry應用部署的開發者一定不會感到陌生。
以下是vmc如何通過caldecott應用與MySQL instance進行交互。在介紹實現機制之前,先來了解一下caldecott這個應用程序的功能與框架。
caldecott應用
首先該caldecott應用是一個sinatra框架的應用。在功能上,主要分爲兩個部分:第一,接收vmc發送來的http請求,並從該應用的環境變量中獲取綁定的service instance的信息,並將這些service instance的credentials返回給vmc;第二,接受vmc的caldecott client發送來的建立tunnel請求,本身作爲一個caldecott server建立與caldecott client的連接之後,將client發送來的內容再發給mysql server。以下爲caldecott應用程序的大部分ruby代碼:
# add vcap specific stuff to Caldecott
class VcapHttpTunnel < Caldecott::Server::HttpTunnel
get '/info' do
{ "version" => '0.0.4' }.to_json
end
def self.get_tunnels
super
end
get '/services' do
services_env = ENV['VMC_SERVICES']
return "no services env" if services_env.nil? or services_env.empty?
services_env
end
get '/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_json
end
end
VcapHttpTunnel.run!(:port => port, :auth_token => ENV["CALDECOTT_AUTH"])
緊接着步驟4,vmc通過應用caldecott操作MySQL instance:
步驟5:vmc通過restful請求,向caldecott索取已綁定service instance的credentials信息。
步驟6:caldecott從環境變量中讀取service的credentials,並將其返回給vmc。
步驟7:vmc在用戶的機器上開闢一個端口,並使用該端口,caldecott的url,service instance的host以及port來創建一條tunnel。創建的發起者爲caldecott::client,該連接的接受者爲caldecott::server,也就是部署在DEA上的caldecott應用的第二個功能,如以上代碼繼承部分與最後一行。其中vmc端的創建連接代碼如下:
def start_tunnel(local_port, conn_info, auth)
@local_tunnel_thread = Thread.new do
Caldecott::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
})
end
at_exit { @local_tunnel_thread.kill }
end
步驟8:caldecott應用作爲一個caldecott::server,建立一條與MySQL server的TCPConnection。
以上的8個步驟,實現了Cloud Foundry的外部用戶通過vmc與部署在Cloud Foundry上的應用caldecott建立與MySQL server的連接。
完成了以上的操作,當用戶執行mysql指令時,執行“mysql --protocol=TCP --host=localhost --port=10000 --user=uQQMx1PDleAlh --password=p31HW4mHr7LVd d52a850c9721d4f30b1652fa438bbdc79”。其中10000爲本機與caldecott創建tunnel的端口號,所以該請求會通過caldecott::client發給應用caldecott中的caldecott::server,而caldecott::server又會將請求發給MySQL server,最後由MySQL server解析執行並返回結果。
關於作者:
孫宏亮,DAOCLOUD軟件工程師。兩年來在雲計算方面主要研究PaaS領域的相關知識與技術。堅信輕量級虛擬化容器的技術,會給PaaS領域帶來深度影響,甚至決定未來PaaS技術的走向。
轉載請註明出處。
這篇文檔更多出於我本人的理解,肯定在一些地方存在不足和錯誤。希望本文能夠對開始接觸Cloud Foundry中service的人有些幫助,如果你對這方面感興趣,並有更好的想法和建議,也請聯繫我。
我的郵箱:[email protected]新浪微博:@蓮子弗如清