在Kubernetes上運行SAP UI5應用(下): 一個例子體會Kubernetes內容器的高可用性和彈性伸縮

上一篇文章 在Kubernetes上運行SAP UI5應用(上),我介紹瞭如何在Docker裏運行一個簡單的SAP UI5應用,而且已經成功地將一個包含了這個UI5應用的docker鏡像上傳到Docker hub上。node

這篇文章做爲這個主題的下半部分,將會介紹如何在Kubernetes裏運行這個docker鏡像。nginx

文章目錄git

  • Kubernetes裏的兩個重要概念:pod和deployment程序員

  • Kubernetes保證應用程序高可用性和伸縮性的一些體驗github

  • Kubernetes滾動升級(Rolling Update)特性體驗web

在Kubernetes上運行咱們的應用,有什麼收益?根據Jerry這十多天有限的時間裏對Kubernetes的學習,個人理解是,Kubernetes能夠幫助應用開發人員確保其開發出的應用程序以一種高可用的、可伸縮和容錯的方式進行部署和運行,應用開發人員無需花費大量時間和精力去學習Kubernetes底層細節。算法

換句話說,Kubernetes環境的搭建,系統的配置,能夠所有交給Kubernetes的管理員,而應用開發人員做爲Kubernetes的消費者,只須要記住幾個簡單的kubectl命令,就可以輕鬆完成應用程序到Kubernetes上的部署,幾乎不需付出額外的代價就能享受到Kubernetes做爲一個平臺給應用程序帶來的上述非功能性的提高。docker

咱們繼續用前一篇文章使用到的UI5應用進行講解。瀏覽器

Jerry很窮,沒有錢購買額外的服務器本身搭建Kubernetes集羣環境。幸運的是,Kubernetes並無拋棄咱們這些貧窮的程序員,咱們還能夠選擇Kubernetes Clusters as a Service這種解決方案。服務器

在我另外一篇文章 站在巨人肩膀上的牛頓:Kubernetes和SAP Kyma 裏我提到過Gardener, 一個開源的建立Kubernetes集羣的解決方案:

https://github.com/gardener

我在SAP內部的Gardener上建立一個基於Google Cloud Platform的Kubernetes集羣,取名jerry1204:

能夠看到這個建立好的集羣上的Kubernetes版本仍是比較新的, 1.12.3僅僅低於12月3日剛剛發佈的1.13版。

點擊上圖Access標籤頁裏的Dashboard(控制檯)超連接,便可對這個Kubernetes集羣進行操做。固然像SAP上海研究院Kubernetes培訓課程上講課的那些老司機們更喜歡用命令行。

由於是免費的集羣,只分配了一個工做節點:

控制檯裏看到的Kubernetes集羣工做節點信息和命令行kubectl get node -o wide看到的一致:

Kubernetes裏的兩個重要概念:pod和deployment

下面咱們使用命令行來消費咱們前一篇文章上傳到Docker Hub上的鏡像i042416/ui5-nginx:

kubectl run jerry-ui5 --image=i042416/ui5-nginx

這個命令行背後發生了不少事情。

首先,運行在Kubernetes上的應用程序,其高可用性,可伸縮性和容錯性究竟是經過Kubernetes什麼機制保證的?

答案是pod。請單擊上面Kubernetes的架構圖,而後放大,能看到node(節點)裏包含了多個pod,每一個pod裏又包含了多個容器。像它的中文含義(豆莢,飛機,航天器或船隻上可與主體分離的分離倉)暗示的同樣,pod就是應用程序運行的載體,是Kubernetes的基本操做單元。整套Kubernetes系統的設計都是圍繞着pod展開,例如pod的部署和運行,如何保證處於運行狀態的pod總數量等於一個恆定值,如何將pod裏應用提供的服務暴露給外部訪問等等。

回到咱們以前的命令行,咱們試着執行另外一個命令kubectl get pod,果真發現了一個pod被建立出來,誕生已經40秒了(Age = 40s)。

用describe命令查看這個pod的明細:

kubectl describe pod jerry-ui5-6ffd46bb95-6bgpg

下圖Container ID後面的docker://說明這是一個docker容器,固然並不意味着Kubernetes只支持Docker這一種容器技術,好比Kubernetes還支持CoreOS的Rocket。

describe命名輸出的Events區域揭示了一個pod從誕生到開始服役的生命週期狀態跳轉:

Scheduled->Pulling->Pulled->Created->Started

image.gif

從每一個狀態的from字段也能看出不少信息。

Scheduled狀態的from: default-scheduler。Scheduler是Kubernetes的組件之一,負責調度pod到合適的節點上。具體什麼樣的節點算合適,取決於Kubernetes Scheduler調度算法的實現,Jerry沒有研究過。若是把Scheduler當作一個黑匣子,那麼它的輸入是pod和由多個節點組成的列表,輸出是Pod和一個匹配節點的綁定。這個狀態message顯示的內容"Successfully assigned XXX to shoot--jerrytest-jerry1204-worker-yamer-z1-XXX"後面這個shoot--jerrytest開頭的字符串就是pod被分配到的節點的名稱。

後面幾個狀態的from字段都是kubelet,shoot--jerrytest-jerry1204-worker-yamer-z1-XXX,其中kubelet是Kubernetes節點上一個重要的模塊,負責維護和管理運行於該節點上的全部容器,確保pod的運行狀態與使用者指望一致。

在Kubernetes web控制檯裏也同樣能看到這個處於運行狀態的pod:

除了pod以外,Kubernetes第二個重要的概念就是deployment。

執行另外一個命令kubectl get deploy,發現kubectl run命令除了生成一個pod外,還生成了一個deployment。從這個命令輸出的Desired, Current和Up-to-Date, Available下面的數字,結合前面提到的Kubernetes裏幾乎全部的設計都是圍繞着pod來展開這一指導思想,咱們不難猜想出,這個生成的deployment也是爲pod服務的。

實際上,Kubernetes的初學者能夠把deployment的主要職責理解成是保證pod的數量和健康。

在前面的文章裏,咱們已經知道了怎樣使用docker run啓動一個docker鏡像。然而在Kubernetes的世界裏,咱們不會直接和運行在pod裏的docker容器打交道,而是經過Kubernetes service將pod裏的應用提供的服務暴露給外界消費。

到目前爲止,Kubernetes集羣上尚未任何和應用程序相關的service生成。命令kubectl get svc只返回了一個Kubernetes的標準服務。

所以咱們使用命令kubectl expose基於剛剛使用kubectl run生成的deployment建立一個service:

kubectl expose deployment jerry-ui5 --type=LoadBalancer --port=80 --target-port=80

image.gif

一旦expose命令執行後,get svc命令此次就返回了一個和deployment同名的service,暴露給外界訪問的IP地址爲35.205.230.209:

因而,使用url 35.205.230.209/webapp就能訪問運行在Kubernetes pod裏的SAP UI5了:

Kubernetes保證應用程序高可用性和伸縮性的一些體驗

到目前爲止咱們的SAP UI5應用僅僅運行在Kubernetes集羣上的一個工做節點的單個pod裏,尚未感覺到這個應用運行時的表現和以前運行在Docker容器裏有什麼差別。

咱們如今就來嘗試下Kubernetes deployment的水平擴展功能。在Kubernetes操做臺裏選中deployment,從菜單裏執行Scale命令,

設定新的pod的數量:下面截圖的3,意思是告訴這個deployment,在命令執行完畢後,它必需要努力保證,在任什麼時候候由它控制和監控的pod個數必須等於3。

固然這個控制檯上的圖形菜單在命令行裏也存在對應的命令,咱們後面會用到。

上圖OK按鈕點擊後,再次執行kubectl get pod, 能觀察到水平擴展執行以後,生成了兩個新的deployment,因此此次get pod命令總共返回了3個pod,其中後兩個pod從Age能看出是水平擴展執行以後剛剛建立的。

使用kubectl describe命令查看deployment的明細,在Replicas這個字段裏看到這個deployment控制的pod的運行時明細:

3 desired | 3 updated | 3 total | 3 available | 0 unavailable

咱們如今故意用kubectl delete刪除一個pod,再次查看,發生一個新的pod瞬間就自動生成了,處於運行狀態的pod總數仍然爲3。

Kubernetes滾動升級(Rolling Update)特性體驗

滾動升級是Kubernetes一大特點,顧名思義,這是一種平滑過渡的升級方式,經過逐個容器替代升級的方式,來實現無中斷的服務升級。下圖deployment的describe命令的輸出,其中字段StrategyType字段代表kubectl run建立的deployment默認的升級方式就是滾動升級。

我設計了這樣一個簡單的升級場景:個人SAP UI5應用1.0版本同時運行在一個Kubernetes節點的10個pod上。在整個應用不中斷的前提下,經過滾動升級的方式升級到2.0版本。

因爲上一篇文章我上傳到Docker Hub上的鏡像的標籤爲默認的latest,因此我須要在Docker Hub上分別製造兩個標籤爲v1.0和v2.0的鏡像。

下面的命令行推送一個標籤爲v1.0的鏡像到Docker Hub:

修改UI5應用明細頁面的標題,在文字後加上一個**(v2.0)**, 用來表示這一版的應用爲2.0版本:

一樣將這個2.0版本的鏡像推送到Docker Hub上:

Docker Hub上兩個版本的鏡像都就緒了:

首先使用1.0版本的鏡像,啓動單個pod去執行SAP UI5應用:

kubectl run jerry-ui5 --image=i042416/ui5-nginx:v1.0

使用scale命令將單個pod水平擴展到10個pod:

kubectl scale --replicas=10 deployment/jerry-ui5

上圖看出kubectl get pod返回10個處於運行狀態的pod。

使用下面的命令觸發滾動升級,把名爲jerry-ui5的deployent基於的鏡像從v1.0升級到v2.0:

kubectl set image deployment/jerry-ui5 i042416/ui5-nginx=i042416/ui5-nginx:v2.0

使用kubectl rollout status deployment/jerry-ui5查看滾動升級的實時進展狀況。上圖顯示的日誌代表,在某個時間點,有多少箇舊版本的pod正等待被終止,有多少個新版本的pod已經處於可用狀態。

  • X old replicas are pending termination

  • X of Y updated replicas are available

任意點開一個pod查看明細,發現其使用的docker鏡像已是v2.0版本了:

最後在瀏覽器裏看到訂單明細頁面的標題,後面已經出現(v2.0), 再次確認了滾動升級已經成功結束了。

本文介紹的只是Kubernetes特性的冰山一角,更多細節,有待咱們去學習,畢竟SAP雲平臺即將支持Kubernetes環境了。感謝閱讀。

要獲取更多Jerry的原創文章,請關注公衆號"汪子熙":

相關文章
相關標籤/搜索