Kubernetes 已成為容器化應用佈署的根本,選擇合適的 Kubernetes 環境和叢集管理方案至關重要。佈署 Kubernetes 叢集有多種方式,包含本地佈署、雲端服務以及混合雲和多雲環境。本地佈署提供完全控制權,但需自行管理維護;雲端服務簡化管理,但可能受限於供應商;混合雲則適合擁有多個叢集的大型組織,提供統一管理介面。基礎設施即程式碼工具如 Terraform 和 Pulumi 可簡化叢集佈署和管理,確保一致性和可重複性。文章也探討了在本地執行 Kubernetes 的挑戰,例如基礎設施組態、叢集維護、負載平衡和持久化儲存等,並提供相關解決方案。
在 Kubernetes 中,Pod 是最小的佈署單元,由一個或多個容器組成,分享相同的網路名稱空間和儲存資源。理解 Pod 的概念對於管理容器化應用至關重要。Pod 之間的通訊透過 CNI 實作,提供扁平化的網路模型,簡化容器間的通訊和資料流動。設計 Pod 時,最佳實務是將應用程式所需的一切包含在 Pod 中,並將狀態儲存在外部儲存中,例如使用 PersistentVolume。文章以 WordPress 為例,說明瞭如何將應用程式層和資料函式庫層分開佈署,以提高穩定性和可用性。最後,文章示範瞭如何使用指令式語法建立第一個 Pod,並解釋了相關引數的含義。
建立第一個 Kubernetes 叢集的關鍵考量
在現代化的容器化應用程式佈署中,Kubernetes 已成為不可或缺的工具。選擇合適的 Kubernetes 環境和叢集管理解決方案對於確保應用的高效運作至關重要。本篇文章將探討建立第一個 Kubernetes 叢集的關鍵考量,包括不同的佈署選項、管理工具以及在本地環境中執行 Kubernetes 的挑戰。
佈署 Kubernetes 的選擇
有多種方式可以佈署 Kubernetes 叢集,每種方式都有其優缺點。主要的佈署選項包括:
- 本地佈署(On-Premises):在本地環境中佈署 Kubernetes 叢集提供了對基礎設施的完全控制,但需要自行管理叢集的設定、維護和升級。
- 雲端服務(Cloud Services):各大雲端供應商(如 AWS、GCP、Azure)提供託管的 Kubernetes 服務,簡化了叢集的管理和維護工作。
- 混合雲和多雲環境(Hybrid and Multi-Cloud):對於擁有多個 Kubernetes 叢集的大型組織,混合雲和多雲管理解決方案(如 Anthos、Red Hat Advanced Cluster Management 和 VMware Tanzu Mission Control)提供了統一的管理介面。
基礎設施即程式碼(Infrastructure as Code)
使用基礎設施即程式碼工具可以簡化 Kubernetes 叢集的佈署和管理。主要的工具包括:
- Terraform:允許使用程式碼定義和管理 Kubernetes 叢集的基礎設施,確保在不同環境中佈署的一致性和可重複性。
#### 內容解密:
此段 Terraform 程式碼展示瞭如何定義一個簡單的 Kubernetes 叢集。
```terraform
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "my-context"
}
resource "kubernetes_namespace" "example" {
metadata {
name = "example-namespace"
}
}
內容解密:
provider "kubernetes"指定了使用 Kubernetes 提供者,並組態了相關的存取憑證路徑和上下文。resource "kubernetes_namespace" "example"定義了一個名為example-namespace的 Kubernetes 名稱空間,用於隔離資源。
- Pulumi:與 Terraform 類別似,Pulumi 使用程式語言(如 Python 或 Go)來定義和管理基礎設施,提供了更大的靈活性和自定義能力。
#### 內容解密:
此段 Pulumi 程式碼展示瞭如何使用 Python 定義一個 Kubernetes 名稱空間。
```python
import pulumi
from pulumi_kubernetes import core_v1
config = pulumi.Config()
context = config.require('context')
provider = kubernetes.Provider('k8s-provider', context=context)
namespace = core_v1.Namespace('example-namespace',
metadata=core_v1.ObjectMetaArgs(
name='example-namespace',
),
opts=pulumi.ResourceOptions(provider=provider)
)
內容解密:
import pulumi和from pulumi_kubernetes import core_v1匯入了必要的 Pulumi 和 Kubernetes 相關模組。config = pulumi.Config()和context = config.require('context')取得了組態中的 Kubernetes 上下文。provider = kubernetes.Provider定義了一個 Kubernetes 提供者,並指定了上下文。namespace = core_v1.Namespace定義了一個名為example-namespace的 Kubernetes 名稱空間。
選擇適合的 Kubernetes 環境
選擇適合的 Kubernetes 環境需要考慮多個因素,包括控制級別、現有基礎設施、可擴充套件性需求和團隊專業知識。
在本地執行 Kubernetes 的挑戰
在本地環境中執行 Kubernetes 提供了對基礎設施的完全控制,但也帶來了一些挑戰,包括:
- 基礎設施組態:需要自動化節點的組態,可以使用 Rancher 的 cloud controllers 或 Terraform。
- 叢集設定和維護:使用 kubeadm 等工具佈署和管理叢集,需要處理證書更新、節點管理和高用性設定等任務。
- 負載平衡和存取:提供對外部應用的存取可能具有挑戰性,可以使用 MetalLB 等工具來提供負載平衡功能。
- 持久化儲存:需要與物理儲存系統整合,可以使用 Longhorn 等工具來動態組態卷和跨節點複製資料。
在 Kubernetes 中執行容器
本章是本文最重要的章節之一,我們將探討 Pod 的概念。Pod 是 Kubernetes 用來啟動應用程式容器的物件,掌握 Pod 的使用是成為 Kubernetes 專家的第一步。
Pod 的基本概念
在前一章中,我們提到 Kubernetes API 定義了一組代表計算單元的資源。Pod 是 Kubernetes API 中定義的資源,代表一個或多個容器。我們不會直接使用 Kubernetes 建立容器,而是建立 Pod,然後由 Kubernetes 將其轉換為計算節點上的容器。
Pod 和容器的關係初學者可能難以理解,因此我們將詳細解釋 Pod 的概念以及為什麼使用 Pod 而不是直接使用容器。一個 Kubernetes Pod 可以包含一個或多個應用程式容器。本章中,我們將重點介紹只包含一個容器的 Pod。
建立、刪除和更新 Pod
我們將使用 BusyBox 映像建立、刪除和更新 Pod。BusyBox 是一個根據 Linux 的映像,包含了許多有用的工具,用於執行測試。同時,我們也將使用 NGINX 容器映像啟動一個 HTTP 伺服器,並探索如何透過 kubectl 的埠轉發功能存取預設的 NGINX 首頁。
為 Pod 新增標籤和註解
我們將學習如何為 Pod 新增標籤和註解,以便更好地組織和管理 Kubernetes 叢集。這將有助於使叢集保持乾淨和有序。
Jobs 和 CronJobs
最後,我們將介紹兩個額外的資源:Jobs 和 CronJobs。透過本章的學習,您將能夠在 Kubernetes 中啟動和管理容器,這是成為 Kubernetes 專家的第一步。
本章主要內容
- 解釋 Pod 的概念
- 啟動您的第一個 Pod
- 使用標籤和註解管理 Pod
- 瞭解 Jobs 和 CronJobs 資源的使用方法
建立第一個 Pod
要建立一個 Pod,我們可以使用 kubectl 命令列工具。首先,我們需要選擇一個容器映像,例如 NGINX。然後,使用以下命令建立一個 Pod:
kubectl run my-nginx --image=nginx:latest
內容解密:
kubectl run:用於建立一個新的 Pod。my-nginx:Pod 的名稱。--image=nginx:latest:指定要使用的容器映像。
建立 Pod 後,我們可以使用 kubectl 命令檢查其狀態:
kubectl get pod my-nginx
內容解密:
kubectl get pod:用於取得 Pod 的狀態。my-nginx:Pod 的名稱。
要存取 NGINX 伺服器,我們可以使用埠轉發功能:
kubectl port-forward my-nginx 8080:80 &
curl http://localhost:8080
內容解密:
kubectl port-forward:用於將本地埠轉發到 Pod 中的容器埠。my-nginx:Pod 的名稱。8080:80:將本地的 8080 埠轉發到容器中的 80 埠。curl http://localhost:8080:用於測試 NGINX 伺服器是否可存取。
在 Kubernetes 中執行容器
瞭解 Pod 的概念
在 Kubernetes 中,Pod 是最基本的執行單元。要掌握 Pod 的使用,首先需要了解其理論基礎。Pod 有一些特殊的特性,理解這些特性對於有效使用 Kubernetes 至關重要。
什麼是 Pod?
在 Kubernetes 中,建立、更新或刪除容器都是透過 Pod 來完成的。Pod 是一組在同一個機器上、以同一個 Linux 名稱空間執行的容器。這是理解 Pod 的第一條規則:Pod 可以由一個或多個容器組成,但同一個 Pod 中的所有容器都會在同一個工作節點上執行。Pod 不能跨越多個工作節點,這是一條絕對的規則。
為什麼要透過 Pod 這一中間資源來管理容器?Kubernetes 本可以設計一個直接管理容器的資源。原因是容器技術鼓勵以 Linux 行程而非虛擬機器的角度來思考問題。容器不是虛擬機器的替代品,它們不是用來執行多個行程的。
容器技術提倡一個金科玉律:容器與 Linux 行程之間應該是一對一的關係。然而,現代應用程式往往由多個行程組成,而非單一行程。因此,在大多數情況下,僅使用一個容器不足以執行一個完整的微服務。這意味著行程(也就是容器)需要能夠相互通訊,分享檔案系統、網路等。Kubernetes Pod 提供了將容器邏輯分組的能力。同一個 Pod 中的所有容器/行程應該被分組在一起,以便一起啟動並享受行程間和容器間通訊的便利。
圖 4.1:容器和 Pod
為了幫助理解,假設你有一個執行中的 WordPress 網誌在虛擬機器上,你想將其轉換為 WordPress Pod 以佈署到 Kubernetes 叢集。WordPress 需要多個行程才能正常運作,是說明 Pod 必要性的最佳例子。
WordPress 的需求
- 一個 NGINX HTTP 伺服器:作為 Web 應用程式,需要一個 HTTP 伺服器行程來接收和提供網誌頁面。NGINX 是一個優秀的 HTTP 伺服器,能夠完美地完成這項任務。
- PHP-FastCGI-Process-Manager (FPM) 直譯器:WordPress 是用 PHP 編寫的網誌引擎,因此需要 PHP 直譯器來運作。
NGINX 和 PHP-FPM 是兩個不同的行程,需要分別啟動,但它們需要能夠協同工作。在虛擬機器上,這很簡單:只需在虛擬機器上安裝 NGINX 和 PHP-FPM,並透過 Unix 通訊端讓它們進行通訊。
在容器世界中,事情變得更加複雜,因為在同一個容器中執行這兩個行程是一種反模式。你需要執行兩個容器,一個用於 NGINX,另一個用於 PHP-FPM,並且需要讓它們能夠相互通訊並分享一個共同的目錄,以便都能存取應用程式碼。
使用 Pod 的好處
Pod 將多個容器包裝在一起,實作了簡單的行程間通訊。以下是 Pod 提供的主要好處:
- 同一個 Pod 中的所有容器可以透過 localhost 相互存取,因為它們分享相同的網路名稱空間。
- 同一個 Pod 中的所有容器分享相同的連線埠空間。
- 你可以將磁碟區掛載到 Pod 上,然後將磁碟區掛載到底層容器,從而實作目錄和檔案位置的分享。
使用 Kubernetes,你可以輕鬆地將 WordPress 網誌佈署為一個 Pod,其中包含 NGINX 和 PHP-FPM 兩個容器。由於它們都可以在 localhost 上相互存取,因此通訊變得非常容易。你還可以使用磁碟區將 WordPress 的程式碼暴露給兩個容器。
程式碼範例:建立 WordPress Pod
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
spec:
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: wordpress-code
mountPath: /var/www/html
- name: php-fpm
image: php:fpm
volumeMounts:
- name: wordpress-code
mountPath: /var/www/html
volumes:
- name: wordpress-code
hostPath:
path: /path/to/wordpress/code
內容解密:
apiVersion和kind定義了 Kubernetes 資源的版本和型別。在這個例子中,我們建立了一個v1版本的Pod。metadata部分包含了 Pod 的中繼資料,例如名稱。spec部分定義了 Pod 的規格,包括它包含的容器和磁碟區。containers列出了 Pod 中的容器。在這個例子中,我們有兩個容器:nginx和php-fpm。volumeMounts定義了容器內的掛載點,用於存取共用的磁碟區。volumes定義了 Pod 可以使用的磁碟區。在這個例子中,我們使用hostPath將主機上的 WordPress 程式碼目錄掛載到 Pod 中。
最複雜的應用程式通常需要多個容器,因此將它們分組在同一個 Pod 中,以便 Kubernetes 一起啟動它們,是個好主意。請記住,Pod 的存在只是為了簡化大規模的容器間(或行程間)通訊。
最後,請注意,在 Kubernetes 叢集管理的機器上手動啟動的容器,不會被 Kubernetes 視為它所管理的容器。它變成了一種不受管控的孤兒容器。Kubernetes 只管理透過其 Pod API 啟動的容器。
也就是說,通常會有隻包含一個容器的 Pod。但無論如何,Pod 是 Kubernetes API 提供的最低層抽象,也是你將與之互動的資源。
在 Kubernetes 中執行容器:Pod 的設計與管理
在 Kubernetes 環境中,Pod 是基本的佈署單元。瞭解 Pod 的運作方式對於管理容器化應用程式至關重要。每個 Pod 在啟動時都會獲得一個私有 IP 地址,並且 Pod 之間可以透過 IP 地址進行通訊。
Pod 之間的通訊
Kubernetes 採用扁平化的網路模型,該模型由名為 Container Network Interface (CNI) 的元件實作。CNI 提供了一個標準化的橋接介面,連線容器化應用程式和底層網路基礎設施,從而簡化了容器之間的通訊和資料流動。
CNI 具有靈活的外掛式架構,這些外掛使用標準輸入/輸出與容器執行時進行通訊。外掛規範定義了網路組態、IP 地址分配和跨多主機連線維護的明確介面。容器執行時呼叫這些外掛,能夠動態管理和更新 Kubernetes 環境中的容器網路。
設計 Pod 的最佳實踐
雖然瞭解 Pod 至關重要,但在實際的 Kubernetes 環境中,大多數團隊使用更高層次的抽象:Deployment。Deployment 自動執行諸如擴充套件和重啟失敗的 Pod 等任務,從而確保應用程式更強壯和易於管理。
設計 Pod 時,應遵循兩個簡單的規則:
- Pod 應包含啟動應用程式所需的一切。
- Pod 應將任何狀態儲存在外部儲存中(PersistentVolume)。
現代應用程式通常將狀態儲存在外部,例如使用資料函式庫儲存(如 Redis 或 MySQL)。以 WordPress 為例,它使用 MySQL 來儲存和檢索文章。因此,建議將應用程式層和資料函式庫層分開,執行在不同的 Pod 中,以提高設定的穩定性。
為什麼要將應用程式層和資料函式庫層分開?
- 資料永續性:將資料儲存在獨立的 Pod 中,可以確保資料不會因為應用程式 Pod 的當機而丟失。
- 可用性:分開佈署可以提高整體架構的可用性。
- 穩定性:應用程式 Pod 的當機不會影響到資料函式庫的運作。
啟動第一個 Pod
在本文中,我們將介紹如何在 Kubernetes 叢集中建立第一個 Pod。首先,我們將使用 NGINX 映像來建立一個 Pod。建立 Pod 需要兩個引數:
- Pod 名稱:由使用者任意定義。
- 容器映像:用於建立其底層容器。
Kubernetes 支援兩種語法來建立 Pod:指令式語法和宣告式語法。指令式語法是直接從終端執行 kubectl 命令,而宣告式語法則需要編寫一個包含 Pod 組態資訊的 YAML 檔案,然後使用 kubectl apply -f 命令套用它。
使用指令式語法建立 Pod
kubectl run nginx-pod --image=nginx:latest
內容解密:
kubectl run:用於建立並執行一個 Pod。nginx-pod:指定的 Pod 名稱。--image=nginx:latest:指定用於建立容器的映像名稱和標籤。
這個命令會根據 nginx:latest 映像建立一個名為 nginx-pod 的 Pod。透過這種方式,可以快速驗證 Kubernetes 叢集的運作狀態,並為進一步的佈署和管理打下基礎。