天天看點

操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

通過Rancher Kubernetes Engine運作高可用 PostgreSQL

操作指南:通過Rancher在K8S上運作PostgreSQL資料庫
這篇是我們關于在Kubernetes上運作PostgreSQL系列文章的其中一篇。下面是相關文章和連結。

Rancher Kubernetes Engine (RKE)是一個輕量級的Kubernetes 安裝程式,支援在裸金屬和虛拟機上安裝Kubernetes。RKE解決了Kubernetes安裝的複雜性問題。通過RKE安裝是比較簡單的,而跟下層的作業系統無關。

Portworx是一個雲原生的存儲和資料管理平台,來支撐Kubernetes上持久性的工作負載。通過Portworx,使用者能夠管理不同基礎架構上的、不同容器排程器上的資料庫。它為所有的有狀态服務(Stateful Service)提供了一個單一的資料管理層。

本文列出了操作步驟:通過RancherKubernetes Engine (RKE),在AWS的Kubernetes叢集上,部署和管理高可用PostgreSQL叢集。

總結來說,在Amazon上運作高可用PostgreSQL,需要:

  1. 通過Rancher KubernetesEngine安裝一個Kubernetes叢集
  2. 安裝雲原生存儲解決方案Portworx,作為Kubernetes的一個DaemonSet。
  3. 建立一個存儲類來定義你的存儲要求,比如,複制因子,快照政策和性能情況
  4. 使用Kubernetes部署PostgreSQL
  5. 通過killing或者cordoning叢集中的節點,來測試故障恢複
  6. 可能的話,動态的調整PG Volume的大小,快照和備份Postgres到S3

如何通過RKE來建立一個Kubernetes叢集

RKE是一個安裝和配置Kubernetes的工具。可以支援的環境包括裸金屬,虛拟機或者IaaS。在本文中,我們會在AWS EC2上建立一個3節點的Kubernetes叢集。

更為詳細的步驟,可以參考這篇tutorial from The New Stack. (

https://thenewstack.io/run-stateful-containerized-workloads-with-rancher-kubernetes-engine-and-portworx/

做完這些操作,我們會建立一個1 master 和 3 worker 節點的叢集。

操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

在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的所有操作步驟。

操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

等候直到Postgres pod變成運作狀态。

操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

我們可以通過使用與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}           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

指令的輸出資訊,确認了支撐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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

預設狀态下,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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

現在,我們來模拟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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

我們繼續删除這個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) (

)- Portworx的客戶存儲排程器,允許在資料所在節點上放置多個pod,并且確定正确的節點能夠被選擇來用來排程Pod。

讓我們運作下面的指令驗證一下。我們會發現一個新的pod被建立了,并且被排程在了一個不同的節點上。

$ kubectl get pods -l app=postgres           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

讓我們把之前的節點重新部署回來。

$ 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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

我們看到資料庫表都還在,并且所有的内容都是正确的。

在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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

在運作上面指令的時候,可能會有多種錯誤産生。第一個錯誤提示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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

注意到卷還有10%就要滿了。讓我們用下面的指令來擴充。

$ /opt/pwx/bin/pxctl volume update $POD --size=2

Update Volume: Volume update successful for volume 834897770479704521           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

為卷做快照,并且恢複資料庫

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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

有了快照,我們來删掉資料庫。

$ 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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

最後,讓我們通路由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           
操作指南:通過Rancher在K8S上運作PostgreSQL資料庫

我們發現表和資料都是正常的。如果我們想要在另一個Amazon區域建立一個容災備份,我們可以把快照推送到Amazon S3。Portworx快照支援所有的S3相容存儲對象,是以備份也可以是其他的雲或者是本地部署的資料中心。

_

小結

Portworx可以通過RKE很容易的部署,用來運作Kubernetes上生産系統中有狀态的工作負載。通過跟STORK的整合,DevOps和StorageOps團隊能夠無縫的在Kubernetes上運作資料庫叢集。他們也可以為雲原生應用運作傳統的操作,比如擴充卷,快照,備份,容災恢複。