Enterprise Postgres made easy. On Kubernetes
StackGres 是 Kubernetes 的全棧 PostgreSQL 發行版,打包成一個簡單的部署單元。
使用精心選擇和調優的 PostgreSQL 元件。
一個企業級的 PostgreSQL 棧需要幾個其他的生態系統元件和重要的調整。
不僅僅是 PostgreSQL。它需要連線池、自動故障轉移和 HA、監控、備份和 DR、集中式紀錄檔記錄……我們已經構建了它們:一個 Postgres 堆疊。
Postgres 不僅僅是資料庫。還有圍繞它的整個生態系統。如果 Postgres 是 Linux 核心,我們需要一個圍繞 PostgreSQL 的 PostgreSQL 發行版,用生產部署所需的元件來補充它。這就是我們所說的 PostgreSQL 棧。這堆東西需要整理。通常有幾個軟體實現相同的功能。並不是所有的都具有相同的品質或成熟度。有許多優點和缺點,它們往往不容易評估。最好有一個自定義的元件選擇,這些元件可以打包和設定為以可預測和可信的方式一起工作。
Operator 是一種打包、部署和管理 Kubernetes 應用程式的方法。一些應用程式,比如資料庫,需要更多的手工操作,而云原生 Postgres 需要 operator 提供額外的知識,瞭解如何維護狀態和整合所有元件。StackGres operator 允許使用使用者建立的一些自定義資源來部署 StackGres 叢集。
目前,StackGres 的堆疊由以下元件組成:
StackGres 是 Kubernetes 的全棧、生產級 PostgreSQL 發行版。StackGres 提供了在生產環境中執行 PostgreSQL 所需的所有特性和管理選項,除此之外,它還附帶了合理的預設選項。
"StackGres" 這個名字來源於執行生產級 PostgreSQL 範例所需的 「元件堆疊」。
在這一頁,我們將介紹 StackGres 的重要概念。
生產就緒的資料庫管理是 StackGres 的核心。StackGres 以一種簡單的宣告性方式支援所有常見的(和一些不常見的)資料庫管理操作。在這樣做的同時,StackGres 堅持生產級行為。這意味著不只是盲目地執行某些操作(例如,當用戶更新資料庫範例的目標狀態時),而是以一種最小化應用程式和使用者中斷的方式,就像優秀的 DBA 所做的那樣。
因此,您可以將 StackGres 視為您友好的 DBA 的 Kubernetes 版本-只是使用 Kubernetes API,更快的響應時間和更少的咖啡休息時間。
StackGres 是一個基於 Kubernetes 的平臺,它以 Kubernetes operator 的形式提供生產級 PostgreSQL。所以 StackGres 的一切都與 Kubernetes 緊密相連。
Kubernetes operator 是一種打包、部署和管理基於 Kubernetes 的應用程式或平臺的方法。
有些工作負載(如資料庫)需要更多的手工操作,而云原生 Postgres 部署需要了解如何維護狀態和整合所有元件。
StackGres operator 允許使用使用者建立的一些自定義資源來部署 StackGres 叢集。
除此之外,StackGres 還遵循了工程師所熟悉和喜歡的 Kubernetes 的可用性和觀感。使用者自定義的 StackGres 資源意味著在 Kubernetes 中我們所知道的相同的方便的宣告式模型中使用。也就是說,使用者定義一個期望的目標狀態(通常是YAML,儘管也可能有其他選項),StackGres operator 完成如何達到該目標狀態的繁重工作。
StackGres 平臺為所有與 Postgres 相關的操作提供了一個單一的存取點。
使用者有多種方式存取和修改 Postgres 叢集,即通過 Kubernetes API(例如使用 kubectl
), REST API 或 web UI。
無論選擇哪種方式或哪種組合,StackGres 都確保狀態和所有操作始終一致。
這為使用者提供了最大的靈活性和簡單性。例如,如果 StackGres 設定由三個使用者操作,其中一個使用者使用 kubectl
處理所有事情,第二個使用者使用自己的 curl
指令碼,第三個使用者使用 UI,那麼他們都可以執行相同的操作並存取相同的資訊。所有不同的方式都能實現所有的功能。
StackGres "stack" 的元件由部署在主 Postgres 容器旁邊的 sidecar 容器提供。
所有容器基礎映象都是由 StackGres 構建和提供的。
輕量級和安全的容器映像基於 RedHat 的 UBI 8。
當我們提到 "cluster" 時,我們指的是由 StackGres 管理的 PostgreSQL 伺服器的集合。
因此,StackGres 叢集(由自定義 Kubernetes 資源型別 SGCluster
定義)是一個複製、管理、生產就緒和優化的 PostgreSQL 伺服器。StackGres 叢集具有固定的、合理的設定預設值,所有這些都偏向於生產級體驗。因此,對於一個工作設定,定義一個 StackGres 叢集已經足夠了。
StackGres 叢集基本上是一個 statfulset,其中每個 pod 是一個資料庫範例。
StatefulSet 保證每個 pod 總是繫結到它自己的持久卷。
因此,資料庫範例資料將被對映到 kubernetes 中 Patroni 範例的狀態。
我們使用一種稱為 sidecar 的模式,其中主應用程式在容器中執行,
而位於同一 pod 中的其他容器提供連線池、統計資料匯出、邊緣代理、紀錄檔排程程式或資料庫實用程式等側功能。
UDS: Unix Domain Socket
在生產環境中成功執行 Postgres 需要一整套與 PostgreSQL 相關的元件——一組精心設計的開源元件,它們被構建、驗證並打包在一起。有一個圍繞 Postgres 構建的工具生態系統,可以用來建立 Postgres 發行版。這就是我們所說的元件堆疊。
為了進行比較,Postgres 就像 Linux 發行版的 Linux 核心——雖然它位於核心,但它仍然需要周圍的許多元件來提供 Linux 發行版所提供的功能。
選擇該堆疊的正確元件是一項具有挑戰性的任務。
在我們做出選擇之前,有許多元件和多個軟體發行版在功能上重疊,或者有優缺點需要考慮。
需要對所有元件有高度的瞭解,以便選擇適合的元件並提供生產就緒的 Postgres 發行版。
我們的 Postgres 發行版由一個核心元件 (Postgres) 和其他一些元件組成,這些元件滿足了 Postgres 生產發行版在不同領域的需求。
用於 Postgres 叢集節點的主容器使用 UBI 8 最小映象作為其基礎映象,其中新增了一個普通 PostgreSQL。容器使用通過 storage class 設定的持久儲存。始終與 sidecar util 容器一起部署,以允許系統/資料庫管理員存取。
在生產環境中使用預設設定執行 PostgreSQL 通常不是一個好主意。PostgreSQL 使用非常保守的預設值,為了獲得良好的效能,必須對其進行調優。
這裡有一些地方可以找到更多關於 Postgres 設定引數和最佳實踐的資訊:
預設情況下,StackGres 被調優以獲得比使用預設設定更好的效能。使用者仍然可以根據自己的需要更改設定。
直接連線到 PostgreSQL 不能很好地擴充套件。一旦達到設定的 max_connections
限制(預設值為 100),超過這個數的連線將被拒絕,這是必須避免的。
雖然許多企業應用程式框架提供了共用資料庫連線的功能,但多個應用程式部署幾乎從不共用它們的連線池。
設定一個非常高的允許連線數並不能完全解決這個問題,因為我們會注意到連線延遲與負載不成比例地增加,如下圖所示(綠線):
這是由於 PostgreSQL 每個連線管理一個程序,這對於大量連線會導致 CPU 核心爭用和作業系統排程開銷。
由於這些原因,強烈建議在資料庫範例前面使用適當的連線池。
以下是三種常見的 PostgreSQL 連線池解決方案:
現在,選擇哪一個呢?
StackGres 選擇的解決方案是 PgBouncer。
StackGres 選擇的解決方案是 PgBouncer。它足夠簡單和穩定,可以用於連線池。
PgBouncer 的缺點是缺乏多執行緒,當連線增加超過一定限制時可能導致 CPU 飽和,這取決於執行的單個 CPU 核心的效能。
當前者變得更加成熟時,Odyssey 可能是取代 PgBouncer 的一個很好的候選人。
如果一個 Postgres 範例宕機或不能正常工作,我們希望通過選擇一個工作範例轉換為新的主範例並設定所有其他範例和應用程式以指向這個新的主範例來恢復叢集。我們希望這一切都能在沒有人工干預的情況下發生。
高可用性解決方案可以實現這一點。這個問題有多種解決方案,很難從中選擇一種:
StackGres 選擇 Patroni 作為 HA 解決方案。它是一個很好的解決方案,依靠分散式共識演演算法為主範例的選擇提供一致的機制。特別是,Patroni 能夠使用與 Kubernetes 相同的分散式共識演演算法,因此它不需要安裝其他服務。
備份解決方案也是一個有多種選擇的生態系統:
另外,我們將備份儲存在哪裡?
最後,我們的備份是否會在需要時工作,還是會失敗?
Wal-g 是 Wal-e 的後繼版本,是提供增量(通過 archive 命令)和完全備份支援的最完整、最輕量級的解決方案。
此外,它還提供了開箱即用的特性,允許在持久卷中儲存備份
(使用支援 ReadWriteMany
存取的儲存類)或 AWS S3、谷歌雲端儲存或 Azure Blob 儲存等雲端儲存。Wal-g 還允許設定頻寬或磁碟使用率等方面。
我們希望將分佈在所有容器中的紀錄檔儲存在一箇中心位置,並能夠在需要時對其進行分析。沒有好的解決方案,所以必須自己創造一個。有 fluentd 和 Loki,但後者不能很好地與 Postgres 一起工作。另一種方法是使用 Timescale 將所有紀錄檔儲存在 Postgres 中。
如何定位主範例,如果它發生了變化怎麼辦?我如何獲得流量指標?是否可以管理流量:副本,A/B測試叢集,或事件檢查?
Envoy 是一個開源的邊緣和服務代理,專為雲原生應用而設計。它是
可延伸,以便根據實際流量或連線特性提供高階功能。例如,可以解析 Postgres 指標以提供統計資料,或者可以設定 TLS 證書。
Envoy 還能夠使用完善的 Prometheus 格式 暴露指標。
OnGres Inc.贊助了 Envoy Proxy 專案,提供了暴露 PostgreSQL 監控指標 和實現 SSL termination support 支援等貢獻。
我們可以使用哪種監控解決方案來監控 Postgres 叢集?
StackGres 的方法是啟用盡可能多的監控解決方案。目前,只有 Prometheus 可以使用 PostgreSQL Server Exporter 連線到 StackGres stats,並且如果使用 Prometheus Operator 安裝 Prometheus,則可以整合為提供自動繫結機制的 sidecar。
請注意 Prometheus 是一個外部依賴,StackGres 希望你單獨安裝和設定它。
當然,StackGres 提供了一個選項,可以將 Prometheus 與 StackGres Operator 一起部署,作為 Helm chart 的一部分,您可以按照其中描述的步驟設定所需的引數,以便監視整合按預期工作。請閱讀並回顧成功安裝的步驟和注意事項。
另外請注意,Prometheus 將在某個時候從 Helm chart 中刪除,因此實際的說明將會改變並過時。
預設情況下,Prometheus Operator Helm chart 與 Grafana 一起提供。StackGres 提供了一個整合,允許直接從 StackGres UI 監控 StackGres 叢集 pod。實現這一目標有多種選擇。
StackGres包括兩種方式:
為了實現這樣的整合,需要一些手動步驟。
有一些使用者介面可用於與 Postgres 互動,例如 DBeaver,它允許檢視資料庫內容和設定。我們需要一個能夠管理整個叢集的使用者介面。如何列出叢集?一個叢集有多少個節點?複製狀態如何?一個節點使用了多少計算資源?如何獲取特定節點的監控資訊?
StackGres 通過 web 和 CLI 提供了一個使用者介面,它能夠監控和與建立的 StackGres 叢集互動。它允許執行基本和高階任務,如 list/get/create/update/delete 叢集或執行切換或備份恢復。