Cloud Foundry中vmc tunnel與caldecott原理

        在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]

新浪微博:@蓮子弗如清 



發佈了47 篇原創文章 · 獲贊 10 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章