Kubernetes 部署:全面指南
Kubernetes 作為開發者社群中的熱門選擇,是廣泛用於在叢集上執行 Docker 容器的平台。這個強大的平台提供了多種方法,讓您能夠部署和更新在容器中執行的應用程式,從而為各種情境提供高度的靈活性。在 Kubernetes 中,容器在 Pod 內執行,其部署則由 Kubernetes Deployment 來定義。這篇部落格文章將探討 Kubernetes Deployment、其類型、部署策略以及最佳實踐。
什麼是 Kubernetes 部署?
在 Kubernetes 中,Deployment 是一種資源物件,用於管理叢集內容器化應用程式的部署與生命週期。它負責為應用程式提供更新,並確保所需數量的相同 Pod 隨時處於運行且可用的狀態。此外,它還為 Pod 和 ReplicaSet 提供宣告式更新。Deployment 是 Kubernetes 中用於自動化縮放、滾動更新及回滾的特點。
Deployment 是 Kubernetes 中的物件,用於指定 Pod 的目標狀態,並透過建立與管理 ReplicaSet 來確保此狀態得以維持。 複製集(ReplicaSet)直接管理 Pod,包括其狀態與數量。部署(Deployment)則告知 Kubernetes 如何修改或建立承載應用程式容器的 Pod 實例。Pod 部署的狀態會透過一份清單(manifest)來描述。
管理員可以高效地縮放複製 Pod 的數量,以高度的控制力執行更新後應用程式程碼的逐步推出(rollout),並在需要時回滾至部署的較早版本。為了管理 Kubernetes 部署,管理員會使用命令列介面 kubectl 在 Linux 及其他受支援的作業系統上運作的工具。每個透過 Deployment 建立的 Pod 都與一個 ReplicaSet 相關聯。而 ReplicaSet 則會指向建立該 ReplicaSet 的 Deployment。
Kubernetes 部署的基礎知識
Kubernetes 部署(Deployments)旨在於叢集中部署及縮放容器化應用程式。部署提供了一種宣告式的方法,用以定義應用程式的目標狀態,並自動化達成及維持該狀態的過程。與 Kubernetes 部署相關的基本概念與組件包括:
Desired state. 部署(Deployment)定義了應用程式的預期狀態,例如 Pod 的複本數量、要使用的容器映像檔,以及分配給每個 Pod 的資源。Declarative configuration. 部署通常採用宣告式方法,即管理員在 JSON 或 YAML 檔案中指定系統狀態。雖然命令式方法允許管理員直接設定要執行的操作,但 Kubernetes 中的宣告式方法則讓管理員能定義所需的結果,而 Kubernetes 會透過其內部機制來實現該結果。 Kubernetes 的部署控制器會監控節點和 Pod 的健康狀態。若發生即時變更(例如 Pod 發生故障),則該 Pod 即可被替換。因此,Kubernetes 會即時監控叢集的狀態,並進行調整以符合預期狀態。ReplicaSet. 一個 Deployment 負責管理一個 ReplicaSet。ReplicaSet 會根據需要建立和刪除 Pod,以維持預期的複本數量。透過這種方式,Kubernetes 能夠確保在任何時刻,所指定的 Pod 複本皆處於運行狀態。Rolling updates. 部署支援滾動更新,讓您能在不造成服務中斷的情況下更新應用程式。Kubernetes 會逐步以新 Pod 取代舊 Pod,這有助於確保在部署更新過程中,容器化應用程式仍保持可用狀態。Rollback. 若在 Kubernetes 的更新過程中發生問題,您可以將 Deployment 還原至先前版本,使應用程式恢復至已知正常運作的狀態。
陳述式配置
在 Kubernetes 中,宣告式方法意味著您只需指定系統的預期狀態,Kubernetes 便會採取必要措施來達成並維持該狀態。 您可透過配置檔案(通常採用 YAML 或 JSON 格式)描述最終目標,而 Kubernetes 會持續運作,以確保實際狀態與預期狀態相符。
在 Kubernetes 中,通常更傾向採用宣告式方法,因為它能維持預期狀態的一致性、促進自動化,並能更好地支援協作與版本控制。命令式方法雖適用於快速、臨時性的任務,但較不適合管理複雜且長期的應用程式部署。
部署、Pod 和 ReplicaSet 如何協同運作
在 Kubernetes 中,Deployment、Pod 和 ReplicaSet 是密切相關的組件,共同負責管理應用程式的部署、縮放及生命週期。為了進行正確的配置,了解它們之間的關係,以及它們在 Kubernetes 中如何協同運作,至關重要。
- A
PodPod 是 Kubernetes 叢集中最簡單且最小的物件,代表一個正在執行的程序的單一實例。一個 Pod 可包含一個或多個容器,這些容器共用相同的儲存卷和網路命名空間。Pod 設計上具有短暫性,因為它們可根據需要進行建立與銷毀,以符合由更高階物件(如 Deployment)所指定的預期狀態。 - A
ReplicaSet確保在任何時刻都有指定數量的相同 Pod 正在運行。它透過管理 Pod 的建立與刪除,以維持所需的複本數量。每個 ReplicaSet 都會使用標籤選擇器來識別並管理其管轄範圍內的 Pod,以確保維持正確的 Pod 數量。雖然您可以直接建立和管理 ReplicaSet,但它們通常由 Deployment 來管理,因為 Deployment 提供了額外的功能性。 - A
Deployment是一種更高階的 Kubernetes 物件,用於管理 ReplicaSets 並為應用程式提供宣告式更新。如前所述,Deployments 允許管理員定義應用程式的所需狀態及其他設定。
當您建立或更新部署 (Deployment) 時,系統會自動建立一個新的複寫集 (ReplicaSet),以根據定義的規格來管理 Pod。每次更新部署時,系統都會建立一個新的複寫集來處理新版本的 Pod,而舊的複寫集則會保留,直到新 Pod 成功部署完成為止。這確保了更新能在受控的方式下進行,並維持應用程式的可用性。
Deployment 透過其 ReplicaSet 間接管理 Pod 的生命週期。透過在 Deployment 中定義目標狀態,您可以指定要執行的 Pod 的特徵與數量。隨後,Deployment 會透過管理相應的 ReplicaSet 來確保此狀態,而 ReplicaSet 則負責管理 Pod。
因此,Pod 是執行容器的執行單位,ReplicaSet 確保有足夠數量的 Pod 正在運行,而 Deployment 則透過控制 ReplicaSet,為應用程式提供宣告式管理與更新。這種階層式結構確保您的應用程式具備可擴展性、韌性及易於管理。Deployment 抽象化了直接管理 ReplicaSet 和 Pod 的複雜性,提供了一種處理應用程式更新與縮放的強大方式。
部署配置詳細資訊
在 Kubernetes 中使用 YAML 進行部署配置是一種常見的做法,原因在於其易讀性和簡潔性。Kubernetes 同時支援 YAML 和 JSON 格式的配置檔案,但由於 YAML 具有更親人的語法,因此使用更為廣泛。
YAML(YAML Ain’t Markup Language)是一種既便於人類閱讀又易於書寫的資料序列化標準。 它常被用於配置檔案,以及不同資料結構的程式語言之間的資料交換。在 Kubernetes 中,YAML 用於定義各種物件的預期狀態,包括部署 (Deployment)、服務 (Service)、Pod 等。
YAML 部署檔案的主要組成部分:
apiVersion用於指定 Kubernetes 物件的 API 版本(例如,apps/v1)。kind指定 Kubernetes 物件的類型(例如:Deployment)。metadata包含有關該物件的元資料,例如其名稱和標籤。spec(specification) 用於定義 Kubernetes 物件的預期狀態,包括:replicas指定要維持的 Pod 複本數量。selector指定如何識別由該部署所管理的 Pod。template定義 Pod 範本,其中包含 Pod 的元資料與規格。containers列出 Pod 內的容器,包括:name: 容器的名稱image: 要使用的 Docker 映像檔ports:需開放的埠號
Kubernetes 部署配置語法中,YAML 與 JSON 的差異如下:
- YAML 更易於人讀,採用縮排和鍵值對,而不使用大括號或方括號。
- JSON 採用了更為嚴格的結構,使用大括號 ({}) 和方括號 ([]),這使得在處理複雜的設定時,其可讀性較低。
在 Kubernetes 的 Deployment 中,通常會優先選用 YAML。
YAML 部署範例
以下提供了一個採用 YAML 格式的 Kubernetes 部署範例,其中包含 Pod 和容器的詳細設定。
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 3
selector:
matchLabels:
app: app-name
template:
metadata:
labels:
app: app-name
spec:
containers:
- name: container-name
image: image-name:1.0
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
env:
- name: MY_ENV_VAR
value: "some-value"
volumeMounts:
- mountPath: "/path/volume"
name: volume-name
volumes:
- name: volume-name
persistentVolumeClaim:
claimName: pvc-name
讓我們詳細說明每個區段,以便更清楚地理解。透過設定這些區段,您可以建立一個在 Kubernetes 中既穩健又具擴展性的應用程式部署,確保您的 Pod 和容器能依照您的需求進行設定。
主要設定區段
1. 元資料
metadata:
name: deployment-name
地點:
name: 部署名稱
2. Spec(部署規格)
spec:
replicas: 3
selector:
matchLabels:
app: app-name
地點:
replicas: 需維持的 Pod 複本數量
selector: 定義如何透過標籤識別由該部署所管理的 Pod:
3. Pod 範本(Pod 規格)
template:
metadata:
labels:
app: app-name
spec:
containers:
- name: container-name
image: image-name:1.0
地點:
metadata: 用於識別莢的標籤
spec: Pod 及其容器的配置
設定容器
在此部分,您可以查看用於配置容器的 Deployment 的 YAML 區段。
1. 容器映像檔
image: image-name:1.0
地點:
image: 要使用的容器映像。其中可包含標籤(例如 1.0)以指定版本。
2. 埠號。
ports:
- containerPort: 80
地點:
containerPort: 容器將用來監聽流量的端口
3. 資源請求與限制
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
地點:
requests: 所需的最低資源需求
limits: 容器可使用的最大資源
4. 環境變數
env:
- name: MY_ENV_VAR
value: "some-value"
地點:
env: 為容器定義環境變數
5. 卷掛載
volumeMounts:
- mountPath: "/path/volume"
name: volume-name
地點:
volumeMounts: 指定要在容器內掛載的卷
mountPath: 容器內用來掛載該卷的路徑
設定卷
該 卷數 此節負責設定磁區。
volumes:
- name: volume-name
persistentVolumeClaim:
claimName: pvc-name
地點:
volumes: 定義可供掛載的磁碟區
name: 卷名
persistentVolumeClaim: 指定要用於該卷的持久性卷申領 (PVC)
進階設定
1. 活躍性與就緒性探測
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
地點:
livenessProbe: 檢查容器是否仍在運行
readinessProbe: 用於檢查當前容器是否已準備好接收流量
2. 指令與參數
command: ["my-command"]
args: ["arg1", "arg2"]
地點:
command: 覆寫容器的預設入口點
args: 指定命令
的參數3. ConfigMaps 與機密
envFrom:
- configMapRef:
name: my-configmap
- secretRef:
name: my-secret
地點:
envFrom: 從 ConfigMap 或 secret 匯入環境變數
Kubernetes 部署策略
Kubernetes 有多種部署策略(類型),您可以根據當前情境選擇最有效的策略。商業應用程式對運作時間和可用性有不同的需求。選擇正確的策略,不僅能避免系統停機和服務中斷,還能有效利用資源。以下列出最常見的 Kubernetes 部署類型。
滾動更新與回滾
滾動更新部署假設會依照定義的順序,將應用程式從一個版本遷移至另一個版本(較新版本)。系統會啟動一個搭載新版本應用程式的新 ReplicaSet,並終止舊版本的副本。因此,舊版本的 Pod 將被新版本的 Pod 取代。滾動更新能讓系統從舊版本平穩過渡至新版本,但此操作需要一些時間才能完成。
重新建立部署
目前正在執行的 Pod 會先被終止,然後以新版本重新建立。這種部署策略常見於 Kubernetes 開發環境中,在這些環境中,使用者活動通常不會造成問題。當舊的部署被關閉時,會產生停機時間;此時,”重新建立”部署策略會啟動新的部署實例,並重新建立 Pod 以及應用程式的狀態。
藍綠部署
藍綠部署是 Kubernetes 中更新應用程式的另一種方式,但具有快速切換的特點。Kubernetes 藍綠部署假設同時運行兩個環境:舊版本(藍)與新版本(綠)。這兩者會以”並行”或平行方式部署。 一旦新版本經過測試並確認運作正常(符合設計需求),便會透過更新 Service Selector 來替換版本標籤。此操作針對的是在叢集中執行負載平衡的 Kubernetes Service 物件。完成後,流量將立即切換至新版本。
Kubernetes 的藍綠部署策略讓管理員能夠快速推出新版本,同時避免在不同版本之間切換時所引發的問題。 請注意,由於兩個環境會在一段時間內並行運行,因此資源利用率會較高。
Canary 部署
Kubernetes 的金絲雀部署假設僅將一小群使用者導向容器化應用程式的新版本。新版本運行於比此前一直運作的舊版本更小的 Pod 子集上。金絲雀部署的主要目的是在生產環境中測試新應用程式版本的功能性。 若新版本未出現錯誤,系統管理員便會縮放新版本的部署規模,並依照適當的順序逐步取代舊版本。
若在新版本針對小部分使用者部署後發生問題,系統管理員可將金絲雀部署回滾至舊版本。其優勢在於能夠針對小規模使用者群體測試新功能性,同時避免對整體系統運作造成負面影響的風險。
Kubernetes 重新建立部署
使用”重新建立部署”時,所有 Pod 都會被終止,並替換為新版本。當舊版與新版無法同時運行時,可採用此策略。停機時間取決於關閉舊應用程式並在容器中啟動新應用程式所需的時間。完成後,應用程式的狀態將完全更新。
縮放與管理
對 Kubernetes 部署進行縮放與管理,對於確保您的容器化應用程式能夠因應不同工作負載並維持高可用性至關重要。Kubernetes 提供了適用於手動與自動縮放的強大機制,以及用於高效管理部署的工具。
手動縮放
手動縮放是用來透過以下方式手動調整應用程式的複本(實例)數量: kubectl 命令列工具。
- 擴大規模:
kubectl scale deployment deployment-name --replicas=10此指令會將 my-deployment 的複本數量增加至 10 個。
- 縮放規模:
kubectl scale deployment deployment-name --replicas=2此指令會將 my-deployment 的副本數量減少至 2 個。
水平匣式自動擴展器 (HPA)
水平 Pod 自動擴展器 (HPA) 會根據觀察到的 CPU 使用率或其他選定的指標,自動調整 Pod 複本的數量。
- 建立 HPA 的指令如下:
kubectl autoscale deployment deployment-name --cpu-percent=50 --min=2 --max=10此指令會為HPA設定
deployment-name將 CPU 使用率維持在 50% 左右,並進行縮放,讓複本數量在 2 至 10 個之間動態調整。 - 使用 YAML 進行 HPA 設定是一種較進階的方式。以下將說明一個用於水平自動擴展的 YAML 部署設定範例。
apiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata:name: deployment-hpa-namespec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: deployment-nameminReplicas: 2maxReplicas: 10targetCPUUtilizationPercentage: 50請使用以下指令套用 YAML 設定:
ubectl apply -f hpa.yaml
垂直匣式自動擴展器 (VPA)
垂直 Pod 自動擴展器(VPA)會自動調整 Pod 的資源請求與限制,以符合實際使用情況。VPA 的 YAML 配置如下:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: deployment-vpa-name
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: deployment-name
updatePolicy:
updateMode: "Auto"
若要套用 YAML 設定,請使用以下指令:
kubectl apply -f vpa.yaml
Kubernetes 部署的最佳實踐
正確配置 Kubernetes 部署可確保建立一個能成功且可靠地執行容器化應用程式的環境。若配置不當或採用錯誤的部署管理策略,可能會導致系統停機、資料遺失等問題。遵循 Kubernetes 部署的最佳實踐,有助於確保您的應用程式具備韌性、可擴展性及可維護性。
Use declarative configuration. 請將您的 Kubernetes 設定儲存於採用版本控制的 YAML/JSON 格式檔案中。這樣一來,便能更輕鬆地管理變更,並在需要時進行回滾。請使用kubectl apply -f以套用這些設定,因為這能進行冪等操作,確保叢集的狀態與設定檔相符。Use namespace isolation. 使用命名空間來邏輯性地隔離不同的環境(例如:開發、測試、正式上線)和團隊。這有助於更有效地管理資源和權限。Resource requests and limits. 為您的 Pod 設定資源請求與限制,以確保它們擁有必要的資源,並避免資源爭用。Liveness and readiness probes. 設定存活探針以重新啟動狀態異常的容器,並設定就緒探針以控制流向容器的流量。Use labels and selectors用來整理和篩選資源。可利用標籤將資源依應用程式、環境、版本等進行分組。Use ConfigMaps and secrets. 將非敏感的配置資料儲存於 ConfigMaps 中。將敏感資料(包括密碼和 API 金鑰)儲存於 Secrets 中。Monitor and log your environment. 運用 Grafana 和 Prometheus 等工具進行監控,以檢查容器化應用程式的效能與運作狀態。使用 ELK 堆疊(Elasticsearch、Logstash、Kibana)或 Fluentd 等集中式日誌記錄解決方案來收集並分析日誌。Follow security best practices. 實作 Pod 安全政策,以在您的 Pod 上強制執行安全標準。針對 Kubernetes 部署使用網路政策,以控制 Pod 之間的流量。Prepare for backups and disaster recovery. 請定期備份您的 Kubernetes 資源與持久化資料。規劃並測試災難還原策略,以確保在發生故障時,能迅速恢復應用程式與服務。
結論
Kubernetes 部署(Deployments)在管理 Kubernetes 叢集內應用程式的生命週期方面扮演著關鍵角色。它們提供了一種宣告式的方法來定義應用程式的預期狀態,包括複本數量、容器映像檔以及配置設定。 透過編排 ReplicaSets,Deployment 可確保指定數量的 Pod 正在運行,並以受控且無縫的方式自動處理更新與回滾。這為應用程式帶來更強的可擴展性、韌性及管理便利性,使 Kubernetes Deployment 成為現代應用程式部署與運維不可或缺的工具。