【K8s 是什麼】比較 Docker 容器、K8s 和 GKE 的架構與優勢

【K8s 是什麼】比較 Docker 容器、K8s 和 GKE 的架構與優勢

Kubernetes(K8s)是什麼?和 Docker 相比有哪些差異?而 Google Kubernetes Engine(GKE)相較 K8s 又多了哪些優勢呢?一起來認識容器化時代裡不可不知的 Docker、K8s 和 GKE 這三大服務吧!

Docker 容器―微服務的現代化基礎

容器化服務為何會誕生呢?現今的軟體應用產量大增,其呈現方式也從過去所有服務全裝在一起的形式,發展成分散且輕量的分散式架構與無伺服器技術(Serverless),讓軟體產品在迭代更新與服務運行上能更快速且穩定。而容器化技術就彷彿是輕量化時代的里程碑,所以下面我們就首先來認識什麼是 Docker 容器化服務吧。

Docker 容器的出現

在認識 Docker 容器前,這邊先來了解虛擬主機(VM)當前所面臨的困境。過去架設一個網站,除了需要靜態的程式碼與圖片等網頁資源,如 HTML、CSS和 Javascript 等;也會用到處理客戶端連線的 Apache、Nginx 等網站伺服器,和儲存與讀取資料的資料庫。

而 VM 若以分散式服務來規劃這樣的三層式架構,會變成一個服務對應一台專門的VM,並以內網串接進行資料傳遞。這樣當一台 VM 壞掉或過載,我們就能以映像檔(Image)重啟或增加 VM,確保網站正常服務。

VM 三層式架構_示意圖
VM 的三層式架構

但,VM 需要搭配作業系統(OS)的配置會產生3個問題。第一,每個服務都需佔據大量的基礎設施資源創建 OS;第二,重啟或新增 VM 需花費大量時間開機,導致服務從中斷到恢復的過程非常漫長;第三,若遇到公司需將服務搬遷的狀況,OS 的版本與規格常增加搬遷困難度,非常不符合當代軟體的營運需求。而「Docker 容器化服務」,便是解決上述問題的一帖良藥。

Docker 容器的優勢

Docker 容器透過封裝應用程式與其相依性配置形成輕量的映像,且可直接運行在宿主機(host machine)上,減少對宿主機負荷的同時提供更多容器服務使用。而輕量化帶來的好處除了上述所提,它也讓 Docker 容器提供一致性的發布環境,使開發團隊可輕易地攜帶與轉換運行環境,提高協同作業的便利性。

另外,Docker 容器還能在數秒內完成建置,讓我們可快速地發布與更新服務。反觀 VM 映像檔因需涵蓋 OS 相關內容而相對肥大,且還須透過監視器(Hypervisor)模擬硬體環境以執行映像檔,消耗更多的服務資源並徒增宿主機的負荷。

訂閱 Cloud Ace 電子報
掌握每月最新研討會資訊、雲端技術文和數位轉型參考!

Kubernetes(K8s)― Docker 容器編排工具

上面我們了解到一台宿主機可運行多個 Docker 容器服務,但,若我們今天啟用了多個 Docker 容器在多個宿主機上,該如何管理這些容器呢?這時,我們需要的就是容器編排工具(Container Orchestration)。坊間有各種容器編排工具,比如 Docker 的 Docker Swarm、可以用來測試的 Docker Compose 和紅帽的 OpenShift 等,而當中最具代表性的無疑就是 Google 於 2014 年對外開放的 Kubernetes(K8s)

K8s 前身是 Google 內部的 Borg 叢集管理系統。而如下圖所示,過去管理者需各別管理不同主機內的容器。為了確保所有容器服務正常,管理者需設置對應的監控系統並手動重新部署有問題的環境,在管理上非常不易。

Docker、K8s 架構比較圖

而 K8s 則提供可彈性運行分散式系統的自動化管理架構,透過集中化的管理介面控管所有節點。從服務的自動部署、自動修復、負載平衡、權限控管,到服務間的溝通與滾動式更新都可以透過 K8s 達成。

Kubernetes 提供的服務:
1. 支援負載平衡並分配網路流量與服務自動擴展,達成高擴展性的穩定服務。
2. 可自動掛載自訂的儲存系統,與外部基礎設施串接。
3. 可透過 YAML 描述檔部署容器服務,且可指定容器所需之 CPU 與 RAM。
4. 可自動重啟失敗的容器、替換容器,並刪除不健康的容器。
5. 可儲存管理敏感資料如密碼、金鑰,使其能供給容器使用。
6. 可執行 Canary 部署、Blue/Green 部署、滾動式更新、回滾更新。

K8s 是什麼― Cluster 介紹

K8s 是以叢集(Cluster)作為單位來控管其內部的系統。在 Cluster 中,我們可將其切分為控管單元的 Control Plane 與服務資源單位的節點(Node)。簡單來說,用戶會透過 Control Plane 對 Node 與其內部的 Pod(多個容器組成的最小單位)進行管理與監控,而 Control Plane 內又由以下四種服務組成。

Control Plane 服務元件:
1. API Server:作為內外溝通的介面接收請求並觸發操作。
2. etcd:K8s 的儲存服務,會儲存狀態、設置與敏感資料。
3. Scheduler:為 K8s 的調度服務,決定哪些 Pod 要分配給哪些 Node。
4. Controllers:透過多個控制器如 Replication Controller、Endpoint Controller、SA and Token Controller 來調節系統狀態。

K8s Cluster 架構圖

K8s 是什麼― Node、Pod 介紹

接著來認識 K8s 中實際提供服務的兩個單位,NodePod。我們可將 Node 視為具有定義的運算與儲存資源的獨立機器,讓最小單位的 Pod 能被建立在其中。而 Node 中還有兩個服務元件,分別是 kubelet kube-proxy。kubelet 負責接收 Pods 的當前狀態以檢查當中的容器健康狀態;而 kube-proxy 則是用來傳遞 Node 內外網路流量給 Pod 的網路代理。

K8s Node、Pod 架構圖

而 Pod 作為 K8s 中的最小元件,負責運作與管理一個或多個容器服務,而 K8s 不以容器為最小單位,是因為網路介面的管理將會非常複雜而困難。所以每個 Pod 中都會有一個獨立的網路介面,用以提供 Cluster 內的 IP 位置以便於服務間的溝通與對外的開放。

而 Pod 內則轉用 Port 來對接各別容器服務,使內外流量皆能準確地傳遞給指定的容器。考量容器服務重啟會造成資料遺失,K8s 除了設計服務為無狀態(stateless)外,也可透過 Volume 將 Pod 內的 Container 轉為有狀態(stateful)服務。

K8s 服務― Pod 的垂直與水平擴展

依據上述所提 Pod 的特性,我們在設計 K8s 服務部署時,可考慮將彼此互相有需求的容器放進同一個 Pod,避免有容器還沒啟動,另一個有依賴性服務的 Pod 就先一步運行而造成錯誤。而既然以 Pod 作為容器服務的群組單位,我們的自動擴展(Auto Scaling)自然是要以 Pod 作為運作的單位囉。

如上圖所示,K8s 的 Pod 有兩種自動擴展模式。一個是在 Node 中增加更多相同服務 Pod 的 Horizontal Pod Autoscaler(HPA);另一個是對單一 Pod 進行運算與儲存資源擴充的 Vertical Pod Autoscaler(VPA)。而當 Pod 進行 HPA,K8s 的負載平衡會自動為我們將流量平均分配給每個 Pod,使服務能在用戶無感的情境下擴展。

K8s 劣勢―建置過程與 Day-2 維護管理

在了解了 K8s 的強大服務能力後,相信大家現在應該迫不及待想使用,但儘管 K8s 提供了許多強大的功能,使用前我們還是要先經歷一段冗長的安裝設置過程。例如 Cluster 與 Node,都需各別進行設置與相關套件的安裝。如下圖所示,資源計算、第三方套件安裝、 K8s 環境建置、網路設定等,全都是非常繁瑣的過程。且只要有一個環節出錯,光除錯就需要大量的時間。

Day-2 維護管理_流程圖

除了安裝設置,Day-2 維護管理也是場大工程,從寫排程收集 Log 到設置額外套件監控狀態數值,都須人工完成。而一旦硬體出問題,又會有更多事項要處理簡直沒完沒了。所以下面我們就要來了解 GCP 上的 K8s 能為我們做什麼,有效減少使用 K8s 會遇到的難題。

Google Kubernetes Engine(GKE)― K8s 代管服務

前面講述了容器化服務與 K8s 提供的自動化部署與管理服務所帶來的好處,但同時我們也看到了其中需面對的難題。所以接下來將為大家介紹 Google Kubernetes Engine(GKE)的服務架構,了解 GKE 如何解決先前我們提到的問題,提供使用者更便捷的服務。

GKE 是什麼―服務架構介紹

如下圖所示,GKE 基本的用戶操作介面與 K8s 相同。使用者可透過 kubectl 指令對 GKE Cluster 的 Control Plane 呼叫 API,來控制 Cluster 內部元件。且呼叫 API 的方式可透過 HTTP、gRPC、GUI 下達,也就是說除了原本 K8s 的指令式控制外,我們也能透過 GKE Console 圖像介面來操作 Control Plane。而 Control Plane 的建置、更新與維護皆由 GKE 代管,所以運算、儲存等硬體資源,和 K8s 軟體、網路環境的安裝與更新都可假手 GKE 處理,大量減輕使用者的負擔。

另外 GKE 也會自動利用 Google Compute Engine(GCE)創建 Node,讓運算資源能有效運用雲端的便利與擴充性。而除了基本元件設置會使用 GCP 的資源,GKE 也內建了許多 GCP 服務的串接。如 VPC 網路環境的串接、作為容器服務曝露點的 Load Balancing,和前面提到 Day-2 所需要的稽核紀錄需求。由於 GKE 已內建將各層級紀錄資訊即時收集入 Logging,所以使用者可透過 Monitoring 觀察使用即時狀態。除此之外當然還有代管式資料庫網路防護工具大數據分析等雲端服務可供使用,而這完善的資源整合,也讓我們能更專注於促進公司發展的軟體開發。

GKE 特點―不同 Cluster 類型的 HA 實踐

前面提到 GKE Cluster 具備自動化建置功能,我們可透過圖像化介面設置自訂的 Cluster 與 Node 來建構 GKE 的整體環境。而雲端服務應用上的一個重要效益就是高可用性(High Availability)部署的可能性,這點在 GKE Cluster 的自動化建置上也能直觀地被體現。

介紹 K8s Cluster 時我們提到 K8s 將控制與資源分成 Control Plane Data Plane(即 Nodes),而 GKE 也將其 Cluster 的建置類型依照 Control Plane 與 Data Plane 的 HA 組合進行分類。所以假設我們因成本考量不希望建置 HA,那 GKE 提供的 Single-zone Cluster,可讓 Control Plane 與 Data Plane 皆建立在單一 Zone 內,只要該 Zone 的機房不發生問題,部署於其中的 GKE 服務就都能有效運轉。

但若今天考量到服務穩定性,無法接受任何單一機房事故導致服務中斷,那我們就能使用 Multi-zone 的 Cluster,將 Data Plane 部署於同一 Region 內的所有 Zone。如此一來即便今天運作主要服務的 Zone 發生事故,也僅會發生無法連結 Cluster API Server 的狀況,我們部署的容器服務依舊能運行。而若要讓 Control Plane 也不中斷就可選擇 Regional 的 Cluster,將 Control Plane 也部署於同 Region 的每一個 Zone 內達成完全的 HA。

GKE 介紹― Node Pools 服務

前文我們提到在 GKE 中,Node 是由 GCE 創建的。且有別於自行創建的 K8s 需手動對各別 Node 安裝對應資源並建置網路環境,GKE 在 Cluster 建置時便會依據我們對 Node 的需求,建立對應的 VM 資源並設置所需的所有環境。另外還能做到基於 Node 的自動擴展,避免硬體資源匱乏。

基於上述優勢,GKE 更發展出了 Node Pools 服務,我們可依據容器服務所需的資源來定義多個 Node Pool。舉例來說當今天只需用最小的計算能力執行容器服務,可選擇最便宜的 VM 機型作為 Node Pool。但如果要運行有 ML 功能的容器,那就可以設定一個具有 NVIDIA GPU 的 Node Pool,大幅提升其計算能力。

而部署服務時,我們可透過描述檔 (YAML)指定 Pod 要執行在哪個 Node Pool 中,以便靈活依據不同服務的資源需求配置 Pod 到合適的 Node Pool,防止不必要的硬體虛耗進而減少專案成本。此外,我們知道 GCE 可透過 Service Account 指定權限並使用對應的 GCP 服務。所以同理,我們也能在 Node Pool 中指派 Service Account ,使同 Pool 中的 Node 都可使用同權限允許的存取服務,提升專案安全性。

GKE 介紹―三層式資安防護機制

我們知道在資安防護概念中,最好的策略就是在每一個層級都加上防護的措施,讓駭客因為架構複雜度高而打退堂鼓。因此這邊將介紹能替 K8s 加上層層防護的 Layer of Defense。如下圖所示,我們可將 GKE 的安全防護機制分為 Project、Cluster 與應用程式部署層級。而 GKE 作為建立在 GCP 上的代管服務,當然也預設將所有雲端內部傳輸與儲存的資料加密,實踐標準的資料防護。

GKE 的三層防護機制

Project 層級防護機制

GKE 是建立在 VPC 網路環境上的服務架構,所以從 Project 層級來看,Firewall rules 是可有效保護 GKE 環境的。這邊提醒務必要將 GKE 所在的 VPC 防火牆對外存取範圍限縮,最好僅限工作環境的 IP Range。而 GKE 延續所有 GCP 服務預設有即時紀錄 Audit Logging,只要透過簡易的核可設置就能看到所有 GKE 操作的稽核紀錄,達到公司內部的資安防護。

另外,當我們部署 Ingress 服務,GKE 會使用 HTTP(s) Load Balancer 來開放容器的對外服務,因此只要搭配 Cloud Armor 就能防禦 L3、L4 與 L7 的攻擊,並限縮存取服務的用戶 IP 和地理位置等資訊,提升服務提供窗口的安全性。同理,在 Project 層級,我們也能透過 IAM 限制操作者權限,結合上述的 Service Account 賦予 Node 權限。

Cluster 層級防護機制

接著是 Cluster 層級的防護措施。首先,基於對 Control Plane 的保護,Cluster 在建置時便可設置為 Private Cluster,讓 Cluster 所在的 VM 不具備外部直接存取的能力,進而構成封閉的開發環境。此外,我們甚至可以設置針對 Control Plane 存取的白名單,限定只有特定的網段才能進到 Control Plane 執行操作。

對比前面提到的 IAM 權限,K8s 中也有著相似的角色權限服務,即 RBAC(Role-based access control)。RBAC 透過賦予角色權限來指定特定用戶訪問 K8s API 的能力,另外我們還可更進一步在 Cluster 層級去設置更細微的用戶權限劃分,安全性上可謂是層層把關。

而 K8s API 的防護還不只如此,所有從 Control Plane 傳輸的流量,不論是 Control Plane to Node 還是 Control Plane to Control Plane,皆會透過 TLS 進行加密傳輸以防止駭客攔截。而在 Pod to Pod 的網路連線上,GKE 也整合了開源的 Calico 網路防護政策,我們只需在創建 Cluster 時一鍵勾選,就能在 GKE 內創建容器服務間的流量傳輸安全政策。

應用部署層級防護機制

最後是應用部署層級的防護。我們知道在軟體服務中,最容易被入侵的就是來源不明的第三方套裝軟體。開發專案時,我們可能需要使用一些被分享在網路上的套裝軟體,這當中只要有人惡意於軟體中加上木馬或蠕蟲,我們辛苦開發的軟體就會非常危險。因此,GKE 可搭配 Google Artifact Registry Vulnerability Scanning,掃描並認證 Docker image 的安全性,再透過設定 Binary Authorization Policy 確保所有部署的 Docker Image 皆通過認證,確保應用程式部署流程的安全性。

如同 Node(GCE)用來給 GCP 驗證權限的 Service Account,GKE 也可對其內部的 Pod 設定 Workload Identity,使 Pod 能透過 Workload Identity 來使用 GCP 提供的服務。而上述這些層層的權限設置、檢查與加密服務,就是 GKE 能有效保障 K8s 遠離駭客攻擊的秘訣。

如何決定要不要使用 GKE 服務?

到這裡,相信大家對容器、K8s 與 GKE 都有了一定的了解,那麼接下來的問題就是我們到底該如何決定是否需要使用 GKE 呢?代管服務雖然方便而強大,但仍舊有著其性質本身的限制,因此下面提供5個考量點,方便各位評估當下狀況是否需使用 GKE 服務。

是否使用 GKE 服務可參考以下問題:
1. 是否需要自動化的軟硬體更新服務?
2. 是否需要客製化的 K8s 網路連線服務?
3. 是否需要自動化且安全的 CI/CD 流程?
4. 是否需要自動化的資源擴展?
5. 是否需要自動化的 Log 收集與即時監控?

以上就是容器化服務和 Google Kubernetes Engine 的介紹,未來我們會再分享 GKE 的相關實作教學。大家對文中內容有任何問題都可留言詢問,也歡迎許願感興趣的 GCP 內容。 最後,如果想更了解 GCP 或有技術服務相關需求也都歡迎聯絡我們獲得更進一步的資訊。

延伸閱讀:

【K8s 教學】第一次用 Google Kubernetes Engine 就上手
GKE Autopilot 教學―輕鬆管理 K8s,加快軟體開發流程
[DevOps實作] 使用 Google Cloud 全代管服務達成 CI/CD
[DevOps實作] GitLab部署asp.Net Core到 Kubernetes Engine 達成 CI/CD
使用 Cloud Run 部署一個 API Server

發佈留言