經過Rancher Kubernetes Engine運行高可用 PostgreSQL
node
這篇是咱們關於在Kubernetes上運行PostgreSQL系列文章的其中一篇。下面是相關文章和連接。ios
Rancher Kubernetes Engine (RKE)是一個輕量級的Kubernetes 安裝程序,支持在裸金屬和虛擬機上安裝Kubernetes。RKE解決了Kubernetes安裝的複雜性問題。經過RKE安裝是比較簡單的,而跟下層的操做系統無關。git
Portworx是一個雲原生的存儲和數據管理平臺,來支撐Kubernetes上持久性的工做負載。經過Portworx,用戶可以管理不一樣基礎架構上的、不一樣容器調度器上的數據庫。它爲全部的有狀態服務(Stateful Service)提供了一個單一的數據管理層。github
本文列出了操做步驟:經過RancherKubernetes Engine (RKE),在AWS的Kubernetes集羣上,部署和管理高可用PostgreSQL集羣。sql
總結來講,在Amazon上運行高可用PostgreSQL,須要:shell
如何經過RKE來建立一個Kubernetes集羣數據庫
RKE是一個安裝和配置Kubernetes的工具。能夠支持的環境包括裸金屬,虛擬機或者IaaS。在本文中,咱們會在AWS EC2上建立一個3節點的Kubernetes集羣。json
更爲詳細的步驟,能夠參考這篇tutorial from The New Stack. (https://thenewstack.io/run-stateful-containerized-workloads-with-rancher-kubernetes-engine-and-portworx/)bash
作完這些操做,咱們會建立一個1 master 和 3 worker 節點的集羣。
架構
在Kubernetes上安裝Portworx
在RKE的Kubernetes 上安裝Portworx,跟在Kubernetes集羣上經過Kops安裝沒什麼不一樣。Portworx有詳細的文檔,列出每步的操做 (https://docs.portworx.com/portworx-install-with-kubernetes/cloud/aws/),來完成在AWS環境的Kubernetes上運行Portworx集羣。
The New Stacktutorial(https://thenewstack.io/run-stateful-containerized-workloads-with-rancher-kubernetes-engine-and-portworx/) 也包含了在Kubernetes部署Portworx DaemonSet的全部操做步驟。
Kubernetes集羣運行起來,Portworx安裝和配置完成,咱們就開始部署一個高可用的PostgreSQL數據庫。
建立一個Postgres 存儲類
經過存儲類對象,一個Admin能夠定義集羣中不一樣的Portworx卷的類。這些類在動態的卷的部署過程當中會被用到。存儲類自己定義了複製因子,IO狀況(例如數據庫或者CMS),以及優先級(好比SSD或者HDD)。這些參數影響着工做負載的可用性和輸出,所以參數能夠被根據每一個卷分別設置。這很重要,由於對生產系統的數據庫的要求,跟研發測試系統是徹底不同的。
在下面的例子裏,咱們部署的存儲類,它的複製因子是3,IO狀況設定成「db」,優先級設定成「high」。這意味着存儲會被優化爲適合低傳輸速率的數據庫負載(Postgres),而且自動的部署在集羣具有最高性能的存儲裏。
$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-repl3-sc.yaml storageclass "px-repl3-sc" created
建立一個Postgres PVC
咱們如今能夠基於存儲類建立一個PersistentVolume Claim (PVC)。動態部署的優點就在於,claims可以在不須要顯性部署持久卷Persistent Volume (PV)的狀況下被建立。
$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-postgres-pvc.yaml persistentvolumeclaim "px-postgres-pvc" created
PostgreSQL的密碼會被建立成Secret。運行下面的命令來用正確的格式建立Secret。
$ echo postgres123 > password.txt $ tr -d '\n' .strippedpassword.txt && mv .strippedpassword.txt password.txt $ kubectl create secret generic postgres-pass --from-file=password.txt secret "postgres-pass" created
在Kubernetes上部署PostgreSQL
最後,讓咱們建立一個PostgreSQL實例,做爲一個Kubernetes部署對象。爲了簡單起見,咱們只部署一個單獨的Postgres Pod。由於Portworx提供同步複製來達到高可用。所以一個單獨的Postgres實例,是Postgres數據庫的最佳部署方式。Portworx也支持多節點的Postgres部署方式,看你的須要。
$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/postgres-app.yaml deployment "postgres" created
確保Postgres的Pods是在運行的狀態。
$ kubectl get pods -l app=postgres -o wide --watch
等候直到Postgres pod變成運行狀態。
咱們能夠經過使用與PostgresPod一塊兒運行的pxctl工具,來檢查Portworx卷。
$ VOL=`kubectl get pvc | grep px-postgres-pvc | awk '{print $3}'` $ PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}') $ kubectl exec -it $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume inspect ${VOL}
命令的輸出信息,確認了支撐PostgreSQL數據庫實例的卷已經被建立完成了。
PostgreSQL的錯誤恢復
讓咱們爲數據庫填充5百萬行的樣例數據。
咱們首先找到運行PostgreSQL的Pod,來訪問shell。
$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'` $ kubectl exec -it $POD bash
如今咱們進入了Pod,咱們可以鏈接到Postgres而且建立數據庫。
# psql pgbench=# create database pxdemo; pgbench=# \l pgbench=# \q
默認狀態下,Pgbench會建立4張表:(pgbench_branches,pgbench_tellers,pgbench_accounts,pgbench_history),在主pgbench_accounts表裏會有10萬行。這樣咱們建立了一個簡單的16MB大小的數據庫。
使用-s選項, 咱們能夠增長在每張表中的行的數量。在上面的命令中,咱們在「scaling」上填寫了50,這樣pgbench就會建立一個50倍默認大小的數據庫。
咱們的pgbench_accounts如今有5百萬行了。這樣咱們的數據庫變成了800MB (50*16MB)
# pgbench -i -s 50 pxdemo;
等待直到pgbench完成表的建立。咱們接着來確認一下
pgbench_accounts如今有500萬行的填充。
# psql pxdemo \dt select count(*) from pgbench_accounts; \q exit
如今,咱們來模擬PostgreSQL正在運行的節點的失效,
$ NODE=`kubectl get pods -l app=postgres -o wide | grep -v NAME | awk '{print $7}'` $ kubectl cordon ${NODE} node "ip-172-20-57-55.ap-southeast-1.compute.internal" cordoned
執行kubectl get nods, 確認了其中一個節點的排程已經失效了。
$ kubectl get nodes
咱們繼續刪除這個PostgreSQLpod。
$ POD=`kubectl get pods -l app=postgres -o wide | grep -v NAME | awk '{print $1}'` $ kubectl delete pod ${POD} pod "postgres-556994cbd4-b6ghn" deleted
一旦刪除完成。Portworx STorageORchestrator for Kubernetes (STORK)(https://portworx.com/stork-storage-orchestration-kubernetes/),會把pod重置來建立有數據複製集的節點。
一旦Pod被刪除,它會被重置到有數據複製集的節點上。Portworx STorageORchestrator for Kubernetes (STORK) (https://portworx.com/stork-storage-orchestration-kubernetes/)- Portworx的客戶存儲排程器,容許在數據所在節點上放置多個pod,而且確保正確的節點可以被選擇來用來排程Pod。
讓咱們運行下面的命令驗證一下。咱們會發現一個新的pod被建立了,而且被排程在了一個不一樣的節點上。
$ kubectl get pods -l app=postgres
讓咱們把以前的節點從新部署回來。
$ kubectl uncordon ${NODE} node "ip-172-20-57-55.ap-southeast-1.compute.internal" uncordoned
最後,咱們驗證一下數據仍然是可用的。
咱們來看下容器裏的pod名稱和exec。
$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'` $ kubectl exec -it $POD bash
如今用psql來確保咱們的數據還在。
# psql pxdemo pxdemo=# \dt pxdemo=# select count(*) from pgbench_accounts; pxdemo=# \q pxdemo=# exit
咱們看到數據庫表都還在,而且全部的內容都是正確的。
在Postgres進行存儲管理
測試了端到端的數據庫錯誤恢復後,咱們在Kubernetes集羣上來運行StorageOps。
徹底無停機下,擴充卷
咱們如今來演示一下,在空間將滿的狀況下,如何簡單的、動態的爲卷添加空間。
在容器內打開一個shell,
$ POD=`kubectl get pods -l app=postgres | grep Running | awk '{print $1}'` $ kubectl exec -it $POD bash
讓咱們來用pgbench來運行一個baseline transaction benchmark,它將嘗試增長卷容量到1Gib,而且沒能成功。
$ pgbench -c 10 -j 2 -t 10000 pxdemo $ exit
在運行上面命令的時候,可能會有多種錯誤產生。第一個錯誤提示Pod已經沒有空間了。
PANIC: could not write to file "pg_xlog/xlogtemp.73": No space left on device
Kubernetes並不支持在PVC建立後進行修改。咱們在Portworx上用pxctl CLI工具來進行操做。
咱們來獲取卷的名稱,用pxctl工具來查看。
SSH到節點裏,運行下面的命令
POD=`/opt/pwx/bin/pxctl volume list --label pvc=px-postgres-pvc | grep -v ID | awk '{print $1}'` $ /opt/pwx/bin/pxctl v i $POD
注意到卷還有10%就要滿了。讓咱們用下面的命令來擴充。
$ /opt/pwx/bin/pxctl volume update $POD --size=2 Update Volume: Volume update successful for volume 834897770479704521
爲卷作快照,而且恢復數據庫
Portworx支持爲Kubernetes PVCs建立快照。讓咱們爲以前建立的Postgres PVC來建立一個快照。
$ kubectl create -f https://github.com/fmrtl73/katacoda-scenarios-1/raw/master/px-k8s-postgres-all-in-one/assets/px-snap.yaml volumesnapshot "px-postgres-snapshot" created
能夠經過下面的命令來看全部的快照。
$ kubectl get volumesnapshot,volumesnapshotdata
有了快照,咱們來刪掉數據庫。
$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'` $ kubectl exec -it $POD bash $ psql drop database pxdemo; \l \q exit
快照就跟卷是同樣的,咱們可使用它來建立一個新的PostgreSQL實例。讓咱們恢復快照數據,來建立一個新的PostgreSQL實例。
$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-snap-pvc.yaml persistentvolumeclaim "px-postgres-snap-clone" created
重新的PVC,咱們建立一個PostgreSQL Pod,
$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/postgres-app-restore.yaml deployment "postgres-snap" created
確認這個pod是在運行狀態。
$ kubectl get pods -l app=postgres-snap
最後,讓咱們訪問由benchmark工具建立的數據。
$ POD=`kubectl get pods -l app=postgres-snap | grep Running | grep 1/1 | awk '{print $1}'` $ kubectl exec -it $POD bash
$ psql pxdemo \dt select count(*) from pgbench_accounts; \q exit
咱們發現表和數據都是正常的。若是咱們想要在另外一個Amazon區域建立一個容災備份,咱們能夠把快照推送到Amazon S3。Portworx快照支持全部的S3兼容存儲對象,因此備份也能夠是其餘的雲或者是本地部署的數據中心。
_
小結Portworx能夠經過RKE很容易的部署,用來運行Kubernetes上生產系統中有狀態的工做負載。經過跟STORK的整合,DevOps和StorageOps團隊可以無縫的在Kubernetes上運行數據庫集羣。他們也能夠爲雲原生應用運行傳統的操做,好比擴充卷,快照,備份,容災恢復。