Kubernetes的架構與抉擇
Kubernetes(後面會簡稱K8S)在Cloud Native世界中是一種作業系統。它提供了運行容器的可靠性(reliable)與可擴展性(scalable)。但我們怎麼運用這種服務呢?應該是自己從頭到尾建置?用實體機來跑?還是用雲端的服務器?還是要用PaaS的服務呢?哪相關的管理工具,workflow tools, 儀錶板還有web interface呢?
看來有很多的問題需要被釐清,但我們會努力嘗試解釋。
這篇文章我們不會專注在很細的技術層面,例如 building, tuning, 與 troubleshooting k8s的cluster。網路上已經有很多類似的技術文件可以參考了。相對的我們會聚焦在了解整個k8s cluster的架構面以及有了這些資訊後根據你的需求如何來運行K8S。我們也會概述使用一些 K8S PaaS的優缺點。
K8S cluster的架構
你大概知道k8s cluster就是好多台Server組合起來的,但甚麼是k8s cluster?它是如何運作的?如同剛剛說的,技術細節不會在這裡出現,但你應該要了解的應該是了解K8S cluster各部分的組成與它們的功用,了解根據你的需求有你有甚麼樣的選項,是自建還是用廠商賣的產品或服務呢。
The Control Plane
這是整個Cluster的大腦稱作control plane。它運行了所有k8s所需要的工作例如: scheduling containers, managing Services, serving API requests等等之類的工作(如下圖)
Control plane 由以下幾部分組成:
kube-apiserver
這是control plane的front-end處理API requests
etcd
這是k8s的Database儲存所有cluster的相關資訊。例如甚麼node還活著,甚麼resourcec在clusterc還是可用的等等。
kube-scheduler
這是決定在哪裡運行新的Pod
kube-controller-manager
這是負責資源的控制,例如Deployment
cloud-controller-manager
這是與雲端平台互動的管理component,例如cloud provider 的Load balancers 與 disk volume
在k8s cluster的node中運行這些元件的稱為master nodes.
Nodes components
在k8s cluster運行你的container的node稱作 worker node.如下圖
在worker node上有幾個元件運行
kubelet
這是負責驅動container runtim讓你的container可以在上面如何運行並且監控它的狀態。
kube-proxy
是網路的元件,主要負責在同一個node or 不同的node 甚至是對internet之間的route request.
Container runtime
這是真正啟用或停止container並且處理它們之間的溝通。有用過Docker的應該知道這就像docker rumtime一樣的作用,但k8s支援更多的runtime像是 rkt或是CRI-O.
除了以上說的這些之外, master node 跟worker node沒有不一樣的地方。一樣都是跑在一台有OS的VM或實體機上。大部分正常的狀況下 master node 跟worker node 運行元件都會在各自的node上面跑,不過如果你是在比較小的開發或測試環境,這些全部的元件是可以調整全部攬在一群機器上面運行的。
Control plane的高可用度
既然Master node運行哪麼多重要的元件通常在正式的環境當然不會只有一台了,所以我們一定會對master node做HA的。一個有HA的master node設定得當的話是可以運行的很好的,但如果node之間的網路如果有問題導致master node之間無法溝通的話哪network partition的問題就會產生了。
而etcd 資料庫的data replication 在HA中是橫跨多個node的,而且能夠在網路無法溝通的狀況下繼續運行。只要這個多node中有一群的法定node(etcd在上面run)有達到的話。
假設以上的設定都得當哪麼在這一群的master nodes中,有node 有重開機或掛掉不能用的話,哪麼整體的control plane服務還會是正常的。
Control plane failure
如果你的control plane是有問題的或是損毀的並不會讓你的container 被關掉,但它可能會讓你的程式或服務的運作會怪怪的或是會發生一些錯誤。例如你把你所有的master nodes都關機,Pods仍然會在worker node會在繼續運行(至少會跑一陣子)。但你無法再佈署新的的容器或是做一些資源異動,另外controllers 的服務(像是Deployment)也沒辦法使用。
因此這邊要再次強調master nodes的重要性。我們需要足夠的master nodes來達成HA的要求。在正式環境master node最好是有三台以上才能達到法定機器樹的運作,而且建議數量的數字"都是單數"。
Worker node failure
相反的,任何一個work node如果有問題或掛掉了是沒有關係的(前提是你有足夠的work node資源),k8s如果偵測到work node有問題,control plane會把上面的Pod再另外於可用的work node上重新起新的Pod(如果control plane是正常的話)。
如同剛剛提及的,work node 的大規模出錯或掛掉將取決與你的infrastructure。如果你是放在地端用很舊的機器,哪大規模work node failure是可能的。但若是在雲端平台的話這個可能性是很低的(比你在地端機房自建k8s還低)。
不過使用雲端平台(AWS/GCP/Azure)的大規模失敗的可能性還是有的。所以像 AWS / GCP/Azure都有所謂的availability zone(簡稱AZ)的概念,在HA的設計上需要注意這一點。但若是測試或開發是可以放在同一個AZ,這樣node之間的流量費用比較省。
信任K8S的HA,但驗證它
雖然k8s HA讓你的master nodes/ work nodes都可以在底層 node fail的狀況下服務能繼續運作,不過經常得測試它才是明智之舉。若你的平台服務有維護期間或是服務不忙的時候(特別是在地端機房自建k8s)嘗試重啟任一台master node與 worker nodes,看看是不是服務還是正常的。
若這個測試是在生產環境的話應該服務需要正常。但是若你是使用雲端平台的PaaS服務(GCP-GKE, AWS-EKS, Azure-AKS),它們的maste node服務是不允許你重開的,因為control plane的服務是這些業者幫你維護的。
K8S的自建成本
在公司要開始導入K8S的之前大家一定都會遇到一個問題需要討論。哪就是在我們把生產環境放到K8S之前,這個K8S 平台是要用買的還是自建呢?你是要買機器(Server/network device/ LB等等)自建還是付錢給廠商讓他們來建平台呢?讓我們看一下我們有那些選擇。
自建意味著你的團隊可能需要不少人來建這個平台,從實體Server到網路設備安裝設定然後k8s 也要安裝設定外加其他可能需要跑的軟體,像是 Redis/PostgreSQL/Nginx等等也需要自己搞定。
但是自建也讓你擁有最高的彈性與最大的控制權。你可以決定你要跑甚麼版本的k8s,甚麼樣的功能要或不要開啟。何時或要不要升級等等之類。不過任何事有好的一面就會有壞的 一面。
自建的工作比你想的還多
自建需要很多的資源投入,從人的方面來說,需要
- 厲害的工程師(這對老闆來說是人力成本)
- 工程師要花時間(這對老闆來說是時間成本)
- 要維護,還要故障排除(這對老闆來說可能是營業損失)。
如果僅僅只是設定讓k8s cluster跑起來事還蠻簡單的,但從零開始的自建到開始讓生產環境跑在k8s cluster上我們有以下議題需要考量:
- Control plane有HA了嗎?如果沒有,哪整個k8s cluster在master node掛掉時就會又有問題了。你還可以deploy 或update你的程式嗎?如果沒有control plane,你正在跑的程式可以有fault-tolerant嗎?
- 你的work nodes的數量夠多嗎?如過掛掉的機器太多或是放在雲端平台時其中一個zone fail,你的服務會停止嗎?你需要自己手動啟用新的work node還是它有自動啟動的機制?
- 你的 k8s cluster夠安全嗎?在這個cluster內所有node的內部通訊是用TLS加密與信任的憑證嗎?使用者與相關的程式在這個cluster是不是最小權限呢(剛好的權限可以執行它們的工作)?容器安全性的設定是否正確?有任何不需要的存取要進到control plane的相關元件嗎?etcd資料庫的安全性設定是否正確與足夠呢?
- cluster裡所有的服務是不是夠安全呢?如果是從Internet來的流量相關的驗證與授權是否正確呢?進到cluster API是不是有得當的限制呢?
- 你的cluster 是一致的嗎?意思是你的cluster有符合CNCF(Cloud Native Computing Foundation)所定義的嗎?(CNCF 的定義部分我們之後會在其他文章說明)
- 你的cluster node是配置完全的嗎?每一台node的底層其實也是Linux的作業系統,在你使用shell scripts設定完之後是不是就放著不管了呢?哪每一台node 的OS要怎麼管理呢? 怎麼update怎麼安全的上patch等等一些傳統的OS管理工作,特別是可能是一群OS需要管理。你需要一些管理工具,例如CHEF。
- cluster中一些資料要不要備份呢?如果需要要怎麼做呢? 回復的程序是甚麼呢?要多就測試一次呢?
- 如果cluster已經開始運行正式環境了,你的長時間的維護計畫是甚麼呢?你要怎麼起一個新的node?然後將相關的配置快速的套用上去呢(CHEF也可以解決這類的問題)?是要自動擴展cluster規模嗎?還是手動呢?
以上諸如此類的問題都是技術主管們在想要自建服務時需要考慮到的問題:人力成本/時間成本/維護成本等等。
它不只是只有初始化設定
現在請謹記在心你需要運行k8s cluster的議題不只只有第一次初始化設定,而是要加上整個cluster的長時間運作。當你對你的k8s infrastructure做出變更或升級時你需要考慮這樣對cluster有甚麼衝擊,例如HA等其他問題都需要考量。
你還需要一套監控機制(最好是在cluster的機器之外)來監控從clutser 底層的機器/實體網路設備到k8s 元件的部分是否都是運作正常,相對的監控系統也需要建立以便能24小時監控。
K8s是一個進步很快的平台,經常有新的功能或版本推出。你可能因為一些維運問題需要常去跟更新以及了解這些更新你現有的環境有甚麼影響。如過你的k8s版本很久沒更新有時需要重建一個新版本的k8s才有辦法用到新功能。有時讀了一些k8s的書或是文章也可能讓你沒辦法馬上做出需要的設定,如果設定也沒有很重要你可能就忘記再去設定了。外加你需要定期的測試整個cluster功能是不是正常的,例如關掉一台master node或幾台worker node。
自動化的復原測試工具像是Netfix的 Chaos engineering可能幫助做這些隨機關機的測試,像是關掉nodes, Pods, 或是切斷網路連線等等這些。不過若你的cluster是跑在雲端平台的PaaS服務上其實測試這些是多此一舉的。
工具不會幫你完成所有的工作
有關K8S相關的工具在市面上讓我們眼花撩亂(要錢的或不用錢的),這些工具是幫助你設定與管理k8s cluster,這些像山一樣多的的工具都會說自己的工具好棒棒。可惜的這些大部份都工具只解決簡單的部分而避開了困難的部分。另一方面好棒棒的企業等級的工具不是貴鬆鬆不然就是一直說在研發中,從另一個角度來說賣斷的軟體長期來看賺的比託管式的服務來得少。
K8S其實是很難的
雖然很多人認為設定與管理K8S是很簡單的,但實際的狀況是它很難。考慮到k8s的功用,它是非常簡單且精心設計的,但它能處理的卻是非常複雜的情況,這個導致困難的軟體產生。
毫無疑問的,K8S需要花費大量的時間與精力(人力)如何正確的管理你的cluster與維持每日24小時不間斷的維運。我們沒有鼓勵你不要用K8S,但是你需要非常了解你自建K8S所花費的投資,但另一面你也可以使用託管式的K8S來用。
自建K8S的管理成本
如果你的公司大到有很多用不完的資源跟聘請一堆熟K8S工程師,哪麼自建對你的公司來說就不太是問題。但對台灣一堆中小企業或新創公司來說,哪來的這麼多錢可以揮霍。所以如果你們公司是這一類型的公司,哪自建對你的公司來說就可能是不可行的方案。
開始用託管式的K8S
基於台灣的大部分企業規模都是中小企業。其實我們鼓勵您使用託管式的K8S服務。原因就如同上面所提到自建的管理成本,使用託管式服務的成本效益比自建來得少(雖然少不了可能要付使用費或license的費用)。除非你要搞一些在託管式的K8S上不允許的先進實驗,或是想省使用費或license費用把開發/測試環境放在上面(但這樣子又會有環境不一致的狀況發生)。
使用託管式K8S好處就是一些底層的工作廠商都幫你處理好了,像是資安基本設定,生產環境等級的HA等都可以在幾分鐘之內處理完畢。如果有一天你的公司大到你可以自建K8S,哪麼原來託管式的K8S架構或運作方式也是你的自建的參考之一。
接下來我們會介紹幾種比較受歡迎的託管式的K8S服務,並提到我們對這些託管式K8S的看法跟我們喜歡每一家K8S的哪一部分。當然如果你一開始只是想嘗試使用自建的K8S(用現有的舊機器或VM)不想付任何費用,我們在後面也會介紹一些安裝K8S cluster的工具。
本篇文章是從中立的角色來分析這些託管式的K8S,不是這些廠商發的業配文。在K8s的世界中變化的速度很快,競爭者此起彼落我們並沒有辦法比較到全部的業者,只是介紹目前這個時間大家比較常用的。
託管式的Kubernetes Services
託管式的K8S服務好處上面有提到節省的管理成本,在幾分中之內就把你的cluster建立好,特別是control plane的部分(只要抓起來用就可以了)。
Google Kubernetes Engine(GKE)
第一個提到的就是Google了,因為他們是第一個提供託管式服務的廠商。同時Kubernetes也是Google發明的並且將它release出來成open source(筆者最熟的也是GKE)。
在GCP的console點來點去幾分鐘內k8s cluster就跑起來了,或是使用GCP的GKE Autopilot(這個更簡單)。GCP會幫你負責control plane的HA, 自動上security patches, master node掛掉它會幫你起新的。你只要用點選的GCP可以幫你把你的cluster自動升級成你想要的版本。你在create K8s cluster時為了達到整個cluster 的高可用度,你可以將cluster 的level 調整成regional level,這樣你的多個 master node and worker就會分散在這些regional的的AZ中。
GKE的Cluster可以根據你cluster負載(node 的CPU or QPS)根據你訂的規則來讓你的work node數量自動的變多或變少。這個好處就是node 的數量關乎到費用,使用量沒哪麼多時可以少付錢。因為Google 是K8s的發明者也是第一個提供K8s託管式服務的雲端業者。GEK會是一個與其它託管式業者比較的標竿(去除掉GCP其他服務沒有其他家哪麼多這個因素)。
Amazon Elastic Container Service for Kubernetes(EKS)
AWS其實提供EKS非常久了,但AWS後期推出了一個自己專屬的容器服務Elastic Container Service(ECS). 雖然ECS跑container還是可用的,不過ECS並沒有像k8s哪麼強大或靈活。顯然,隨著EKS的發布,甚至AWS都決定未來是k8s的世界了。而使用ECS是為了想要更省錢(因為只要一個VM就可以跑,不用像K8s規定的數量)的使用容器服務卻又不需要k8s這麼厲害架構(或多花錢)的客戶所設計的。
但EKS有一些麻煩的地方需要自己手動設定,跟AWS上的一些服務的整合性不是很好。但反過來說就是因為GCP的服務沒哪麼多所以GKE與GCP其他服務整合性才比較高。
Azure Kubernetes Service(AKS)
雖然Azure是第三個提供託管式的K8S服務的公有雲業者但他們的進程其實蠻快的。不過從整體上來看AKS與GKE很相近(應該是說GKE的功能特徵AKS也會抄過去用)。使用console或使用 Azure “az”這個CLI來create k8s cluster.其他部分就跟GKE and EKS沒甚麼不同的地方。
Redhat OpenShift
這是一個蠻特別的K8S託管式服務,因為你可以安裝在地端或是雲端。它也比上面講的三朵公有雲做的還要多,它還多了管理整個軟體開發週期的部分,像是CI(Continuous integration) 與 build tool, test runner, application deployment, monitoring, 跟Orchestration.
OpenShift 可以部署在裸機(bare-metal server)/VM/私有雲/公有雲, 所以基本上你可以用OpenShift create 一個cluster 然後橫跨上述講的這些環境(基本上如果是work nodes 橫跨不同的環境,其實GCP/AWS也提出了它們自己的方案)。基本上OpenShift比較和適合大型組織(有錢有人有資源),因為它的控制權又比在公有雲上多一些。而且它跑在私有雲上你就需要負責一些底層的作業,意味著你需要多一些人手。
用買的還是自建: 我們的建議
我們必然需要快速瀏覽一些可用於管理k8 cluster的選項,因為在K8s 的世界所提供的相關產品範圍很大且種類繁多,並且很多廠商一直在前撲後繼的進入這個世界。但我們會根據一些常識性原則來提供一點建議。其中之一是run less software的理念.
Run Less Software
Run less software 論點有三個主軸,這三個主軸將幫你加快選擇上的困難。
- 選擇標準技術
- 外包無差別的繁重工作
- 創造持久的競爭優勢
對技術控來說使用創新的新技術是興奮好玩的,就像小孩拿到新玩具一樣,但對老闆來說就不是哪麼一回事。使用大家都正在使用的無聊軟體通常是一個好選擇。它可以運作,它可能支援度很好,而且公司也不會這樣陷入不可知的風險跟要處理不可避免的bug.
如果你正在運行containerized workload與Cloud native Application,k8s就是一個最好方法的選項。所以你在選擇k8s 相關的工具或方案時考慮的應該是最成熟,最穩定,大家都在用的。
"外包無差別的繁重工作"是由Amazon定義出來的。意思是又累又煩的工作,像是安裝與管理設定軟體,維護Infra等等之類。這一類的工作沒有特別的,都是照SOP手冊就可以完成的。所以公司的員工精力不應該花在這種事上面。Run less software哲學就在於公司員工不應該做這一類的工作,而必須將精力專注在核心業務上(對一些open mind或外商可能可以,但對台灣老闆可能不是這麼一回事)。
PS:關於外包無差別的繁重工作的概念,有興趣的人可以讀這一本: 貝佐斯新傳:無極限!巔峰中再創新局的亞馬遜帝國
盡可能的使用託管式K8S
根據上面所說的Run less software的哲學來看,我們不應該將員工精力用在k8s的維運(Installing/configuring/maintaining/securing/upgrading/cluster reliable)上(理想上),而應該將這些可以用SOP做完的工作外包出去。
"Cloud native不是一種cloud provider,也不是K8S,更不是container,它不是一種技術。這是通過不做沒有特色的東西來加速公司的業務的做法。"
在託管式的K8s服務中,GKE顯然是目前的贏家。雖然其他人可能會在這一兩年趕上,但GEK還是仍然會保持領導一段時間。但哪就K8S本身來看,若公司整體的IT服務是需要多樣且複雜的雲端服務哪又是另一種評估的方式了。例如AWS/Azure的PaaS DB選擇跟支援度可能比GCP要好一些。
但會不會有Vendor Lock-in的狀況呢?
如果你決定用其中一家託管式的K8S服務哪會不會沒辦法離開到其他平台繼續運作呢?這其實不一定,K8S現在已經是一個標準平台了所以你如果在GKE上運行你的服務,哪麼一樣也可以運行在被認證過的K8S服務業者的平台上。運行k8s其實就是避免Vendor lock-in的第一步並且是很大的一步。
哪麼使用託管式的K8S服務是不是比自建K8S更容易被業者綁架呢?我們認為這是另一回事。自建的K8s會有很多機械式的工作需要執行來維護整個cluster。使用託管式的K8s的所有一切都與特定的cloud provider的API緊密相關。例如你要在AWS啟用EC2來建立與運作K8S, AWS 的腳本(Cloudformation)跟你要在GCP上執行一模一樣的K8S建立/運作的作業,這是完全不一樣。有一些工具可以幫忙轉換這種腳本的差異,但大部分都沒這種功能。
有一部分的原因跑在特定的cloud provider是因為技術人員的偏好,可能是已經熟悉了這家業者的標準做法跟介面。所以你在設計你的程式 與自動化的運行在k8s時應該從k8s的一些標準架構或做法來考量而不是從特定的雲端業者的infra來考量,這樣你就不會被某一個業者給綁架。
一 定要自建的話,請採用標準的工具
如果因為某些原因一定要自建K8s Cluster的話,請採用成熟,強大,大家都在用的工具。視你的需求我們會建議使用kops或是kubespray。如果你已經用AWS很久了未來也會繼續呆著,請用kops.若是你要跨多個環境(多雲跟地端)使用K8s的話,請用Kubespray或是GKE/AWS 的K8S的相對應解決方案。
k8s cluster的管理
如果你連cluster都不想管,只想把容器放上去跑就好的話,這種服務稱為clusterless services,像是 Azure Container Instance ,AWS Fargate或GCP的Cloud Run。這個cluster的管理也由雲端業者幫你代管了,你最多就是把容器放上去跑之前要指定一些參數。像是你的程式需要的CPU / Memory以及其他的服務內容。
總結
現在Kubernetes已無處不在了,不管是在雲端還是地端機房。這一篇我們簡單介紹了一些k8s會用到的工具/服務/產品,希望這些資訊對你在使用k8s時會有用。
不過就如同之前提到的,K8s的世界變化很快有些產品或服務的功能介紹可能已經不是最新的了,但我們希望即使你在閱讀本文時也會有很多改變。然而我們認為基本觀點是正確的: 假若業者可以提供比你自行管理k8s cluster更好更便宜的話,哪就不值得你自行去管理k8s cluster。