Google 於2015年釋出Kubernetes(簡稱K8S)後,引起了話題。原先僅是屬於內部專案 – Borg,IT大廠如Redhat, CoreOS, IBM, 甚至 Amazon, Microsoft 這些公有雲端供應商都搶著整合進自己的服務中。到底是什麼原因讓Kubernetes爆紅?
容器興盛的開始
相信您一定聽過Docker,這個在2013年推出,以碼頭貨櫃命名的容器,強調build, ship and run的觀念(可前往Katacoda教學網站試試看)。Docker的輕量虛擬化的技術及易於移植的特性,非常利於現代雲端服務的開發及部署。相對來說,傳統的虛擬機需要追求高規格,且在基礎設施和維運(Ops)上需要花費非常多的工夫和心力。以下是傳統虛擬機器與Docker容器所做的比較[1]:

*詳細可參考Docker官方網站
當開發維運時,最希望的就是在部署後持續監控,當任一台伺服器流量過頭的時候,希望可以自動擴展;當流量很低迷時,可以自動縮減伺服器。除此之外,最重要的是,當一台伺服器掛點後,希望可以自動修復,而且隨時必須保持服務實例的個數。以上很多功能Docker都可以幫您做到,並利用容器來提供服務。這樣的服務型態被稱作CaaS(Container as a Service),看起來一切都很美好。但是Docker容器不是萬能,在容器/服務個數越來越複雜的情況下,如何管理叢集和服務的生命週期,將會是各家容器編排管理(orchestration)的能力。其中Google的Kubernetes就是一個十分精良的容器編排管理工具。
微服務架構的成形
應用推展的過程中,程式碼將越來越龐大,傳統單體架構(Monolithic Architecture)的服務會造成巨大的不便(如下圖[2]),例如:
1.龐大且複雜的程式碼 -除錯、新增功能與測試都包在一起,變得十分複雜
2.容易以低效率的開發方式進行 – 利用新語言和新框架將更為困難,因為搬移或更動將耗費巨大成本
3.不利於敏捷開發 – 現今的服務幾乎是每天更新,單體架構會讓這件事變得很耗時間
4.可靠性低 – 單體架構是將所有的模組均建構在一個程序(process)內,當其中一環有bug時,容易牽一髮動全身

而微服務(microservices)架構正好解決了這樣的問題(請見下圖),將每一個具有商業邏輯的服務獨立出來,例如不再將所有資料都寫入同一個資料庫,而是每個單獨的服務都有一個最適合自己本身結構的資料庫。好處是讓每個服務都可以用最適合自己的語言、資料庫來開發。從下圖可以看到,乘客管理、Web UI、金流等都是一個獨立出來的微服務,而每個服務都開放了REST API實行客戶端或者服務之間的溝通。在實作上,每一個商業功能/服務都可能是一台VM或者一個容器。

Kubernetes特別適合微服務這樣的架構。將數個容器組合起來成一個服務(Service,註:Service是K8S的專有名詞,下面會介紹),Kubernetes也提供了良好的服務發現(Service discovery)機制,讓每個服務彼此可以通信。最重要的是K8S強大的編程可以自動擴展服務,甚至還可以對大規模的容器作滾動更新(Rolling update)以及回滾機制(Rolling back/Undo),更可以整合CI/CD等DevOps的工具,絕對讓您用最小的力氣管理最龐大的系統。
Kubernetes的架構
了解容器和微服務的基本概念後,您就會了解K8S正是實現微服務架構的一個完美工具。Kubernetes還是一個開源專案,您可以自己設計並作出貢獻。更令人興奮的是,由於開源的特性,更多的雲端供應商也將K8S納為己用,Google就更不用說了,您可以在Google Container Engine (GKE) 裡面使用Kuberenetes。
話不遲疑,現在來瞧瞧K8S的架構:

K8S屬分布式系統,主要元件有:
1.Master – 大總管,可做為主節點
2.Node – 主要工作的節點,上面運行了許多容器。可想作一台虛擬機。K8S可操控高達1,000個nodes以上
3.masters和nodes組成叢集(Clusters)
更細部來看:

Master 包含了三個基本組件
Etcd, API Server, Controller Manager Server
Node 包含了四個基本組件
Kubelet, Proxy, Pod, Container
這邊不打算細項討論,有興趣的朋友可參閱這本O’Reilly免費電子書[3] 或者 官方互動教學網站 試試看。現在我們著重在K8S最重要的三個部分,即是:
Pod
Service
Deployments (Replication Controller)
Pod
容器是位於pod內部,一個pod包覆著一個以上的容器,這造成K8S與一般容器不同的操作概念。在Docker裡,Docker container是最小單位,但在K8S可想作pod為最小單位。從以下pod的特性來看,就可以了解為什麼它是K8S裡面三巨頭之一了。
1.Pod 擁有不確定的生命週期,這意味著您不曉得任一pod是否會永久保留
2.Pod 內有一個讓所有container共用的Volume,這會與Docker不同
3.Pod 採取shared IP,內部所有的容器皆使用同一個Pod IP,這也與Docker不同
4.Pod 內的眾多容器都會和Pod同生共死,就像桃園三結義一樣!
Service
K8S的 Service 有它的獨特方法,我們看看它的特性
1.每個Service包含著一個以上的pod
2.每個Service有個獨立且固定的IP地址 – Cluster IP
3.客戶端訪問Service時,會經由上述提過的proxy來達到負載平衡、與各pod連結的結果
4.利用標籤選擇器(Label Selector),聰明地選擇那些已貼上標籤的pod
Deployments
舊版的K8S使用了副本控制器(Replication Controller)的名詞,在新版已經改成 Deployments囉。Deployments顧名思義掌控了部署Kubernetes服務的一切。它主要掌管了Replica Set的個數,而Replica Set的組成就是一個以上的Pod[4]。
1.Deployments 的設定檔(底下以YAML格式為例),可以指定replica,並保證在該replica的數量運作
2.Deployments 會檢查pod的狀態
3.Deployments 下可執行滾動更新或者回滾

至於Kubernetes怎麼建構服務的呢? 又如何在GKE內使用呢? 如果這篇文章迴響不錯,後續會再向各位解說喔 🙂
參考資料:
[1] http://www.ithome.com.tw/news/91847
[2] https://www.nginx.com/blog/introduction-to-microservices/
[3] O’Reilly free e-book http://www.oreilly.com/webops-perf/free/kubernetes.csp
[4] https://kubernetes.io/docs/user-guide/deployments/