天天看點

openstack和容器內建的why,what,hao

轉自   http://mp.weixin.qq.com/s?__biz=MjM5MzM3NjM4MA==&mid=401909586&idx=3&sn=15fe2e134ac883305087d19f4f16baf5&scene=2&srcid=1113gfUOHCjpwfvkoum3eWEa&from=timeline&isappinstalled=0#rd

OpenStack內建容器方案解讀

2015-11-13 雲頭條

前言:

很多時候,對于一個研發人員來說,往往更關注軟體實作層面的東西,缺少了怎麼把一些知識串聯起來對軟體特性設計本身的一些思考,基于一門底層技術之上的猜想,比如說它為什麼要去設計這些特性,基于這些特性我們能幹什麼是值得我們去深思。這次我主要不是針對容器技術是怎麼實作的去分享,而是從openstack能使用容器技術的特性來幹什麼的緯度展開讨論。對于我而言,無論是什麼事,我都習慣從Why -> How -> What來思考問題,我相信這個世界沒有無緣無故的愛,也沒有無緣無故的恨,有句話叫“存在即合理”,那麼openstack為什麼要做容器平台也一定有它得理由。是以我以Why How What的順序來給大家分享下openstack內建容器技術的方案。

一、Why:openstack為什麼要內建容器技術

首先:要明确知道得是openstack的“根”是要做內建引擎,是以也就确定了它必然會往內建方向發展。具體點說,openstack隻要管好三個子產品:計算、存儲、網絡,着重在如何讓這三個子產品高效的協同工作,而對于主流的計算、存儲、網絡解決方案,openstack都可以将它們內建進來供使用者選擇适合他們業務場景得解決方案組合。最初的openstack的計算子產品的解決方案是以虛拟化技術為主的VM,随着這兩年以docker為主得容器技術迅猛發展,openstack看到了在VM之外的計算方案,是以openstack自然會将docker內建到計算子產品中來,以此來豐富自己的計算能力。其次:openstack一直緻力于打造一個統一的硬體和軟體無關的IT基礎設施架構,那就意味着它必須去考慮兩件事:

  • 一個部署了openstack的IT廠商如果想使用docker這樣的容器技術的時候該怎麼辦?總不能讓IT廠商在垂直領域去重新找一個新得容器管理方案。
  • 一個想使用容器技術的IT廠商,如何去幫他們考慮硬體資源的彈性問題?

Peter Thiel有句名言:失敗者才去競争,創業者應當選擇壟斷。以其說openstack是“被逼上梁山”的,不如說openstack選擇了在IaaS市場的壟斷。如果openstack将以docker為主的容器技術內建進來,那麼IT廠商就可以通過openstack找到一個統一的跨平台得API來管理他們的虛機、容器和裸機,即不失容器固有的功能,又能給容器提供一個托管平台。再者:以docker為主的生态圈的發展勢頭大有取代以VM為主的openstack的趨勢。CloudFoundry Diego版本Garden項目中加入了docker的支援,Garden的前身是warden,而warden其實比docker發展的更早,早期的docker和warden一樣都是基于lxc來做,但是warden起初的定位并沒有針對使用者使用,隻是提供給cloudfoundry一個運作時隔離環境而已,是以失去了市場先機。openshit V3中也加入了docker的支援,還有兩個針對雲計算的作業系統的CoreOS和Atomic,也都加入docker的支援,CoreOS自家還有針對企業級市場的rocket(rkt)容器技術。是以我個人覺得從戰略上考慮,openstack怎麼能允許docker取我而代之呢?相反,如果我把你招入麾下,那麼自然就告訴别人這個行業誰才是老大。

二、How:openstack是如何內建容器技術方案

我曾經思考過計算機為何會如此的高效,思考過如何像計算機一樣提高自己的工作效率,我覺得有兩點:管理和執行力。對于計算機而言,執行力自不必說,非0即1。那麼效率就落在管理上面,在計算機的世界裡,管理的最終目的即是如何充分的利用資源來做更多的事。管理離不開組織,組織離不開規模,規模離不開個人,docker就像個人一樣,接下來讓我們看下openstack是如何去考慮管理容器這件事。

起初openstack社群在将docker內建進來的時候有過兩個方案:heat driver和nova driver,這兩個都是以插件得形式接入openstack,但是都是直接将docker當成VM來使用,缺少了對docker得抽象封裝,如果大規模的使用docker的時候,那麼管理上就會出現很大的問題(就像一個上了規模的上市公司的CEO每天去管理公司×××阿姨的工作),自然也就無法發揮docker的價值,結論就是将docker作為控制粒度直接內建進來是不可取的,是以就必須要對docker進行抽象封裝(可以了解為進行組織劃分),把控制粒度控制在docker的抽象封裝上。docker對于個人開發者而言,已經很好用了,但是對于像前面提到的大規模部署容器得企業而言,手動操作docker的批量建立、排程和管理會成為了制約docker在任何組織内大規模應用的重要障礙。有問題,那就必然有解決問題的對策,是以docker的生态圈出了一些工具來解決這些問題:比如:針對容器編排和部署的Compose(Fig)、Machine、Swarm以及後來的Fleet,針對應用支援和運作時的Flynn、Deis等等,到最後實作大一統的是google公司開源的一款專門針對容器叢集管理得工具kubernetes,國人一般直接音譯成k8s,我們後面再重點介紹kubernetes。Compose、Machine、Swarm、Fleet這類的工具主要focus在容器的編排和部署上面,如何讓容器更易于使用,但是在管理效率上不是很高效。Flynn、Deis、openshift V3、CF V3這類的主要focus在建構一個PaaS平台上,對于PaaS平台來說,最重要的問題就是解決應用依賴問題,拿CloudFoundry來說,它使用一個Buildpack子產品來做平台應用依賴管理,很多特殊的應用往往就需要對Buildpack做定制化開發才可以支援,而如果使用docker來做這件事,就很easy了,一個Dockerfile就可以搞定一個應用的依賴問題。确實在docker剛出來的時候,就很多人預言了基于docker的微PaaS平台會大熱,當然了,我個人覺得openstack不選擇這類PaaS平台是因為它不想自己所提供的容器平台隻是一個解決應用依賴的平台,它應該還可以做更多的事。既然有專門針對容器技術的編排管理工具,openstack自然不會想到自己重新去實作一個,而是想着怎麼把它們直接內建進來。除此之外,openstack還考慮如何把容器內建做成一個可以像其它的openstack服務,比如:nova、cinder、trove、glance、ironic等等一樣得服務(跟着組織走),我想用的時候直接把服務起來就可以了。基于這兩個需求,Rackspace的工程師Adrian Otto主導了magnum項目,專門用來對接openstack和容器技術平台,下面我們來介紹下magnum這個項目是如何做這件事。

1、magnum項目介紹

前面已經說到,magnum項目其實隻要做好兩件事:

  • 怎麼把容器編排管理工具內建進來。
  • 怎麼把自己作為一個openstack的服務。

對于第二件事比較簡單,照着其他服務得架構思路就可以實作,但是針對第一件事,就必須要思考如何去抽象封裝。magnum的抽象思路是:将容器編排系統抽象封裝進來。這樣做的好處是:

  • 不需要去重複造容器編排的輪子
  • 可以将各種優秀的容器編排工具內建進來
  • 可以利用編排工具所支援的各種優秀的容器技術解決方案比如rocket、garden、openVZ等等內建進來,而不一定隻是docker。

下面我們具體來看下magnum 是如何抽象封裝,先看一張官方的magnum軟體架構圖:

  • Bay:magnum用Bay來抽象容器編排工具,到L版釋出的時候,支援的Bay類型有:kubernetes(k8s)、docker swarm、mesos。
  • Baymodel:容器規格。對于nova來說有flavor,自然對于容器來說,也有它自己的規格。

其它的比如Node、Pod、Service、RC這幾個都是k8s的概念,到後面介紹k8s的時候再介紹。同openstack得其他服務一樣,magnum也是通過一個API服務來接受請求,再轉發到後端得conductor處理,conductor去調用不同得後端Bay驅動來跟不同的容器編排工具的得API做互動。除此之外,magnum使用openstack的keystone來提供一個異步的API來管理應用容器和一個完整的多租戶實作,這也是magnum有别于docker或者kubernetes的地方。

在編排管理工具的選型上,到L版為止支援的Bay類型有docker swarm、mesos、kubernetes。magnum內建度最高的是kubernetes,實作了一層和kubernetes對應的互動API,目前magnum預設的Bay類型是kubernetes(官方推薦),先看下Docker swarm和mesos。

  • Docker swarm:swarm雖然也是對docker做了一層抽象封裝,但是它的抽象還是有點過于簡單,不适合于複雜的應用場景。它更多是可能是替代Docker用戶端,因為docker用戶端還不支援跨主機操作。
  • mesos:

    1、如果站在magnum上面來說,我們知道mesos是一個非常優秀的架構排程系統,雖然mesos也可以排程docker容器,但是它也還是以docker為控制粒度,缺少了對docker的抽象封裝,不适合在運作大量的容器叢集中做管理,而且在kubernetes的roadmap中會将mesos作為排程插件接入kubernetes,換句話說就是把kubernetes這個架構運作在mesos之上,或者說把mesos作為kubernetes的排程架構。我覺得這才是kubernetes和mesos最好的結合,是以這裡我沒想明白magnum為什麼要把mesos內建到magnum這裡面進來。我個人覺得在sahara這個項目中可以考慮怎麼去更好的內建mesos,可以給Hadoop社群提供一個yarn之外的選擇。

    2、如果單純站在mesos上面來說,目前有一個比較好的應用管了解決方案:mesos+marathon,marathon是一個基于mesos的應用管理架構,前身是Chronos,主要還是focus在資料中心,是以marathon主要運用在運作Hadoop、Strom、Spark、kafaka等等資料處理架構為主的IDC中心,當然它也可以管理普通的web應用。在大資料和雲計算的結合方面,目前sahara這個項目一直在做這件事,它可以考慮将marathon內建進來。

回到我們最初談到的openstack要奔着壟斷去的,它不會給IT廠商去做如何選擇的“機會”。在google的kubernetes一出來的時候,立馬一統容器管理的江上,openstack又豈會放過,這也是為什麼magnum會對kubernetes做深度內建的原因。

接下來我們看下magnum建立一個kubernetes的簡單的過程:

  • 建立Baymodel
  • 建立kubernetes Bay
  • 使用kubernetes的pod、service、rc模版來建立應用。

這些模版是kubernetes原生的模版。是以magnum要做得事情很少,基本又回歸到kubernetes自身得使用上面來了。回過頭來看magnum的控制粒度,把容器編排管理工具作為控制粒度,把容器應有的特性封裝交給容器編排管理工具來做,這樣就不會影響到一個優秀得容器叢集管理工具得價值。對于openstack來說管理變得簡單了,接下來讓我們重點來介紹下kubernetes。

2、kubernetes項目介紹

kubernetes能幹什麼?首先kubernetes是google基于Borg開源的一個容器編排系統,Borg是google内部一直在使用的一個叢集管理工具,實際上,容器技術的核心功能cgroup最早就是由google的工程師送出給Linux核心,google内部也一直在使用容器技術,Borg能夠處理google每天成千上萬個應用得任務處理,充分證明Borg系統是“靠譜的”大規模應用管理系統,google已經将Borg進行更新,代号Omega。同樣百度内部也開發了一個号稱可以媲美Borg的叢集管理系統Matrix,并且拿到了百度内部最高獎(100萬美金)。還有facebook的Corona、twitter的Aurora,可以想像一個好的叢集管理系統有多重要,這也是我們t2cloud雲平台2.0的目标。正是因為基于Borg得基因,是以kubernetes一開始就是為管理大規模的應用而生得,隻不過kubernetes是專門針對大規模容器叢集做管理得。那麼它肯定有一套非常完美的對象抽象,否則怎麼管理大規模的容器。此外,kubernetes還是跨主機容器化應用管理的系統,實作了包括部署、高可用管理和應用彈性伸縮在内的一系列基礎功能,并封裝成為一套精簡的RESTful API對外提供服務,除了mesos已經可以作為kubernetes的排程服務之外,劍橋大學計算機實驗室開源的一款最新的叢集排程平台Firmament也正在跟kubernetes內建,Firmament目前還在alpha階段。接下來我們來看下kubernetes是如何針對複雜的應用在管理上去抽象封裝容器叢集,先看kubernetes官方的架構圖:

openstack和容器內建的why,what,hao
  • pod:kubernetes排程的最小單元,kubernetes不對單一的容器進行排程,相反,它将一些強耦合的應用元件容器捆綁在一起進行排程,這麼做有兩個好處:1、對于強耦合應用,比如說某個應用帶了一個db服務,兩個服務之間互相通路的方式變簡單了,一個容器服務可以直接通路另一個容器服務指定的目錄,一個容器可以直接通過localhost通路另一個容器,不需要更複雜的通路方式。2、可以簡化排程系統,尤其是在大規模容器叢集中,管理的粒度變大了,就相當于“放權”之後管理者要做的事就少了,那麼排程者本身就能夠大大的提高排程效率。
  • rc:全稱replication controller,這個抽象是kubernetes用來保證應用可靠性而設計的,它被設計用來保證叢集中pod的副本數,并且保證這些副本的期望狀态與目前的狀态一樣。熟悉Cloud Foundry得人都知道,Cloud Foundry使用一個獨立的元件HM9000來做統一監控管理,是以各個元件要不斷的将資訊發送給HM9000來監控處理,包括openstack的ceilometer監控也是,是以容易造成性能瓶頸。是以,kubernetes就設計了一個非常輕量化的對象來處理監控,每一個pod都可以自己定義一個rc,而一個rc隻負責監控它所選擇的pod,針對不同的pod狀态有不同的處理政策,非常的精簡高效。
  • label:label的設計用來管理kubernetes中運作的大量的pod、rc等等對象的運作執行個體。它是一個鍵/值對,結構非常簡單,就是一個key和value均是string類型的map結構(go語言文法)。它通過lable selector來做lable管理的,比如我們使用的pod模版中有("name":"nginx")("name":"wordpress")這類的label,叢集中運作很多這類模版建立的執行個體。那麼我就可以通過lable去檢視目前叢集中所有name為nginx的pod執行個體。這隻是一個簡單的應用,實際應用中還可以将lable運用在複雜應用的分層緯度中去做分層管理,比如有一個非常大的應用,需要很多的pod組成,那麼你就可以通過底層、中間件、上層這三種lable來區分每個pod所屬的層次機構,是以lable非常适用在建構微服務架構為主的應用中做為微服務架構下應用的微服務的分類管理。lable可以随着執行個體的建立綁定,也可以動态的增/減,同一個pod中key是唯一的,value可以變。在建立pod或者rc等等執行個體的模版中可以自行指定label,而對于使用者來說,可以通過label selector來選擇指定的lable。
  • service:這個是kubernetes設計用來代理pod請求的,為什麼?因為pod的ip不是固定的,是以就需要一個有固定IP的服務來代理pod的路由,service通過label selector來選擇它所要代理的pod的label。很多人可能就會想,那直接在Node節點跑一個Agent不就搞定了,很多分布式架構都會有這樣的設計,kubernetes也有,但是kubernetes設計service還有一層考慮就是你可以更人性化的去管理你的應用,雖然service的背景實作機制也是要依賴Node節點的kube-proxy代理服務,但是把service固定住,那麼背景的應用pod你可以随時更換而不需要再修改代理規則,對于使用者來說,你隻感覺到service就行了,完全屏蔽掉背景實作。service還可以為pod做負載均衡,當rc控制了多個pod的時候,service可以将流量分發到各個pod節點上。

上面幾個概念是kubernetes對大規模叢集管理做的一些對象抽象,從控制粒度為應用到穩定性保證到大規模分類管理到負載均衡,可以讓你很輕松的去做一個大規模的容器叢集管理。接下來點下kubernetes的軟體架構,從上面的圖可以看出,首先,kubernetes采用的是現在主流的分布式架構,是以就有主從的概念。主要節點上面運作:kube-api、kube-scheduler、kube-controller-manager服務,從節點上面運作:kube-proxy,docker服務,整個叢集使用etcd作為後端存儲系統和服務發現。主要節點上面的幾個服務主要是用來做對象控制、排程和管理用的,而從節點上面除了正常的docker服務之外還運作了一個kube-proxy服務用來做service的代理,kube-proxy使用etcd的一個非常重要的watch機制來watch etcd上面的service來更新從節點所在的主機上面的iptables規則。

對于kubernetes軟體實作層面的東西,我這裡不做過多的文章,感興趣可以去閱讀源代碼,go語言的代碼還是很好閱讀。前面都是一直在說如何去管理容器這件事,但是我們是否想過會有管理容器這件事,換句話說就是容器值得我們去管理,接下來我們來聊聊使用以Docker為主的容器技術來開發會帶來哪些好處。傳統的網際網路應用開發流程如下:

  • 從代碼庫拉取代碼
  • 本地環境安裝依賴(進階點的可以直接配置一個依賴腳步執行一下就OK)
  • 送出代碼倉庫觸發CI,做CI測試
  • 測試人員測試
  • 運維人員釋出應用

理想很豐滿,現實很骨感,簡單的幾個環節就可能會出現各種各樣的問題,比如開發、測試和生産環境不一緻導緻的問題,版本更新帶來的依賴問題等等。當然了,軟體沒有什麼解決不了的問題,最終肯定都會有解決的辦法,但至于“解決方法”所付出的代價可能就值得我們商榷了。那如果使用Docker來開發,它又有什麼特點,先看一個使用Docker來開發的流程圖:

openstack和容器內建的why,what,hao

使用Docker開發可以有如下好處:

  • 持續部署與測試 Docker消除了開發、測試、生産環境的差異性,保證了應用生命周期的環境一緻性和标準化,你還可以像git工具一樣去對Docker鏡像做版本控制。現在主流的配置管理工具:Chef、Puppet、Ansible、Saltstack等等也都支援Docker。開發者在開發階段編寫好Dockerfile執行本地開發,送出完整鏡像到鏡像庫,測試人員拉取鏡像測試完送出到釋出鏡像庫,運維人員從釋出鏡像庫釋出鏡像,一旦出現故障還可以快速復原,大大簡化了持續內建、測試和釋出的過程。
  • 跨平台 Java有句名言叫“一處編譯,到處運作”,同樣,Docker也有一句名言“一處建構,到處運作”。Docker鏡像可以運作在任何運作Docker引擎的主控端上,目前,Docker隻支援運作Linux發行版本,運作Docker引擎的除了支援Linux發行版外,還支援window nano server。
  • 資源使用率高 Docker隻是一個程序級别的系統開銷,相比Hyper-V、KVM、Xen等等硬體仿真級别的虛拟化技術而言,在對主控端資源使用率方面,Docker可以高出一節。當然了,正式因為它是容器技術,隻是提供了在程序級别的隔離,隔離性方面肯定比不上虛拟化技術,這就要考慮到實際的應用場景的隔離級别了。

    這些隻是我個人覺得Docker可以帶來的好處,更多的功能還等着我們去挖掘。kubernetes的管理思想和Docker的特性,結合微服務架構的思想,可以很輕松的建構複雜的大型應用,當然了,對于一個複雜的大型應用離不開另外兩大塊:存儲和網絡。這是兩個比較大的内容,需要下次專門來分享,這裡我可以簡單的點一下這兩塊内容。

  • 存儲:kubernetes的存儲針對pod而言,支援的存儲類型有:emptyDir(Node節點的一個目錄)、hostPath(共享Node檔案系統路徑的一種機制。這個機制對于同一個節點的pod資料不會丢失,但是pod節點發生跨主機遷移,那麼資料就會丢失,是以不推薦使用)、nfs(就是網絡檔案系統,nfs的性能問題一直都是一個瓶頸)、rbd(ceph塊存儲,ceph是我們t2cloud雲平台現在在使用的分布式存儲解決方案,理所當然的我們也是推薦使用ceph作為kubernetes的存儲解決方案)像其他的還有Glusterfs、iscsi、gitRepo等等可以參考官網。下次可以給大家分享下我們雲平台現在的ceph解決方案。
  • 網絡:Docker自身的網絡模型決定了它隻能在同一台主控端上面通信,是以Docker生态圈出了很多Docker的網絡解決方案,比如:Weave、Flannel、Pipework、SocketPlane,Docker自己也釋出了libnetwork來解決網絡問題。kubernetes本身也可以算是Docker網絡的一種解決方案,前面有提到過kubernetes為每一個pod配置設定一個ip,這就是它的“單pod單IP模型”,通過這個IP位址,可以在一個扁平化的網絡位址空間裡面跨網絡與其他實體機、虛拟機或者容器進行通信,這個扁平網絡是由某種IaaS或者網絡工具OVS(OpenVSwich)、Socketplance來保證。

三、What:openstack完整的容器技術平台

openstack可以通過magnum項目來提供一個深度的容器解決方案,結合openstack的ironic項目提供的裸機計算能力,那麼openstack最終展現出來的就是一個完整的計算方案:虛拟機、容器、裸機。(隻能說目前是完整的,未來以OGE、SLURM為主的網格計算和以Unikernel為主的無核技術說不定會有一個比較好的方案)。在通過openstack去使用容器技術或者說docker的角度來看,你還可以使用openstack的應用目錄服務murano來使用容器技術,使用murano模版來配置docker鏡像或者配置部署kubernetes。最low的,你可以直接在openstack的VM中安裝docker服務即可。此外,社群還有一個跟openstack部署相關的關于docker的項目:Kolla,這個項目主要的目的是使用docker快速的部署更新openstack服務,我個人對這個項目保持謹慎的态度。

這次的分享就到這裡,對于我們研發人員來說,有時候跳出軟體實作本身來看軟體平台設計,你會對軟體平台有不一樣的解讀,再回過頭去開發、設計軟體平台的時候,往往你會有不一樣的了解。功能是建立在應用場景之上的,計算機不還講究“上下文”的嗎?是以對于Docker來說,不一定是所有的應用都适合用它部署,至于什麼應用适合,什麼應用不适合也沒有什麼明确的定義,就我們t2cloud雲平台2.0來說,主要用在針對無狀态服務的應用上面。這次的分享隻是一個開始,接下來我們還會給大家分享下我們t2cloud雲平台2.0所使用的分布式存儲ceph和容器平台網絡的演進(Docker網絡、kubernetes網絡、magnum網絡以及如何進入openstack的網絡演進)。如果讀者發現文章裡面有了解不對的地方,可以指出來([email protected]),我們一起來學習。