在 Kubernetes 環境下,容器的無狀態特性使得資料持久化成為應用程式開發和維運的關鍵環節。尤其在 EKS 這樣的雲原生平台上,如何有效地利用 EBS 等雲端儲存服務來實作資料持久化,更需要仔細考量。本文將探討如何利用 PV 和 PVC 機制,確保資料在 Pod 重啟或刪除後仍能完整保留,並探討在微服務架構下,如何有效管理資料持久化,以提升應用程式的可靠性和可擴充套件性。常見的實務作法是將應用程式資料儲存在外部儲存服務中,例如 EBS。透過設定 PV 和 PVC,可以將 EBS 磁碟區掛載到 Pod 中,讓容器能夠存取持久化的資料。
資料永續性在EKS中的重要性
在Kubernetes中,資料永續性是至關重要的。因為每個容器及其內部的一切都會在容器被銷毀時丟失,所以儲存容器執行過程中處理的事務資料變得非常重要。本章將討論如何在AWS的EKS(Elastic Kubernetes Service)中使用EBS(Elastic Block Store)來實作資料永續性。
Kubernetes的儲存卷
與傳統的作業系統類別似,系統管理員通常會建立不同的掛載點來儲存資料。例如,在Windows中,常見的做法是使用C:來儲存作業系統資料,而使用D:來儲存其他資料。類別似地,在Linux系統中,系統管理員通常會保留根目錄(/)用於作業系統相關的檔案,並建立特定的掛載點,如/data,用於儲存事務資料。
在Kubernetes中,我們採取類別似的方法。簡而言之,我們建立一個由永續性儲存(如EBS)支援的持久性儲存區(Persistent Volume, PV),然後允許Pod透過持久性儲存區宣告(Persistent Volume Claim, PVC)來使用這些PV。
展示Pod內部資料的非永續性
假設我們在microk8s Kubernetes叢集中有一組nginx Pod,我們的目標是將這些Pod的網頁根目錄(webroot)外部化,通常網頁檔案(資料)儲存在該目錄下。預設情況下,nginx使用/usr/share/nginx/html目錄來儲存其內容檔案,我們將從容器外部掛載這個目錄,以便我們的更改是持久的。
首先,我們需要建立一個基本的nginx佈署。建立一個名為mynginx.yaml的檔案,其內容如清單15-1所示。
清單15-1:建立一個基本的nginx佈署
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment-ch15
spec:
selector:
matchLabels:
app: mynginx
template:
metadata:
labels:
app: mynginx
spec:
containers:
- ports:
- containerPort: 80
name: mynginx
image: nginx
然後,使用以下命令應用這個組態來建立佈署:
microk8s kubectl apply -f mynginx.yaml
輸出結果如下:
shiva@wks01:~$ microk8s kubectl apply -f mynginx.yaml
deployment.apps/mydeployment-ch15 created
shiva@wks01:~$
內容解密:
apiVersion和kind定義了Kubernetes資源的型別和版本。metadata包含佈署的名稱。spec定義了佈署的規格,包括選擇器、範本和容器規格。selector和template中的labels必須匹配,以便佈署管理正確的Pod。containers部分定義了容器使用的映像和埠。
建立佈署後,我們可以使用myservice01.yaml檔案來暴露網頁服務,如清單15-2所示。
清單15-2:服務佈署檔案的內容
apiVersion: v1
kind: Service
metadata:
name: "myservice"
spec:
ports:
- port: 80
targetPort: 80
type: LoadBalancer
selector:
app: "mynginx"
輸入清單15-2中的內容,將檔案命名為myservice01.yaml,然後使用清單15-3中所示的命令來應用它。
清單15-3:應用和確認服務佈署
microk8s kubectl apply -f myservice01.yaml
microk8s kubectl get service
輸出結果如下:
shiva@wks01:~$ microk8s kubectl apply -f myservice01.yaml
service/myservice configured
shiva@wks01:~$
shiva@wks01:~$ microk8s kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 5h23m
dep-webserver LoadBalancer 10.152.183.146 <pending> 80:32151/TCP 5h18m
myservice LoadBalancer 10.152.183.142 <pending> 80:30439/TCP 5h13m
shiva@wks01:~$
內容解密:
apiVersion和kind定義了服務資源。metadata包含服務的名稱。spec定義了服務的規格,包括埠、型別和選擇器。type: LoadBalancer表示服務將透過負載平衡器暴露給外部。selector用於選擇提供服務的Pod。
如前所述,埠30439是服務埠;因此,我們可以使用埠30439來存取網頁服務,如清單15-4所示。
資料永續性的實作
為了實作資料永續性,我們需要建立一個持久性儲存區(PV)並將其掛載到Pod中。這樣,即使Pod被銷毀,儲存在PV中的資料也將被保留。
步驟1:建立持久性儲存區(PV)
建立一個名為mypv.yaml的檔案,其內容如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- wks01
內容解密:
apiVersion和kind定義了PV資源。metadata包含PV的名稱。spec定義了PV的規格,包括容量、存取模式和回收策略。local部分定義了PV使用的本地儲存路徑。nodeAffinity用於指定PV所在的節點。
使用以下命令建立PV:
microk8s kubectl apply -f mypv.yaml
步驟2:建立持久性儲存區宣告(PVC)
建立一個名為mypvc.yaml的檔案,其內容如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
內容解密:
apiVersion和kind定義了PVC資源。metadata包含PVC的名稱。spec定義了PVC的規格,包括存取模式和資源請求。
使用以下命令建立PVC:
microk8s kubectl apply -f mypvc.yaml
步驟3:在Pod中使用PVC
修改mynginx.yaml檔案,將PVC掛載到Pod中:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment-ch15
spec:
selector:
matchLabels:
app: mynginx
template:
metadata:
labels:
app: mynginx
spec:
containers:
- ports:
- containerPort: 80
name: mynginx
image: nginx
volumeMounts:
- name: nginx-persistent-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-persistent-storage
persistentVolumeClaim:
claimName: mypvc
內容解密:
volumeMounts部分定義了容器內的掛載點。volumes部分定義了使用的PVC。
使用以下命令更新佈署:
microk8s kubectl apply -f mynginx.yaml
透過以上步驟,我們實作了在EKS中使用EBS進行資料永續性。即使Pod被銷毀,儲存在PV中的資料也將被保留,從而確保了資料的安全性和永續性。
在微服務架構中使用 Kubernetes 實作資料持久化
在現代的雲原生應用程式中,資料持久化是一個至關重要的議題。隨著微服務架構的普及,如何確保資料在容器重啟或刪除後仍然能夠持久儲存,成為了開發者和維運團隊必須面對的挑戰。本文將探討在 Kubernetes 環境中實作資料持久化的方法和最佳實踐。
驗證 Web 伺服器連線
首先,我們需要驗證 Web 伺服器是否能夠正常運作。透過使用 curl 命令,我們可以確認 Web 伺服器是否能夠正確回應請求。
curl -L localhost:30439
內容解密:
此命令使用 curl 工具對本地主機的 30439 連線埠發起 HTTP 請求,-L 引數表示跟隨重定向。預期結果是傳回 Web 伺服器的首頁內容。
執行結果:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
</head>
<body>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
這表明我們的 Web 伺服器正在正常運作,並且能夠正確提供網頁內容。
編輯容器內的 index.html 檔案
接下來,我們將登入到正在執行 Web 伺服器的 Pod 內部,並修改 index.html 檔案的內容。
microk8s kubectl exec -i -t mydeployment-ch15-74d9d4bc84-cx22h -- /bin/bash
內容解密:
此命令使用 kubectl exec 登入到指定的 Pod 內部,並啟動一個互動式的 Bash 終端。-i 和 -t 引數分別表示保持 STDIN 開啟和分配一個虛擬終端。
進入容器後,我們可以使用以下命令修改 index.html 的內容:
echo -e "<html>\n<title>\nnew title\n</title>\n<body>\nnew content\n</body>\n</html>" > /usr/share/nginx/html/index.html
內容解密:
此命令使用 echo 將新的 HTML 內容寫入到 /usr/share/nginx/html/index.html 檔案中,覆寫原有的內容。
驗證修改結果
離開容器後,再次使用 curl 命令存取 Web 伺服器:
curl -L localhost:30439
內容解密:
此時應該看到新的 HTML 內容,表明我們的修改已經生效。
執行結果:
<html>
<title>
new title
</title>
<body>
new content
</body>
</html>
刪除 Pod 後的結果
現在,我們將刪除目前的 Pod,並觀察新的 Pod 是否能夠保留我們之前的修改。
microk8s kubectl delete pod mydeployment-ch15-74d9d4bc84-cx22h
內容解密:
此命令刪除指定的 Pod。由於我們使用的是 Deployment,Kubernetes 將自動建立一個新的 Pod。
新的 Pod 建立後,再次使用 curl 命令存取 Web 伺服器:
curl -L localhost:30439
內容解密:
此時,我們會發現網頁內容已經還原到初始狀態,這是因為我們的修改沒有被持久化儲存。
執行結果:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
</head>
<body>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
使用 Persistent Volume 實作資料持久化
為了實作資料持久化,我們需要使用 Kubernetes 的 Persistent Volume(PV)功能。
建立 Persistent Volume
首先,我們需要建立一個 PV。以下是 pv.yaml 的範例內容:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginxdata
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 2Gi
hostPath:
path: /nginxdata
storageClassName: webcontent
內容解密:
此 YAML 檔案定義了一個名為 nginxdata 的 PV,大小為 2GB,儲存於主機的 /nginxdata 目錄下。accessModes 指定了存取模式為 ReadWriteOnce,表示該 PV 可以被單個節點以讀寫模式掛載。
使用以下命令建立 PV:
microk8s kubectl apply -f pv.yaml
隨著雲原生技術的不斷發展,資料持久化的解決方案也在不斷進步。未來,我們可以期待看到更多根據 Kubernetes 的創新儲存解決方案,以滿足日益增長的資料儲存需求。
Kubernetes 資料持久化架構圖
graph LR
A[Kubernetes Cluster] --> B[Pod]
B --> C[Container]
C --> D[Ephemeral Storage]
A --> E[Persistent Volume]
E --> F[Persistent Volume Claim]
F --> G[Storage Class]
E --> H[Data Persistence]
圖表翻譯: 此圖示展示了 Kubernetes 中的資料持久化架構。Pod 中的容器使用暫時性儲存,而 Persistent Volume(PV)提供了持久化的資料儲存能力。Persistent Volume Claim(PVC)用於請求 PV 資源,而 Storage Class 則定義了儲存資源的型別和特性。最終,資料得以持久化儲存。