在 Kubernetes 環境中,應用程式的高用性和穩定性至關重要。ReadinessProbe 和 LivenessProbe 是確保 Pod 健康狀態的關鍵機制。ReadinessProbe 用於判斷 Pod 是否已準備好接收流量,而 LivenessProbe 則用於檢測 Pod 是否正常執行。這兩種探針都支援命令執行、HTTP 請求和 TCP 連線三種檢查方式,可以根據應用程式的特性選擇合適的方式。此外,持久儲存對於有狀態應用程式尤為重要。Kubernetes 提供了多種持久儲存方案,例如 ConfigMap 和 Secret,可以將組態檔案和敏感資訊與容器分離,提高應用程式的可移植性和安全性。ConfigMap 可以將組態檔案掛載到 Pod 中,方便應用程式讀取組態資訊,同時也方便了組態的更新和管理。
使用 Services 暴露 Pod
在 Kubernetes 中,確保應用程式的可用性和健康狀況非常重要。為了實作這一點,Kubernetes 提供了兩種探針(Probe):ReadinessProbe 和 LivenessProbe。本篇文章將詳細介紹這兩種探針的作用、組態方法以及它們在實際應用中的重要性。
ReadinessProbe:確保 Pod 準備就緒
ReadinessProbe 用於檢查 Pod 是否已經準備好接收流量。它可以透過三種方式進行檢查:
- 命令(Command):在 Pod 內執行一個命令,如果命令的離開碼為 0,則表示 Pod 已經準備就緒。
- HTTP 請求(HTTP):向 Pod 傳送一個 HTTP 請求,如果傳回的 HTTP 狀態碼在 200 到 400 之間,則表示 Pod 已經準備就緒。
- TCP 連線(TCP):嘗試與 Pod 建立 TCP 連線,如果連線成功,則表示 Pod 已經準備就緒。
以下是一個使用 HTTP ReadinessProbe 的範例 YAML 組態檔案:
# nginx-pod-with-readiness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-readiness-http
spec:
containers:
- name: nginx-pod-with-readiness-http
image: nginx
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 5
httpGet:
path: /ready
port: 80
內容解密:
initialDelaySeconds:探針在開始第一次健康檢查之前等待的秒數。periodSeconds:探針執行兩次健康檢查之間的間隔秒數。httpGet:定義 HTTP 請求的路徑和埠。
ReadinessProbe 的作用是確保 Pod 在完全準備就緒之前不會接收到流量。例如,可以呼叫一個內部開啟 MySQL 連線的頁面,以確保應用程式能夠與其資料函式庫進行通訊。
LivenessProbe:確保 Pod 健康執行
LivenessProbe 用於檢查 Pod 是否處於健康狀態。它與 ReadinessProbe 類別似,也可以透過命令、HTTP 請求和 TCP 連線等方式進行檢查。
LivenessProbe 的主要目的是檢測 Pod 是否已經損壞或進入了不可還原的狀態。如果 LivenessProbe 檢測到 Pod 不健康,Kubernetes 將會終止該 Pod。
以下是 LivenessProbe 的幾種檢查方式:
- 命令(Command):在容器內執行一個命令,如果命令的離開碼不為 0,則表示 Pod 不健康。
- HTTP 請求(HTTP):向 Pod 傳送一個 HTTP 請求,如果傳回的 HTTP 狀態碼不在 200 到 400 之間,則表示 Pod 不健康。
- TCP 連線(TCP):嘗試與 Pod 建立 TCP 連線,如果連線失敗,則表示 Pod 不健康。
- GRPC:如果應用程式支援並實作了 gRPC 健康檢查協定,則可以使用 GRPC 進行檢查。
以下是一個使用 HTTP LivenessProbe 的範例 YAML 組態檔案:
# nginx-pod-with-liveness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-liveness-http
spec:
containers:
- name: nginx-pod-with-liveness-http
image: nginx
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
httpGet:
path: /healthcheck
port: 80
內容解密:
initialDelaySeconds和periodSeconds的作用與 ReadinessProbe 中的相同。httpGet定義了用於檢查 Pod 健康狀態的 HTTP 請求路徑和埠。
為什麼需要 ReadinessProbe 和 LivenessProbe?
ReadinessProbe 和 LivenessProbe 是 Kubernetes 中非常重要的功能,它們可以幫助您確保應用程式的可用性和健康狀況。
- ReadinessProbe 確保了 Pod 在完全準備就緒之前不會接收到流量,從而避免了因為應用程式尚未就緒而導致的錯誤。
- LivenessProbe 可以檢測出已經損壞或不可還原的 Pod,並由 Kubernetes 終止它們,從而保持叢集的整體健康狀態。
透過合理地組態和使用 ReadinessProbe 和 LivenessProbe,您可以提高應用程式的可靠性和可用性,為使用者提供更好的體驗。
使用LivenessProbe確保Pod健康檢查
在Kubernetes中,LivenessProbe是一種重要的機制,用於檢查Pod的健康狀態。透過定期執行健康檢查,Kubernetes能夠自動檢測並重啟不健康的Pod,從而提高應用的可用性和可靠性。
HTTP LivenessProbe
HTTP LivenessProbe透過對指定的URL路徑發起HTTP請求來檢查Pod的健康狀態。以下是一個範例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-liveness-http
spec:
containers:
- name: nginx-pod-with-liveness-http
image: nginx
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
httpGet:
path: /healthcheck
port: 80
httpHeaders:
- name: My-Custom-Header
value: My-Custom-Header-Value
內容解密:
initialDelaySeconds: 5表示在容器啟動後5秒才開始進行第一次健康檢查。periodSeconds: 5表示每隔5秒執行一次健康檢查。httpGet指定了要對/healthcheck路徑發起HTTP GET請求,連線埠為80。httpHeaders可以新增自定義的HTTP標頭,這裡增加了一個名為My-Custom-Header的標頭。
Command LivenessProbe
Command LivenessProbe透過執行指定的命令來檢查Pod的健康狀態。如果命令執行成功(傳回碼為0),則認為Pod是健康的。以下是一個範例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-liveness-command
spec:
containers:
- name: nginx-pod-with-liveness-command
image: nginx
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
exec:
command:
- cat
- /hello/world
內容解密:
exec指定了要執行的命令,這裡是cat /hello/world。- 如果
/hello/world檔案存在且cat命令成功執行,則健康檢查透過。 - 如果檔案不存在或命令執行失敗,則健康檢查失敗,Pod將被視為不健康。
TCP LivenessProbe
TCP LivenessProbe透過嘗試連線指定的TCP連線埠來檢查Pod的健康狀態。如果連線成功,則認為Pod是健康的。以下是一個範例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-liveness-tcp
spec:
containers:
- name: nginx-pod-with-liveness-tcp
image: nginx
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
tcpSocket:
port: 80
內容解密:
tcpSocket指定了要連線的TCP連線埠,這裡是80。- 如果連線埠80的連線成功,則健康檢查透過。
使用命名連線埠的LivenessProbe
在HTTP和TCP LivenessProbe中,可以使用命名連線埠。以下是一個範例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-liveness-http-named-port
spec:
containers:
- name: nginx-pod-with-liveness-http-named-port
image: nginx
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
httpGet:
path: /healthcheck
port: liveness-port
內容解密:
- 在
ports部分定義了一個名為liveness-port的連線埠,對映到容器的8080連線埠。 - 在
livenessProbe中,使用liveness-port作為連線埠名稱。
使用StartupProbe
對於啟動時間較長的應用,可以使用StartupProbe來延遲LivenessProbe的啟動時間。StartupProbe與LivenessProbe類別似,但具有更長的容忍失敗次數和檢查間隔。以下是一個範例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-with-startupprobe
spec:
containers:
- name: nginx-pod-with-startupprobe
image: nginx
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 5
httpGet:
path: /healthcheck
port: liveness-port
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
內容解密:
startupProbe定義了一個啟動探針,使用HTTP GET請求檢查/healthz路徑。failureThreshold和periodSeconds定義了在認為啟動失敗之前的最大嘗試次數和檢查間隔。
同時使用ReadinessProbe和LivenessProbe
在同一個Pod中,可以同時使用ReadinessProbe和LivenessProbe。它們具有相似的組態引數,但服務於不同的目的。以下是一些共同的引數:
initialDelaySeconds: 第一次探測執行的延遲時間。periodSeconds: 探測之間的間隔時間。timeoutSeconds: 等待探測超時的時間。successThreshold: 認為Pod就緒(對於ReadinessProbe)或健康(對於LivenessProbe)的成功次數門檻。failureThreshold: 認為Pod未就緒(對於ReadinessProbe)或需要被終止(對於LivenessProbe)的失敗次數門檻。
第9章:Kubernetes 中的持久儲存
在前面的章節中,我們已經瞭解了 Kubernetes 的關鍵概念,本章將是最後一個關於這些概念的章節。到目前為止,我們已經發現 Kubernetes 是透過在 etcd 資料儲存中建立物件來表示所有傳統 IT 層的期望狀態,這些物件將被轉換為叢集內的實際運算資源。
本章將重點關注有狀態應用的持久儲存。與其他資源抽象一樣,這將是另一組我們需要掌握的物件,以在叢集中獲得持久儲存。Kubernetes 中的持久儲存是透過使用 PersistentVolume 資源型別實作的,它有自己的機制。老實說,這些機制最初可能相對難以理解,但我們將探討並全面介紹它們!
在本章中,我們將涵蓋以下主要主題:
- 為什麼使用持久儲存?
- 瞭解如何將 PersistentVolume 掛載到 Pod
- 瞭解 Kubernetes 中 PersistentVolume 物件的生命週期
- 瞭解靜態和動態 PersistentVolume 組態
- 高階儲存主題
技術需求
- 一個可用的 Kubernetes 叢集(本地或根據雲)
- 一個可用的 kubectl CLI,組態為與叢集通訊
如果您不滿足這些技術需求,可以參考第 2 章《Kubernetes 架構 - 從容器映像到執行中的 Pod》和第 3 章《安裝您的 Kubernetes 叢集》,以取得這兩個先決條件。
為什麼使用持久儲存?
儲存是 IT 世界中的重要資源,因為它提供了一種邏輯方式來建立、讀取、更新和刪除(CRUD)資訊,從員工薪資單的 PDF 檔案到海量的醫療保健記錄。雖然儲存是向使用者提供相關資訊的關鍵元素,但容器和微服務應該是無狀態的。換句話說,當容器被重新排程或移動到不同的叢集時,其中儲存的任何資訊都將不可用。微服務也是如此;資料元件應該被解耦,使微服務保持微小的狀態,並且在被重新排程時不必關心資料的狀態和可用性。
那麼,我們應該在哪裡儲存應用程式資料呢?在任何型別的資料儲存中,從業務連續性的角度來看,如果相關的資料儲存與微服務執行在相同的 Kubernetes 叢集中,則應該具有應用程式感知的複製機制。但請記住,Kubernetes 是一個資源協調器,它將根據您為應用程式定義的期望狀態採取行動。在組態 Pod 時,您有機會定義要使用的儲存元件,為容器提供建立、讀取、更新和刪除資料的方式。讓我們來探討一下 Kubernetes 為持久化資料提供的不同選項。
介紹 Volume
第一層儲存抽象是存取 Kubernetes 物件並將其掛載到容器中,如資料卷。這可以透過以下方式實作:
- ConfigMap
- Secret
- ServiceAccount token(與 Secret 相同)
這允許應用程式團隊將微服務的組態與容器或佈署定義解耦。如果我們考慮應用程式的生命週期,憑證、憑證或外部服務的 token 可能需要重新整理,或者組態引數可能需要更新。出於明顯的安全原因,我們不希望這些被硬編碼在佈署清單或容器映像中。
讓我們來看一個 ConfigMap 的範例,使用的清單檔案是 nginx-configmap.yaml:
# nginx-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-hello
labels:
app: test
immutable: false
data:
hello1.html: |
<html>
hello world 1
</html>
hello2.html: |
<html>
hello world 2
</html>
這個 ConfigMap 有兩個定義,分別對應兩個不同的檔案,我們將把它們掛載到 NGINX Pod 中,使用的清單檔案是 nginx-pod.yaml:
# nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-hello
labels:
app: test
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: nginx-hello
mountPath: "/usr/share/nginx/html/hello"
volumes:
- name: nginx-hello
configMap:
name: nginx-hello
程式碼解析:
這個範例展示瞭如何使用 ConfigMap 將檔案掛載到 NGINX Pod 中。首先,我們建立了一個名為 nginx-hello 的 ConfigMap,其中包含了兩個 HTML 檔案的定義。然後,我們建立了一個 NGINX Pod,並將 ConfigMap 掛載到 /usr/share/nginx/html/hello 目錄下。
$ kubectl apply -f nginx-configmap.yaml
configmap/nginx-hello created
$ kubectl apply -f nginx-pod.yaml
pod/nginx-hello created
讓我們驗證一下兩個物件的狀態:
$ kubectl get pod,cm
NAME READY STATUS RESTARTS AGE
pod/nginx-hello 1/1 Running 0 7m26s
詳細解析:
- 建立 ConfigMap:使用
nginx-configmap.yaml清單檔案建立了一個名為nginx-hello的 ConfigMap。 - 建立 Pod:使用
nginx-pod.yaml清單檔案建立了一個名為nginx-hello的 NGINX Pod。 - 掛載 ConfigMap:Pod 中的 NGINX 容器將 ConfigMap 中的檔案掛載到
/usr/share/nginx/html/hello目錄下。 - 驗證狀態:使用
kubectl get命令驗證了 Pod 和 ConfigMap 的狀態。
這個範例展示瞭如何使用 ConfigMap 將檔案掛載到容器中,實作了組態與容器的解耦。