avatarJia-Yau Shiau

总结

本网页介绍了Kubernetes (k8s) 的基础架构与使用概念,以及如何通过容器 (container) 和 Kubernetes 提高软件部署和管理的效率。

摘要

随着计算机科学的发展,软件部署已经从单台计算机转向了在计算机集群 (cluster) 上进行。容器化应用程序的部署变得流行,Kubernetes 因其自动部署、扩展和管理容器化应用程序的能力而成为主流。文章从用户的角度出发,概述了容器和 Kubernetes 的基本架构,以及如何通过 Kubernetes 实现应用程序在集群中的高效部署。

文章首先解释了容器的概念,即一个轻量级的运行单元,包含代码和运行所需的依赖。与传统的虚拟机 (VM) 相比,容器更加高效,因为它不需要生成整个操作系统内核,而是直接调用宿主机的内核。接着,文章介绍了 Kubernetes 的核心组件,包括 Control plane (Master) 和 Compute machine (Worker),以及 Persistent storage 和 Container registry。Kubernetes 能够自动调度资源,支持自动扩展 (auto scaling),并且可以与 Load Balancer 结合,实现更稳定的系统。

文章还介绍了 Kubernetes 的基础架构,包括 Pods、Volumes 和 Persistent Volumes,以及如何使用 kubectl 和 YAML 配置文件来操作 Kubernetes。最后,文章提供了一些关于 Kubernetes 的推荐资源,并强调了 Kubernetes 在未来软件开发中的重要性。

观点

  • 容器化是当前软件部署趋势,它提供了一种轻量级的运行环境,使得应用程序可以快速地在不同的环境中部署和运行。
  • Kubernetes 是一个强大的容器编排工具,它简化了容器化应用程序的部署和管理,并且提高了系统的可扩展性和稳定性。
  • Kubernetes 的核心组件包括 Control plane 和 Compute machine,以及 Persistent storage 和 Container registry,这些组件共同构成了 Kubernetes 的基础架构。
  • Pods 是 Kubernetes 中应用程序运行的最小单位,它们可以包含一个或多个容器,共享网络和存储资源。
  • Persistent Volumes 解决了容器存储的问题,使得数据可以在容器重启或迁移后继续存在。
  • 使用 kubectl 和 YAML 配置文件是 Kubernetes 上部署和管理应用程序的标准方式,它允许开发者以编程的方式定义和创建资源。
  • Kubernetes 的学习和使用虽然有一定的学习曲线,但是它的生态系统和社区支持使得它成为当前和未来软件开发的重要组成部分。

使用者導向的Kubernetes (k8s) 入門介紹: 基本架構與使用概念

隨著電腦科學的發展,主流的軟體系統已經不是單單部屬在一台計算機上,而是部屬在一群計算機組成的叢集 (cluster)。一般常見的雲端資源,其實背後也都是由 cluster支持。另一方面,因為近期使用容器 (container) 來部屬應用程式也相當流行,因此部屬基於 container的 Kubernetes自然成為架設 cluster的熱門選項

Kubernetes (k8s) 是用於自動部署、擴充和管理「容器化應用程式」的開源系統,是目前軟體開發領域炙手可熱的要角。藉由 Kubernetes可以建構出一套穩健的 cluster與營運系統,並且無縫使用大量的開源專案資源。不過 Kubernetes本身使用與操作也具有一定難度,因此對於大部分的人來說也是有一定的學習難度。這篇文章以使用者的角度,概述 container與 Kubernetes的基本架構與使用概念

Cover made with Canva. (圖片來源)

文章難度:★★★☆☆ 閱讀建議: 本篇文章為 Kubernetes的入門簡介,從 container切入,就 Kubernetes的基本設計與元件介紹,再用最基本的 pod操作範例結尾。據我所知,對於大部分的 data scientist來說,接觸 Kubernetes的過程很容易被無數的文檔與細節埋沒。因此這邊文章嘗試以貼近使用者的角度,介紹 Kunernetes的理解大方向,減少在理解過程中被過多細節干擾而抓不到重點。 推薦背景知識:container, Docker, virtual machine, cluster computing, cloud computing, Kubernetes, object storage, network filesystem, microservices architecture, zero-downtime deployment.

如前所述,時下主流的軟體系統已經不是單單部屬在一台計算機上,而是部屬在一群計算機組成的叢集 (cluster)。要部屬在 cluster上一個很直接的問題就是如何將應用程式快速地在不同計算機上部屬,而 container的觀念就從這裡展現它的價值。

What’s Container

Container是一個軟體運行單位,包含了程式碼以及執行所需程式庫、系統工具等軟體相依資源。

透過 container,我們可以在不同電腦上快速地建立、測試和部署程式。

Container vs. VM

對比於 Container,另一個很常聽到的名詞就是 VM (Virtual Machine)。其實不論是 Container或是 VM,都是將硬體虛擬化的實現

VM主要的核心概念是透過 Hypervisor提供虛擬的作業平台來執行客戶作業系統,負責管理其他客作業系統的執行階段,可以簡單想像 Hypervisor是在模擬硬體的行為實現硬體虛體化。而 Container不生成整個 OS kernel,透過直接調用 OS kernel,大幅提升效率並減少運行單位大小,可以說是透過虛擬化作業系統實現硬體虛體化,是更輕量化的選擇。

VM與 Container的差異。(資料來源)

OCI & Docker

所謂的 Container本身是種概念,因此需要透過標準規範其相關設定與運作,讓不同 Container的解決方案能夠有更高的相容性,這個就是 Open Container Initiative (OCI)。我們常常聽到的 Docker,其實就是基於 OCI的一種引擎實作 (或者說 OCI提出時大量參考 Docker設計)。

符合OCI的Docker Engine設計。(資料來源)

Docker利用 Linux核心中的資源分離機制,例如cgroups,以及 Linux核心命名空間 (namespaces),來建立獨立的 containers。這可以在單一Linux實體下運作,避免啟動一個虛擬機器造成的額外負擔。 Docker是目前最流行的 container實現,有極其豐富的生態系。

What’s Kubernetes (k8s)

有了 container,開發者就可以靈活地將應用程式在不同的計算機間搬移與部屬,但這也說不上是 cluster。因此,對一群計算機,最大幅度地利用 container的靈活就是 Kubernetes閃閃發光的價值

Kubernetes是用於自動部署、擴充和管理「容器化應用程式」的開源系統。

該系統由 Google設計並捐贈給 Cloud Native Computing Foundation來使用。 它旨在提供「跨主機叢集的自動部署、擴充以及執行應用程式容器的平台」

聽起來有點抽象,簡單的理解就是 Kubernetes可以建立一套由許多 node (可以想像成電腦) 構成的叢集 (cluster),開發者將應用程式,比如說 model service enpoint,或是一個 model training job,容器化後透過 Kubernetes API送到出,由 kubernetes決定實際執行的硬體

Kubernete大方向架構圖。(資料來源)

除了自動決定部屬硬體外, Kubernetes在維護系統時可以依照使用流量自動調度資源。以 API來說,外部進來的 request會被自動安排到不同的實體回應,而隨著 request的增減, Kubernetes也可以自動增加或減少在 API背後提供計算的實體。一般這個負責導流的原件稱為 Load Balancer,而增減運算實體的行為則稱為 auto scaling

Kubernetes可以使用 load balancer實現更穩健的系統。(資料來源)

Container + Kubernetes

複習一下:容器化讓應用程式可以快速的部屬到不同的環境,但即使省略了環境的設定,終究還是要挑台電腦來部屬。而透過 Kubernetes則是可以更進一步地將容器化程式有效地部屬到 cluster,將部屬與管理實體硬體的過程進一步自動化,也是所謂 IaC (Infrastructure as Code) 理念的實踐。

部屬 container到 cluster上的邏輯。(資料來源)

Kubernetes基礎架構

Kubernetes整體上會有以下幾個重要組成元件:

  • Control plane (Master): 負責接受來自 k8s API的 request,再分配給任務給負責執行的電腦,像是一個管理中心。 Control plane可以、也通常是同時交給多台電腦擔任。另外,在 control plane內會額外維護一個稱為 etcd的儲存應用,用來儲存集群狀態和一些中繼數據
  • Compute machine (Worker): 負責實際執行任務的電腦。
  • Persistent storage: container在運行的邏輯與直接跑在電腦上不同,並不是直接把資料寫在硬體上,而是透過背後 engine分發資源。因此通常 container關閉時,資料也都會被自動清除。但其實有許多資料是使用者希望長期保存的,因此 Kubernetes也有對應的資源規劃,稱為 Persistent Volume (簡稱PV),通常是由 NFS或是 object storage (如 S3或 MinIO) 實現。
  • Container registry: 因為 kubernetes執行都是 container,因此需要有一個空間儲存 container images。以 Docker為例,可以直接使用 docker engine的 private registry或是使用功能更全面的 Harbor,也可以直接使用雲端的 DockerHub或 AWS ECR。
Kubernetes架構與重點元件。(資料來源)

Application在 Kubernetes的運作

一個應用程序在 Kubernete的 lifecycle大致分成幾個階段: 提交執行要求後,進入排程等候資源,安排實際資源並執行,最後執行完成後回收資源。以下先介紹 Kubernetes在計算與儲存兩個面向的重要觀念,再看一個部屬應用的簡單範例。

基本運行單位: Pods

Pod是應用程序 (application) 在 Kubernetes cluster運行的最小單位。

以下列幾個 pod的重點觀念:

  • Pod是應用服務的最小運行單位,依照執行狀態大致可分為 pending, running與 completed三個階段
  • 在 Pod被創建後,會先進入排程等候實體資源 (pending),等到資源足夠後,Kubernetes才會將 Pod安排到 Node運行 (running),這時候才會開始實際運作。當 pod內的應用執行完畢, Kubernetes會關閉 pod並回收資源 (completed)
  • 一個 pod 裡面可以存在一個或是多個 container。同一個 Pod 中的 Containers 共享相同資源及網路,彼此透過可以直接透過 local port number 溝通。
Node與 pod的關係。(資料來源)

儲存空間: Volumes & Persistent Volumes

通常虛擬化的計算機至少會包含計算與儲存兩個部分,先前的部分解釋了 Kubernetes如何將計算放到實體的計算機上,但管理計算資源與儲存空間其實是兩個完全不同的問題。

在一般的情況,在創建 pod的時候我們會掛載 (mount) 稱為 volume的儲存空間給 pod使用。與其他container 邏輯相似,在 container 中的檔案不是永久存在的,隨著 container 的重啟檔案就會隨之消失。因為在 Kubernetes中一個 pod可以擁有多個 containers,Kubernetes規劃了更完整的 volume機制, volume不會隨著 containers的關閉而消失,並且可以讓 pod內的 containers同時存取

Pod與 volume的關係。(資料來源)

而對於某些希望長期存在,或者明確地說,不隨著 pod關閉而刪除的資料, Kubernetes則是設計了 Persistent Volume (PV)。基本上通常 PV由 cluster管理員建立,屬於虛擬化的資源,而使用者要使用的時候,則是要 claim要使用多少。在 Kubernetes這個被使用者 claimed的儲存空間稱為 Persistent Volume Claim (PVC),可以像 volume一樣直接mount給 pod使用。

Pod使用Persistent Volume的邏輯。(資料來源)

這邊補充一個小細節,在 Kubernetes PV的設計上, PV與 PVC是一對一的關係,即一個 PV只能被一個 PVC綁定。但一個 PVC可以被不同的 pods存取,因此可以達成跨 pods的資料共用。另外,PV可以分為靜態與動態兩種,不過這篇文章就不多提了。

使用 kubectl與 YAML操作

不論是哪種實作的Kubernetes,通常都支援使用原生的 kubectl在Kubernetes上部署和管理應用程序,在大多數的情況,使用者都是透過 kubectl發送撰寫好的 yaml檔案在 Kubernetes cluster部署和管理應用程序

以下是一個簡單的 yaml範例,定義一個 pod,在 pod裡運行redis (儲存資料庫),並 mount volume給 pod使用。

Kubernetes內各種資源的 config其實都蠻複雜的,可以從重點設定慢慢了解。通常會先看 kind,定義這個資源是什麼類別,可能是 PodDeploymentPersistentVolumeClaim或是其他各種 k8s資源。剩下就像是 container的資源,通常這邊跟 Docker邏輯差不多,還有像是 volume的規劃等等。

使用上通常使用 kubectl來提交資源要求:

在這個範例中,Kubernetes在接收到 YAML spec後,就會開始安排執行這個 pod。當輪到這個 pod執行時, 先安排到某個 node上,再到 docker registry上拉指定的 image,以上範例會去拉 redis/redis。當然 registry可以是公開的 Docker Hub、其他廠商提供的 registry或是自己架設的 private registry。

通常在比較完善的開發流程中,這個過程會被設定為一系列的 workflow,整合到 GitOps的一部分。具體上常見的全開源實作會是透過把 code上傳到 github,在透過 CI/CD Pipeline啟動 Jenkins,由 Jenkins來打包上傳 docker image,並透過 kubectl在 Kubernetes上完成布署。

將 Kubernete與 GitOps結合。(資料來源)

個人感覺 Kubernetes在未來會持續流行很長很長一段時間,因為相關資源已經非常深厚地結合,甚至可以發現在不同雲端平台會有不同 Kubernetes的實作。不過對於使用者來說,其實知道他的大概念後,剩下的就是與自己的工作流程結合了,因此在 Kubernetes整個官方文檔我覺得這頁是最關鍵的:

當然也相當推薦多看看不同開發者或是各大雲端廠商的介紹,畢竟 Kubernetes真的是博大精深,不同人看到的面相一定是很不一樣的。以下列幾個推薦的資源:

好了~這篇文章就先到這邊。老話一句,軟體領域每年改變速度都相當快,說真的要跟緊不是一件容易的事。所以我的觀點可能也會存在瑕疵,若有發現什麼錯誤或值得討論的地方,歡迎回覆文章或來信一起討論 :)

Related Topics

Reference

[1] Docker [Official Website] [2] Kubernetes [Official Website] [3] Introduction to Kubernetes architecture [Red Hat Website] [4] Microsoft Azure Kubernetes Basic [YouTube]

Programming
Kubernetes
Docker
Cloud Computing
Cluster Computing
Recommended from ReadMedium