iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
自我挑戰組

DevOps的下克上之旅( ° ∀ ° )ノ゙系列 第 28

Day 28: Kubernetes 原理

Kubernetes是一個知名的分散式管理、編排Container工具,幫助你將不同的dockerized的APP部屬在不同的環境中(e.g. 不同機器、不同雲端)的container。由Google開源並由GO語言撰寫。由於Kubernetes太長,很多人都稱他為K8S(中間有8個字母)。Kubernetes本身是一個希臘文,意思是船舵或是飛行員的,icon設計為一個船舵,得到了Kubernetes就能在雲端與Container化的暗潮中前行。
https://ithelp.ithome.com.tw/upload/images/20210930/20119044BLZPqDLaR8.png

本文參考自:Kubernetes Crash Course for Absolute Beginners

Kubernetes解決了什麼? 現代化應用趨於MincroServices導致Container應用上升,過去常寫script來管理,但是這實在是太複雜了。因此Kubernetes作為編排Container工具誕生了。Kubernetes有以下幾個優點:

  1. High Available (對於使用者來說幾乎不會有服務暫停時間)
  2. High Scalability (更高的擴展性來應對流量)
  3. Disaster recovery (備份與還原)

Kubernetes 架構

K8S可以區分成至少一個Master與許多Node(Worker)端。採Clustering架構,在Master中會有重要的4個執行部分:

  • API Server: K8s的API接口,負責與Node溝通也是User連進來的入口點。又分成三種User可以操作API Server的方式
    • kubectl : 透過Kubectl指令直接下達命令
    • Rest API : HTTP API接口來調度K8s
    • Web UI : 透過K8S本身的UI來操作K8s
  • ETCD : 保存各個Node狀態的資料庫 Key:Value、reconver 狀態
  • Controller Manager : 管理cluster發生事情
  • scheduler : 當建立新的container(稱作pod)要放在哪個node之中。

Worker Node分成三個部分:

  • kubelet : Node端負責與Master的API Server溝通的、Node之間交換訊息
  • Kube-proxy : 創建虛擬網路的
  • docker : 每個node會包含多個container

https://ithelp.ithome.com.tw/upload/images/20211001/20119044msSpbgOIOy.png

Virtual Network將Node之間、Master與Node之間串聯起來,簡單的來說,Virtual Machine將所有Clustering串聯起來成為一台大機器。

Kubernetes Components

Kubernetes的重要component:

  • Node: Virtula or Physic Machine
  • Pod : Pod為K8s的最小執行單位,運行再Node上。

可以看成是執行的container再外包一層用來與K8s溝通,每個Pod執行1個App (Node.js、DB)。把每個Pod看成是一個獨立的container,那彼此該怎麼溝通呢?整個K8S基於Virtual Machine來溝通,每一個Pod會得到他專屬的虛擬IP,彼此利用這個IP來互相溝通。

https://ithelp.ithome.com.tw/upload/images/20211002/201190444DmNlPMhQK.png

當一個Pod消失後(Container crash之類的原因),重新建立新的Pod不會繼承該IP(即使同樣的container)而會給予新的IP,這對App來說是個麻煩。解法如下:

  • Service : 將虛擬IP與Pod的生命週期切開,Service會保留虛擬IP給下一個繼承該Service的Pod
  • Ingress : 一種內外橋接的Services,將外部網路轉換為虛擬網路的開口。

https://ithelp.ithome.com.tw/upload/images/20211002/20119044DrZsb5jr7h.png

假如今天要讓APP連接Server,我們會在程式內寫上Server的URL、PORT,當這些改變,就得重新build一個新的Image並pull出新的Pod。這就很麻煩了。

  • configMap : 幫助你在pod外部輸入你的變數,並且可以在Pod運行中修改。我們只需要將程式內的變數改成configMap的參數即可。
  • secrets : 保存那些需要加密的變數,用法基本上同configMap

https://ithelp.ithome.com.tw/upload/images/20211002/20119044edORJ5xMob.png

  • volumes : 如Docker一樣,當pod消失data消失。要持久化保存應將資料存在Volumes,可以將資料存在local或是遠端其他K8s clustering中。將storge想成在clustering之外的插鍵,因為K8s並不管pod資料的保存。

https://ithelp.ithome.com.tw/upload/images/20211002/20119044lYqdidhbxG.png

K8s採用clustering架構,為了能夠避免使用者服務暫停,我們可以將POD分配到多個Node之中,而每一個POD由Service所連結,因此可以獲得同樣的虛擬IP。Service同樣的可以用於load balance來動態調整Node之間的負擔。當一個Node上的pod死掉時可以經由另一個Node的Pod接手避免使用者服務中斷。

https://ithelp.ithome.com.tw/upload/images/20211003/20119044VgTi3KEbWK.png

事實上,在開啟clustering時你不會建立第二個Pod,而是會定義一個pods的blueprint,確立會需要多少個pod複製。我們把這個blueprint稱作為Deployment。Deployment就是pod的blueprint,可以看成是pod的更上層封裝(正如pod是container的封裝來符合k8s的應用接口),Deployment讓你能夠更好的在分散式架構中擴展與刪減pods。

  • Deployment : pods的blueprint,解釋如上。

但是會發現如果我們要在資料庫上多開幾個Pod,他們就必須要share同一個data storage。多個database去存取一個data storage會發生data inconsistency的錯誤,也就是同一筆資料同時一個pod寫一個pod讀導致的錯誤。因此我們會在K8s建立Statefuleset來避免data inconsistency。

  • Statefulset : 同Deployment來擴展與刪減pod,但是多了同步的功能來避免錯誤。不過其實Statefulset一般來說很難部屬,推薦將Database放在K8s clustering之外。

上一篇
Day 27 : Github Actions實作自動化推上Azure
下一篇
Day 29 : MinKube 安裝
系列文
DevOps的下克上之旅( ° ∀ ° )ノ゙30

尚未有邦友留言

立即登入留言