天天看點

《開源容器雲OpenShift:建構基于Kubernetes的企業應用雲平台》一3.2 核心元件詳解

本節書摘來自華章出版社《開源容器雲openshift:建構基于kubernetes的企業應用雲平台》一書中的第3章,第3.2節,作者 陳耿 ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視

openshift的核心元件及其之間的關聯關系如圖3-2所示。openshift在容器編排層使用了kubernetes,是以openshift在架構上和kubernetes十分接近。其内部的許多元件和概念是從kubernetes衍生而來,但是也存在一些在容器編排層之上,openshift特有的元件和概念。下面将詳細介紹openshift内部的核心元件和概念。

《開源容器雲OpenShift:建構基于Kubernetes的企業應用雲平台》一3.2 核心元件詳解

在介紹master節點前,我們先補充一些内容。openshift叢集可以由一台或多台主機組成。這些主機可以是實體機或虛拟機,同時可以運作在私有雲、公有雲,或混合雲上。在openshift的叢集成員有兩種角色。

master節點:即主要節點。叢集内的管理元件均運作于master節點之上。master節點負責管理和維護openshift叢集的狀态。

node節點:即計算節點。叢集内的容器執行個體均運作于node節點之上。

如圖3-2所示,在master節點上運作了衆多叢集的服務元件:

api server。負責提供叢集的web console以及restful api服務。叢集内的所有node節點都會通路api server更新各節點的狀态及其上運作的容器的狀态。

資料源(data store)。叢集所有動态的狀态資訊都會存儲在後端的一個etcd分布式資料庫中。預設的etcd執行個體安裝在master節點上。如有需要,也可以将etcd節點部署在叢集之外。

排程控制器(scheduler)。排程控制器在容器部署時負責按照使用者輸入的要求尋找合适的計算節點。例如,在前面章節我們部署的router元件需要占用計算節點主機的80、443及1936端口。部署router時,排程控制器會尋找端口沒有被占用的計算節點并配置設定給router進行部署。除了端口外,使用者還能指定如cpu、記憶體及标簽比對等多種排程條件。

複制控制器(replication controller)。對容器雲而言,一個很重要的特性是異常自恢複。複制控制器負責監控目前容器執行個體的數量和使用者部署指定的數量是否比對。如果容器異常退出,複制控制器将會發現實際的容器執行個體數少于部署定義的數量,進而觸發部署新的容器執行個體,以恢複原有的狀态。

在node節點上沒有這麼多系統元件,其主要職責就是接收master節點的指令,運作和維護docker容器。

這裡要指出的是,master節點本身也是一個node節點,隻是在一般環境中會将其運作容器的功能關閉。但是在我們這個實驗叢集中,由于隻有一個節點,是以這個master節點也必須承擔運作容器的責任。

通過執行oc get node指令可以檢視系統中的所有節點。

檢視叢集資訊需要叢集管理者的權限,請先登入為system:admin。具體方法請檢視之前的章節介紹。

可以看到,目前叢集中隻有一個節點,狀态是ready。通過oc describe node master.example.com指令檢視節點的詳細資訊。

從上面的輸出可以看到該節點詳細的系統資訊、節點上運作的容器資源使用情況、網絡位址等。

在kubernetes中使用命名空間的概念來分隔資源。在同一個命名空間中,某一個對象的名稱在其分類中必須是唯一的,但是分布在不同命名空間中的對象則可以同名。openshift中繼承了kubernetes命名空間的概念,而且在其之上定義了project對象的概念。每一個project會和一個namespace相關聯,甚至可以簡單地認為,project就是namespace。是以在openshift中進行操作時,首先要确認目前執行的上下文是哪一個project。

通過oc project指令可以檢視使用者目前所在的project。

通過oc project 可以切換到指定的項目。現在請切換到上一章建立的helloworld-php項目,接下來我們會以這個項目為基礎進行講解。

在openshift上運作的容器會被一種叫pod的對象所“包裹”,使用者不會直接看到docker容器本身。從技術上來說,pod其實也是一種特殊的容器。執行oc get pods指令可以看到目前所在項目的pod。

執行oc describe pod指令可以檢視容器的詳細資訊,如pod部署的node節點名、所處的project、ip位址等。

使用者可以近似認為實際部署的容器會運作在pod内部。一個pod内部可以運作一個或多個容器,運作在一個pod内的多個容器共享這個pod的網絡及存儲資源。從這個層面上,可以将pod了解為一個虛拟主機,在這個虛拟主機中,使用者可以運作一個或多個容器。雖然一個pod内可以有多個容器,但是在絕大多數情況下,一個pod内部隻運作一個容器執行個體。pod其實也是一個docker容器,通過dockerps指令可以檢視pod的執行個體資訊。

因為大多數情況下都是一個容器運作在一個pod内,很多時候可以将pod等同于我們所要運作的容器本身。

上述代碼是查找php的容器執行個體。一共有兩個輸出,一個是實際的php應用的容器執行個體,另一個是鏡像類型為openshift/origin-pod:v1.3.0的容器,即pod容器執行個體。

容器像盒子一樣為應用提供一個獨立的運作環境,但它并不是一個黑盒子。使用者可以實時地檢視容器的輸出,也可以進入容器内部執行操作。

執行oc logs 指令,可以檢視pod的輸出。

執行ocrsh指令,可以進入容器内部執行指令進行調試。

oc logs及ocrsh是兩個非常有用的指令,是排查容器相關問題的重要手段。

容器是一個一個非持久化的對象。所有對容器的更改在容器銷毀後預設都會丢失。同一個docker鏡像執行個體化形成容器後,會恢複到這個鏡像定義的狀态,并且擷取一個新的ip位址。容器的這種特性在某些場景下非常難能可貴,但是每個新容器的ip位址都在不斷變化,這對應用來說不是一件好事。拿前文部署的php和mysql應用來說,後端mysql容器在重新開機後ip位址改變了,就意味着必須更新php應用的資料庫位址指向。如果不修改應用位址指向,就需要有一種機制使得前端的php應用總是能連接配接到後端的mysql資料庫。

為了克服容器變化引發的連接配接資訊的變化,kubernetes提供了一種叫service(服務)的元件。當部署某個應用時,我們會為該應用建立一個service對象。service對象會與該應用的一個或多個pod關聯。同時每個service會被配置設定到一個ip位址,這個ip位址是相對恒定的。通過通路這個ip位址及相應的端口,請求就會被轉發到對應pod的相應端口。這意味着,無論後端的pod執行個體的數量或位址如何變化,前端的應用隻需要通路service的ip位址,就能連接配接到正确的後端容器執行個體。service起到了代理的作用,在互相依賴的容器應用之間實作了解耦。

通過oc get svc指令,可以擷取目前項目下所有service對象的清單。

通過cakephp的service的ip位址加端口172.30.1.84:8080,可以通路到cake-php的服務。

如果嘗試ping一下service的ip位址,結果是不會成功的。因為service的ip位址是虛拟的ip位址,而且這個位址隻有叢集内的節點和容器可以識别。

除了通過ip位址通路service所指向的服務外,還可以通過域名通路某一個service。監聽在master上的叢集内置dns伺服器會負責解析這個dns請求。service域名的格式是..svc.cluster.local。比如上面例子中的php應用的service域名将會是cakephp-mysql-example.helloworld-ng.svc.cluster.local:8080。可以在master節點上用ping檢查域名解析。

如果發現内部域名解析失敗,可以在/etc/resolve.conf中添加一條指向本機的域名伺服器的記錄。

service提供了一個通往後端pod叢集的穩定的入口,但是service的ip位址隻是叢集内部的節點及容器可見。對于外部的應用或者使用者來說,這個位址是不可達的。那麼外面的使用者想要通路service指向的服務應該怎麼辦呢?openshift提供了router(路由器)來解決這個問題。上一章中介紹了router元件的部署。其實router元件就是一個運作在容器内的haproxy,是一個特殊定制的haproxy。使用者可以建立一種叫route的對象,筆者稱為路由規則。一個route會與一個service相關聯,并且綁定一個域名。route規則會被router加載。當使用者通過指定域名通路應用時,域名會被解析并指向router所在的計算節點上。router擷取這個請求,然後根據route規則定義轉發給與這個域名對應的service後端所關聯的pod容器執行個體。在上一章部署cakephp應用時,我們将route域名修改為php.apps.example.com。當通路域php.apps.example.com時,請求到達router,并由其向後端分發。當pod的數量或者狀态變化時,openshift負責更新router内的配置,確定請求總是能被正确路由到對應的pod。

通過指令oc get routes,可以檢視項目中的所有route。

經常會有使用者混淆了router和service的作用。router負責将叢集外的請求轉發到叢集的容器。service則負責把來自叢集内部的請求轉發到指定的容器中。一個是對外,一個是對内。

容器預設是非持久化的,所有的修改在容器銷毀時都會丢失。但現實是傳統的應用大多都是有狀态的,是以要求某些容器内的資料必須持久化,容器雲平台必須為容器提供持久化儲存(persistent storage)。docker本身提供了持久化卷挂載的能力。相對于單機容器的場景,在容器雲叢集的場景中,持久化的實作有更多細節需要考慮。openshift除了支援docker持久化卷的挂載方式外,還提供了一種持久化供給模型,即persistent volume(持久化卷,pv)及persistent volume claim(持久化卷請求,pvc)模型。在pv和pvc模型中,叢集管理者會建立大量不同大小和不同特性的pv。使用者在部署應用時,顯式聲明對持久化的需求,建立pvc。使用者在pvc中定義所需存儲的大小、通路方式(隻讀或可讀可寫;獨占或共享)。openshift叢集會自動尋找符合要求的pv與pvc自動對接。通過pv和pvc模型,openshift為使用者提供了一種靈活的方式來消費存儲資源。

openshift對持久化後端的支援比較廣泛,除了nfs及iscsi外,還支援如ceph、gluterfs等的分布式儲存,以及amazon webservice和google compute engine的雲硬碟。關于存儲相關的話題,在後續章節會有更詳細的探讨。

openshift提供了一個内部的docker鏡像倉庫(registry),該鏡像倉庫用于存放使用者通過内置的source to image鏡像建構流程所産生的鏡像。registry元件預設以容器的方式提供,在上一章中,我們手工部署了registry元件。

通過oc get pod -n default指令可以檢視registry容器的狀态。

通過oc get svc -n default指令可以檢視registry容器對應的service資訊。

每當s2i完成鏡像建構,就會向内部的鏡像倉庫推送建構完成的鏡像。在上面的輸出示例中,鏡像倉庫的通路點為172.30.73.49:5000。如果檢視上一章cakephp的s2i建構日志,就會看到最後有成功推送鏡像的日志輸出:push successful。

一個常見的疑問是“是不是openshift用到的鏡像都要存放到内置的倉庫?”答案是否定的。内部的鏡像倉庫存放的隻是s2i産生的鏡像。其他鏡像可以存放在叢集外部的鏡像倉庫,如企業的鏡像倉庫或社群的鏡像倉庫。隻要保證openshift的節點可以通路到這些鏡像所在的鏡像倉庫即可。

前文多次提及source to image(s2i),因為s2i的确是openshit的一個重要功能。容器鏡像是容器雲的應用傳遞格式。容器鏡像中包含了應用及其所依賴的運作環境。可以從社群或者第三方廠商擷取基礎的作業系統或者中間件的鏡像。但是這些外部擷取的作業系統或中間件的鏡像并不包含企業内部開發和定制的應用。企業内部的開發人員必須自行基于外部的基礎鏡像建構包含企業自身開發的應用。這個鏡像的建構過程是必須的,要麼由企業的it人員手工完成,要麼使用某種工具實作自動化。

作為一個面向應用的平台,openshift提供了s2i的流程,使得企業内容器的建構變得标準化和自動化,進而提高了軟體從開發到上線的效率。一個典型的s2i流程包含了以下幾個步驟。

1)使用者輸入源代碼倉庫的位址。

2)使用者選擇s2i建構的基礎鏡像(又稱為builder鏡像)。builder鏡像中包含了作業系統、程式設計語言、架構等應用所需的軟體及配置。openshift預設提供了多種程式設計語言的builder鏡像,如java、php、ruby、python、perl等。使用者也可以根據自身需求定制自己的builder鏡像,并釋出到服務目錄中供使用者選用。

3)使用者或系統觸發s2i建構。openshift将執行個體化s2i建構執行器。

4)s2i建構執行器将從使用者指定的代碼倉庫下載下傳源代碼。

5)s2i建構執行器執行個體化builder鏡像。代碼将會被注入builder鏡像中。

6)builder鏡像将根據預定義的邏輯執行源代碼的編譯、建構并完成部署。

7)s2i建構執行器将完成操作的builder鏡像并生成新的docker鏡像。

8)s2i建構執行器将新的鏡像推送到openshift内部的鏡像倉庫。

9)s2i建構執行器更新該次建構相關的image stream資訊。

s2i建構完成後,根據使用者定義的部署邏輯,openshift将把鏡像執行個體化部署到叢集中。

除了接受源代碼倉庫位址作為輸入外,s2i還接受dockerf?ile以及二進制檔案作為建構的輸入。使用者甚至可以完全自定義建構邏輯來滿足特殊的需求。

openshift提供了不同的工具集為開發和運維的使用者提供良好的體驗,也為持續內建和打通devops流程提供便利。例如,openshift提供了eclipse插件,開發工程師可以在eclipse中完成應用及服務的建立和部署、遠端調試、實時日志查詢等功能。

繼續閱讀