詳解CloudFoundry中各個組件的做用

CloudFoundry是一個標杆性的項目,架構設計上有不少值得借鑑之處。從CloudFoundry官網摘了一張圖,咱們以此剖析各個組件的做用。 CloudFoundryhtml

Router

Router是整個平臺的流量入口,負責分發全部的請求到對應的組件,包括來自外部用戶對app的請求和平臺內部的管理請求。nginx

Router是PaaS平臺中相當重要的一個組件,它在內存中維護了一張路由表,記錄了域名與實例的對應關係,所謂的實例自動遷移,靠得就是這張路由表,某實例宕掉了,就從路由表中剔除,新實例建立了,就加入路由表。git

CloudFoundry1.0中的router是用nginx+lua嵌入腳本實現的,2.0用golang重寫,改名爲gorouter,性能有所提高,並聲稱試圖解決websocket請求和tcp請求(雖然這在筆者看來是沒用的),它的代碼在https://github.com/cloudfoundry/gorouter,你們能夠研究一下。github

Authentication

這塊包含兩個組件,一個是Login Server,負責登陸,一個是OAuth2 Server(UAA),UAA是個Java的項目,若是想找一個OAuth2開源方案,能夠嘗試一下UAAgolang

Cloud Controller

Cloud Controller負責管理app的整個生命週期。用戶經過命令行工具cf與CloudFoundry Server打交道,實際主要就是和Cloud Controller交互。web

用戶把app push給Cloud Controller,Cloud Controller將其存放在Blob Store,在數據庫中爲該app建立一條記錄,存放其meta信息,而且指定一個DEA節點來完成打包動做,產出一個droplet(是一個包含Runtime的包,在任何dea節點均可以經過warden run起來),完成打包以後,droplet回傳給Cloud Controller,仍然存放在Blob Store,而後Cloud Controller根據用戶要求的實例數目,調度相應的DEA節點部署運行該droplet。另外,Cloud Controller還維護了用戶組織關係org、space,以及服務、服務實例等等。數據庫

Health Manager

Health Manager最初是用Ruby寫的,後來用golang寫了一版,稱爲HM9000,HM9000主要有四個核心功能:緩存

  • 監控app的實際運行狀態(好比:running, stopped, crashed等等),版本,實例數目等信息。DEA會持續發送心跳包,彙報它所管轄的實例信息,若是某個實例掛了,會立馬發送「droplet.exited」消息,HM9000據此更新app的實際運行數據
  • HM9000經過dump Cloud Controller數據庫的方式,獲取app的指望狀態、版本、實例數目
  • HM9000持續比對app的實際運行狀態和指望狀態,若是發現app正在運行的實例數目少於要求的實例數目,就發命令給Cloud Controller,要求啓動相應數目的實例。HM9000自己,不會要求DEA作些什麼。它只是收集數據,比對,再收集數據,再比對
  • 用戶經過cf命令行工具是能夠控制app各個實例的啓停狀態的,若是app的狀態發生變化,HM9000就會命令Cloud Controller作出相應調整

說到底,HM9000就是保證app可用性的一個基礎組件,app運行時超過了分配的quota,或者異常退出,或者DEA節點整個宕機,HM9000都會檢測到,而後命令Cloud Controller作實例遷移。HM9000的代碼在這裏:https://github.com/cloudfoundry/hm9000,有興趣的同窗能夠研究一下安全

Application Execution(DEA)

DEA,即Droplet Execution Agent,部署在全部物理節點上,管理app實例,將狀態信息廣播出去。好比咱們建立一個app,實例的建立命令最終會下發到DEA,DEA調用warden的接口建立container,若是用戶要刪除某個app,實例的銷燬命令最終也會下發到DEA,DEA調用warden的接口銷燬對應的container。websocket

當CloudFoundry剛剛推出的時候,Droplet包含了應用的啓動、中止等簡單命令。用戶應用能夠隨意訪問文件系統,也能夠在內網暢通無阻,跑滿CPU,佔盡內存,寫滿磁盤。你一切能夠想到的破壞性操做均可以作到,太可怕了。CloudFoundry顯然不會聽任這樣的狀況過久,如今他們開發出了Warden,一個程序運行容器。這個容器提供了一個孤立的環境,Droplet只能夠得到受限的CPU,內存,磁盤訪問權限,網絡權限,再沒有辦法搞破壞了。

Warden在Linux上的實現是將Linux內核的資源分紅若干個namespace加以區分,底層的機制是CGROUP。這樣的設計比虛擬機性能好,啓動快,也可以得到足夠的安全性。在網絡方面,每個Warden實例有一個虛擬網絡接口,每一個接口有一個IP,而DEA內有一個子網,這些網絡接口就連在這個子網上。安全能夠經過iptables來保證。在磁盤方面,每一個warden實例有一個本身的filesystem。這些filesystem使用aufs實現的。Aufs能夠共享warden之間的只讀內容,區分只寫的內容,提升了磁盤空間的利用率。由於aufs只能在固定大小的文件上讀寫,因此磁盤也沒有出現寫滿的可能性。

LXC是另外一個Linux Container。那爲何不使用它,而開發了Warden呢。由於LXC的實現是和Linux綁死的,CloudFoundry但願warden能運轉在各個不一樣的平臺,而不僅是Linux。另外Warden提供了一個Daemon和若干Api來操做,LXC提供的是系統工具。還有最重要的一點是LXC過於龐大,Warden只須要其中的一點點功能就能夠了,更少的代碼便於調試。

Service Brokers

app在運行的時候一般須要依賴外部的一些服務,好比數據庫服務、緩存服務、短信郵件服務等等。Service Broker就是app接入服務的一種方式。好比咱們要接入MySQL服務,只要實現CloudFoundry要求的Service Broker API便可。但實際狀況是在咱們使用CloudFoundry以前,MySQL服務已經由DBA作了服務化、產品化,用起來已經很方便了。有必要實現其Service Broker API,按照CloudFoundry這套規則出牌麼?筆者認爲沒有這個必要。app仍然按照以前訪問MySQL服務的方式去作便可,沒有任何問題。

Message Bus

CloudFoundry使用NATS做爲內部組件之間通訊的媒介,NATS是一個輕量級的基於pub-sub機制的分佈式消息隊列系統,是整個系統能夠鬆散耦合的基石。

咱們以向router註冊路由爲例來講明NATS的做用。不論是外部用戶對平臺上的應用發起的請求,仍是對內部組件(好比Cloud Controller、UAA)發起的請求,都是經由router作的轉發,要能讓router轉發則首先須要向router註冊路由。大致邏輯實現以下:

  • router啓動時,會訂閱router.register這個channel,同時也會定時的向router.start這個channel發送數據
  • 其餘須要向router註冊的組件,啓動時會訂閱router.start這個channel。一旦接收到消息,會馬上收集須要註冊的信息(如ip、port等),而後向router.register這個channel發送消息。
  • router接收到router.register消息後當即更新路由信息
  • 以上過程不停循環,使router的狀態時刻保持最新

Logging and Statistics

Metrics Collector會從各個模塊收集監控數據,運維工程師能夠據此來監控CloudFoundry,出了問題及時發現並處理。物理機的硬件監控則能夠採用傳統的一些監控系統來作,好比zabbix之類的。

Log這塊是個大話題,CloudFoundry提供了Log Aggregator來收集app的log。咱們也能夠經過其餘手段直接把log經過網絡打出來,好比syslog、scribe之類的。

參考資料

同步發表在個人blog:http://blog.ulricqin.com/article/cloudfoundry-component

相關文章
相關標籤/搜索