ReplicaSet 作為 Kubernetes 重要的控制器元件,負責維持 Pod 複本數量,是確保應用程式高用性和容錯性的關鍵。本文詳細介紹了 ReplicaSet 的核心元件,包含 replicas、selector 和 template,並說明如何透過 YAML 檔案定義和佈署 ReplicaSet。同時,文章也涵蓋了 ReplicaSet 的運作機制,例如如何使用標籤選擇器管理 Pod,以及如何處理裸 Pod 的情況。此外,更進一步探討了 ReplicaSet 在實際應用中的高用性和容錯性測試,包含模擬節點移除和 Pod 刪除等場景,驗證 ReplicaSet 的自動修復和擴充套件能力。最後,文章也示範瞭如何結合活性探針監控 Pod 健康狀態,提升應用程式在 Kubernetes 叢集中的穩定性和可靠性。
Kubernetes ReplicaSet 詳細解析與實務操作
Kubernetes 中的 ReplicaSet(RS)是一種用於確保指定數量的 Pod 複本始終執行的控制器。本章將探討 ReplicaSet 的規格、運作機制以及實際操作範例。
ReplicaSet 的主要元件
ReplicaSet 的規格包含三個主要部分:
- replicas:定義應執行的 Pod 複本數量。Kubernetes 會根據此數值建立或刪除 Pod 以維持所需的數量。
- selector:標籤選擇器,用於識別 ReplicaSet 所擁有的或取得的 Pod。需要注意的是,如果現有的裸 Pod(未被 ReplicaSet 管理的 Pod)匹配選擇器,它們可能會被 ReplicaSet 接管。
- template:定義用於建立 Pod 的範本。範本中的標籤必須與選擇器的標籤查詢相匹配。
ReplicaSet 的運作機制
下圖展示了 ReplicaSet 的運作機制:
此圖示說明瞭 ReplicaSet 如何使用 .spec.template 建立 Pod,以及這些 Pod 如何與 .spec.selector 中組態的標籤選擇器相匹配。同時,也說明瞭 ReplicaSet 可以取得現有的匹配標籤的裸 Pod。
建立 ReplicaSet
以下是一個簡單的 ReplicaSet 清單檔案範例(nginx-replicaset-example.yaml):
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset-example
namespace: rs-ns
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17
ports:
- containerPort: 80
內容解密:
apiVersion和kind定義了 Kubernetes 資源的版本和型別。metadata包含了 ReplicaSet 的名稱和名稱空間。spec.replicas指定了所需的 Pod 複本數量。spec.selector.matchLabels定義了用於匹配 Pod 的標籤選擇器。spec.template定義了用於建立 Pod 的範本,包括容器的映像檔和埠組態。
使用 kubectl apply 命令將 ReplicaSet 清單檔案套用到叢集:
$ kubectl apply -f nginx-replicaset-example.yaml
replicaset.apps/nginx-replicaset-example created
檢查 ReplicaSet 的狀態:
$ kubectl describe replicaset/nginx-replicaset-example -n rs-ns
...
Replicas: 4 current / 4 desired
Pods Status: 4 Running / 0 Waiting / 0 Succeeded / 0 Failed
...
使用進階標籤選擇器
ReplicaSet 也支援根據集合的標籤選擇器(set-based selector),可以透過 spec.selector.matchExpressions 定義。例如:
spec:
replicas: 4
selector:
matchLabels:
app: nginx
matchExpressions:
- key: environment
operator: In
values:
- test
- dev
內容解密:
matchExpressions定義了一個根據集合的標籤選擇器。key指定了標籤的鍵。operator指定了匹配運算子,此處為In,表示值必須在指定的列表中。values指定了匹配的值列表。
測試 ReplicaSet 的行為
刪除一個由 ReplicaSet 管理的 Pod:
$ kubectl delete po nginx-replicaset-example-6qc9p -n rs-ns
觀察 Pod 的狀態變化:
$ kubectl get pods -n rs-ns
ReplicaSet 會立即建立一個新的 Pod 以維持所需的複本數量。
建立裸 Pod 並觀察 ReplicaSet 的反應
建立一個匹配 ReplicaSet 標籤選擇器的裸 Pod:
# nginx-pod-bare.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-bare-example
namespace: rs-ns
labels:
app: nginx
environment: test
spec:
containers:
- name: nginx
image: nginx:1.17
ports:
- containerPort: 80
套用清單檔案:
$ kubectl apply -f nginx-pod-bare.yaml
pod/nginx-pod-bare-example created
檢查 ReplicaSet 的事件:
$ kubectl describe rs/nginx-replicaset-example
...
Events:
Type Reason Age From Message
---
-
---
---
---
-
---
-
---
-
---
...
Normal SuccessfulDelete 29s replicaset-controller Deleted pod: nginx-pod-bare-example
ReplicaSet 立即檢測到新的匹配 Pod 並終止它,以維持所需的複本數量。
使用ReplicaSet進行高用性與容錯測試
在前面的章節中,我們已經瞭解了ReplicaSet的基本概念。現在,我們將進一步探討如何利用ReplicaSet來實作應用程式的高用性(HA)和容錯性(FT)。
測試高用性與容錯性
為了示範這個場景,我們將使用之前佈署的ReplicaSet nginx-replicaset-example。首先,我們需要建立一個Service來暴露這個應用程式。
$ kubectl apply -f nginx-service.yaml
service/nginx-service created
接下來,我們將Service轉發到本地埠以便於測試:
$ kubectl port-forward svc/nginx-service 8080:80 -n rs-ns
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
開啟另一個終端,驗證應用程式的可存取性:
$ curl localhost:8080
你應該會看到預設的NGINX頁面輸出。
移除節點測試
在之前的測試中,我們已經驗證了刪除Pod後ReplicaSet會根據副本數量重新建立Pod。現在,我們將移除一個Kubernetes節點,觀察ReplicaSet的行為。首先,檢查目前Pod的分佈情況:
$ kubectl get po -n rs-ns -o wide
輸出結果顯示Pod分佈在不同的節點上。接下來,我們將kind-worker節點標記為不可排程,然後將其移除:
$ kubectl cordon kind-worker
node/kind-worker cordoned
$ kubectl drain kind-worker --ignore-daemonsets
...<removed for brevity>...
pod/nginx-replicaset-example-kw7cl evicted
node/kind-worker drained
$ kubectl delete node kind-worker
node "kind-worker" deleted
檢查Pod的新分佈情況:
$ kubectl get po -n rs-ns -o wide
輸出結果顯示ReplicaSet已經在可用的節點上建立了所需的Pod數量。
擴充套件ReplicaSet
與ReplicationController類別似,我們可以對ReplicaSet進行擴充套件操作。通常,這種操作會由更高層級的物件(如Deployment)來管理。
擴充套件ReplicaSet範例
首先,修改nginx-replicaset.yaml檔案,將replicas屬性設定為5:
spec:
replicas: 5
然後,使用kubectl apply命令應用更改:
$ kubectl apply -f ./nginx-replicaset.yaml
使用kubectl get pods或kubectl describe rs/nginx-replicaset-example命令驗證Pod數量是否已更改。
縮減ReplicaSet
同樣地,如果需要縮減ReplicaSet,可以修改nginx-replicaset.yaml檔案,將replicas屬性設定為2,然後再次應用更改。
結合Pod活性探針使用ReplicaSet
有時,即使容器中的主要程式沒有當機,我們仍可能希望將Pod視為不健康,並要求重啟容器。透過結合使用活性探針和ReplicaSet,可以實作對容器化元件故障的更高彈性。
示範活性探針的使用
我們將建立一個ReplicaSet物件,執行帶有額外活性探針的nginx Pod。該探針檢查HTTP GET請求到路徑 / 是否傳回成功的HTTP狀態碼。如果nginx程式執行但無法成功提供內容,則認為Pod不健康,應該被替換。
內容解密:
- 活性探針的作用:活性探針用於檢測容器內的主要程式是否健康。如果探針檢測失敗,Kubernetes會重啟容器。
- ReplicaSet與活性探針的結合:透過結合使用ReplicaSet和活性探針,可以確保在Pod不健康時,ReplicaSet能夠建立新的Pod來替換它,從而提高應用程式的可用性。
- 示範中的關鍵步驟:建立帶有活性探針的ReplicaSet物件,模擬nginx Pod變得不健康的情況(例如刪除
/index.html檔案),觀察ReplicaSet如何回應並建立新的Pod。
在 Kubernetes 中執行生產級工作負載:ReplicaSet 深入解析
Kubernetes 為現代應用程式提供了高用性(HA)和容錯能力(FT),而 ReplicaSet 是實作這些特性的關鍵構件之一。本章將探討 ReplicaSet 的使用、組態及其在生產環境中的實踐。
建立帶有活性探針的 ReplicaSet
首先,我們建立一個名為 nginx-replicaset-livenessprobe.yaml 的 YAML 清單檔案,定義了一個帶有活性探針的 ReplicaSet 物件。
# nginx-replicaset-livenessprobe.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset-livenessprobe-example
spec:
replicas: 3
selector:
matchLabels:
app: nginx
environment: test
template:
metadata:
labels:
app: nginx
environment: test
spec:
containers:
- name: nginx
image: nginx:1.17
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 2
內容解密:
livenessProbe部分定義了活性探針,用於檢測容器內部的 Nginx 伺服器是否健康。httpGet指定了探針傳送 HTTP GET 請求到容器的/路徑,埠為 80。initialDelaySeconds: 2表示容器啟動後 2 秒開始第一次探測。periodSeconds: 2表示每 2 秒執行一次探測。
接著,使用以下命令將此清單檔案應用到 Kubernetes 叢集:
$ kubectl apply -f ./nginx-replicaset-livenessprobe.yaml
驗證 Pod 是否成功啟動:
$ kubectl get pods
模擬容器內部故障
選擇一個 ReplicaSet Pod 來模擬內部故障,例如刪除 index.html 檔案,使活性探針失敗:
$ kubectl exec -it nginx-replicaset-livenessprobe-example-lgvqv -- rm /usr/share/nginx/html/index.html
檢查該 Pod 的事件日誌:
$ kubectl describe pod/nginx-replicaset-livenessprobe-example-lgvqv
從事件日誌中可以看到,活性探針檢測到容器不健康後,Kubernetes 自動重啟了容器。
ReplicaSet 的刪除
刪除 ReplicaSet 物件有兩種方式:
- 刪除 ReplicaSet 物件及其管理的 Pod:
$ kubectl delete rs/nginx-replicaset-livenessprobe-example - 僅刪除 ReplicaSet 物件,保留其管理的 Pod:
$ kubectl delete rs/nginx-replicaset-livenessprobe-example --cascade=orphan
進一步閱讀
- ReplicaSet:https://kubernetes.io/docs/concepts/workloads/controllers/replicaset
- ReplicationController:https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller