【編者的話】本文主要介紹瞭如何在Kubernetes環境中用Stolon去部署高可用的PostgreSQL,本文從Stolon的結構組成開始,由淺入深介紹原理,從開始安裝到最後對其進行failover測試,深入淺出,為以後部署高可用的PostgreSQL提供了一種的解決方案。

20170312110305

建立一個高可用的PostgreSQL叢集環境總是一件棘手的事情。在雲環境裡部署時更是非常困難。我至少找到了3個專案,它們可以在Kubernetes裡提供高可用的PostgreSQL解決方案。

Patroni是一個模板,它使用Python為你提供一個自己訂製的,高可用的解決方案,為最大程度的可用性,它的配置資訊儲存在像ZooKeeper, etcd或者Consul中。如果DBAs,DevOps工程師或者SRE正在尋找一個在資料中心中快速部署高可用PostgreSQL方案,或者其他的用途,我希望Patroni能夠幫到他們。

Crunchy容器套件提供一個了Docker容器,它能快速部署PostgreSQL,同時也提供管理和監控的工具。並且支援多種用風格的部署PostgreSQL叢集。

Stolon是一個cloud native的PostgreSQL高可用管理工具。它之所以是cloud native的是因為它可以在為容器內部的PostgreSQL提供高可用(kubernetes 整合),而且還支援其他種類的基礎設施(比如:cloud Iaas,舊風格的基礎設施等)

漂亮的圖表加上一些在kubernets.io上的使用者分享說服我去試一下crunchy容器。但是過了一段時間,我改變了想法。

我不想說他設計上的某些缺點或者是其他的什麼不好。但是它給我的感覺就好像是我自己在容器裡手動安裝PostgreSQL一樣,並沒有雲的感覺。

所以我嘗試了一下stolon。在一次又一次的安裝和解除安裝之後,我運行了它的statefulset的例子並且用helm chart建立。

如果你想知道更多關於stolon可以參考作者這篇介紹

下面我將展示一下安裝過程並且演示一下叢集環境下的failover。我們假設安裝用的是helm chart。

Stolon 架構圖(摘抄自stolon的介紹)

20170312110257

Stolon 是由3個部分組成的:

  • keeper:他負責管理PostgreSQL的例項匯聚到由sentinel(s)提供的clusterview。
  • sentinel:it負責發現並且監控keeper,並且計算最理想的clusterview。
  • proxy:客戶端的接入點。它強制連線到右邊PostgreSQL的master並且強制關閉連線到由非選舉產生的master。

Stolon 用etcd或者consul作為主要的叢集狀態儲存。

Installation

$ git clone https://github.com/lwolf/stolon-chart
$ cd stolon-chart
$ helm install ./stolon

You can also install directly from my repository

helm repo add lwolf-charts http://charts.lwolf.org
helm install lwolf-charts/stolon

安裝的過程將會做如下的動作:

首先,會用statefulset建立3個etcd節點。Stolon-proxy和stolon-sentinel也會被部署。Singe time job將叢集的安裝暫停直到etcd節點狀態變成availabe。
chart還會建立兩個服務

  • stolon-proxy—服務來源於官方的例子。他總是指向當前的因該被寫入的master。
  • stolon-keeper—Stolon自己本身不提供任何讀取操作的負載均衡。但是kubernetes的service卻可以做到這點。所以對於使用者來說,stolon-keeper的讀操作是在pod的層面做到負載均衡的。

當所有的元件狀態變為RUNNING時,我們可以試著連線它們。

我們可以用NodePort這種簡單的連線方式部署service。用兩個終端分別去連線master service和slave service。在post的過程中,我們假設stolon-proxy服務(RW)已經暴露了30543埠,stolon-keeper服務(RO)已經暴露了30544埠。

連線master並且建立test表

psql --host <IP> --port 30543 postgres -U stolon -W
postgres=# create table test (id int primary key not null,
value text not null);
CREATE TABLE
postgres=# insert into test values (1, 'value1');
INSERT 0 1
postgres=# select * from test;
id | value
---- --------
1 | value1
(1 row)

連線slave並且檢查資料。你可以寫一些資訊以便確認請求已經被slave處理了。

psql --host <IP> --port 30544 postgres -U stolon -W
postgres=# select * from test;
id | value
---- --------
1 | value1
(1 row)

在測試通過後,我們去試試failover功能。

測試failover

這個案例是官方程式碼庫中statefullset的一個例子
簡單的說,就是為模擬了master掛掉,我們先刪除了master的statefulset又刪除了master的pod。

kubectl delete statefulset stolon-keeper --cascade=false
kubectl delete pod stolon-keeper-0

然後,在sentinel的log中我們可以看到新的master被選舉出來了。

no keeper info available db=cb96f42d keeper=keeper0
no keeper info available db=cb96f42d keeper=keeper0
master db is failed db=cb96f42d keeper=keeper0
trying to find a standby to replace failed master
electing db as the new master db=087ce88a keeper=keeper1

現在,在剛才的那兩個終端中如果我們重複上一個命令,我們可以看到如下輸出。

postgres=# select * from test;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset:
Succeeded.
postgres=# select * from test;
id | value
---- --------
1 | value1
(1 row)

Kubernetes的service把不可用的pod去掉,把請求轉到可用的pod上。所以新的讀取連線被路由到了健康的pod上。

最後,我們需要重新建立statefulset。最簡單的方法就是更新部署了的helm chart。

helm ls
NAME REVISION UPDATED
STATUS CHART NAMESPACE
factual-crocodile 1 Sat Feb 18 15:42:50 2017
DEPLOYED stolon-0.1.0 default
helm upgrade factual-crocodile .

2.用chaoskube模擬隨機的pod掛掉

另一個測試叢集彈性(resilience)的好方法是用chaoskube。Chaoskube是一個小的服務程式,它可以週期性的在叢集裡隨機的kill掉一些的pod。它也可以用helm charts部署。

helm install --set labels="release=factualcrocodile,
component!=factual-crocodine-etcd" --set
interval=5m stable/chaoskube

這條命令會執行chaoskube,它會每5分鐘刪除一個pod。它會選擇label中release=factual-crocodile的pod,但是會忽略etcd的pod。

在做了幾個小時的測試之後,我的叢集環境仍然是一致並且工作的很穩定。

結論

我仍然在我的開發伺服器上執行stolon。到目前為止我還是滿意的。他真的很想一個本地的運環境。有很好的彈性和自動化的failover能力。

如果你對它感興趣-可以檢視我的官方repository或者和我的chart