Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗

越來越多的客戶收到這樣的請求:“我們想要像 Amazon RDS 一樣的產品,但更便宜”; “我們希望它像 RDS 一樣,但無處不在,在任何基礎設施中。” 為了在 Kubernetes 上實現這樣的託管解決方案,我們研究了 PostgreSQL 最受歡迎的運算符(Stolon、Crunchy Data 和 Zalando 的運算符)的當前狀態並做出了選擇。

這篇文章是我們從理論角度(對解決方案的回顧)和實踐角度(選擇什麼以及結果)的經驗。 但首先,讓我們定義一下 RDS 潛在替代品的一般要求是什麼……

什麼是RDS

根據我們的經驗,當人們談論 RDS 時,他們指的是託管 DBMS 服務:

  1. 易於設置;
  2. 能夠使用快照並從中恢復(最好支持 PITR);
  3. 允許您創建主從拓撲;
  4. 擁有豐富的擴展列表;
  5. 提供審核和用戶/訪問管理。

一般來說,執行任務的方法可能有很大不同,但條件 Ansible 的路徑離我們並不近。 (2GIS 的同事得出了類似的結論,因為 他的嘗試 創建一個“基於 Postgres 的故障轉移集群快速部署工具”。)

Operator 是 Kubernetes 生態中解決此類問題的普遍接受的方法。 Flant 的技術總監已經告訴我們,關於 Kubernetes 內運行的數據庫的更多詳細信息, 迪斯托爾他的一份報告.

NB:為了快速創建簡單的運算符,我們建議您關注我們的開源實用程序 外殼操作符。 使用它,您可以在不了解 Go 的情況下完成此操作,但可以使用系統管理員更熟悉的方式:Bash、Python 等。

PostgreSQL 有幾種流行的 K8s 運算符:

  • 匍匐莖;
  • Crunchy 數據 PostgreSQL 操作符;
  • Zalando Postgres 運算符。

讓我們更仔細地看看它們。

運營商選擇

除了上面已經提到的重要功能之外,作為 Kubernetes 的基礎設施工程師,我們還期望運營商提供以下功能:

  • 從 Git 部署並使用 定制資源;
  • Pod 反親和力支持;
  • 安裝節點關聯性或節點選擇器;
  • 設置公差;
  • 調整選項的可用性;
  • 易於理解的技術甚至命令。

在不詳細介紹每一點的情況下(在閱讀整篇文章後,如果您仍然對它們有疑問,請在評論中詢問),我會一般性地指出,需要這些參數來更微妙地描述集群節點的專業化以便為特定應用訂購它們。 這樣我們就可以達到性能和成本之間的最佳平衡。

現在 - PostgreSQL 操作員本身。

1.匍匐莖

斯托隆 來自意大利公司 Sorint.lab 已經提到的報告 被認為是 DBMS 操作員之間的一種標準。 這是一個相當古老的項目:它的首次公開發佈於 2015 年 3000 月(!),GitHub 存儲庫擁有近 40 顆星和 XNUMX 多名貢獻者。

事實上,Stolon 是深思熟慮的建築的一個很好的例子:

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗
該運營商的設備可以在報告中找到詳細信息或 項目文件。 一般來說,只需說它可以完成所描述的所有操作:故障轉移、用於透明客戶端訪問的代理、備份...此外,代理通過一個端點服務提供訪問- 與下面討論的其他兩種解決方案不同(它們有兩種用於訪問的服務)根據)。

然而,斯多隆 沒有自定義資源,這就是為什麼它不能以簡單快速的方式部署——“像熱蛋糕一樣”——在 Kubernetes 中創建 DBMS 實例。 管理是通過實用程序進行的 stolonctl、部署 - 通過 Helm-chart,自定義的在 ConfigMap 中定義。

一方面,事實證明該運算符並不是真正的運算符(因為它不使用 CRD)。 但另一方面,它是一個靈活的系統,允許您按照自己想要的方式配置 K8s 中的資源。

總而言之,對於我們個人來說,為每個數據庫啟動單獨的圖表似乎不是最好的方法。 所以我們開始尋找替代方案。

2. Crunchy Data PostgreSQL 操作符

來自 Crunchy Data 的運算符一家年輕的美國初創公司看起來是一個合乎邏輯的選擇。 它的公開歷史始於 2017 年 1300 月的第一個版本,從那時起,GitHub 存儲庫已獲得近 50 顆星和 1.15 多名貢獻者。 1.18 月份的最新版本經過測試,可與 Kubernetes 3.11-4.4、OpenShift 1.3+ 和 XNUMX+、GKE 和 VMware Enterprise PKS XNUMX+ 配合使用。

Crunchy Data PostgreSQL Operator 架構也滿足規定的要求:

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗

管理是通過實用程序 pgo然而,它反過來又為 Kubernetes 生成自定義資源。 因此,運營商讓我們作為潛在用戶感到高興:

  • 通過CRD進行控制;
  • 方便的用戶管理(也可以通過CRD);
  • 與其他組件集成 脆脆的數據容器套件 - PostgreSQL 容器映像的專門集合以及使用它的實用程序(包括 pgBackRest、pgAudit、contrib 的擴展等)。

然而,嘗試開始使用 Crunchy Data 中的運算符發現了幾個問題:

  • 不存在容忍的可能性——僅提供了nodeSelector。
  • 儘管我們正在部署有狀態應用程序,但創建的 Pod 是部署的一部分。 與 StatefulSet 不同,Deployments 無法創建磁盤。

最後一個缺陷導致了有趣的時刻:在測試環境中,我們設法用一個磁盤運行 3 個副本 本地存儲,結果操作員報告 3 個副本正在工作(儘管事實並非如此)。

該操作員的另一個特點是它與各種輔助系統的現成集成。 例如,安裝 pgAdmin 和 pgBounce 很容易,並且在 文件 考慮預配置的 Grafana 和 Prometheus。 在最近的一次 發布4.5.0-beta1 單獨指出與項目的改進集成 程序監視器,得益於此,操作員提供了開箱即用的 PgSQL 指標的可視化可視化。

然而,Kubernetes 生成的資源的奇怪選擇導致我們找到了不同的解決方案。

3. Zalando Postgres 操作員

Zalando 產品早已為我們所知:我們有使用 Zalenium 的經驗,當然,我們也嘗試過 帕特羅尼 是他們流行的 PostgreSQL HA 解決方案。 關於公司的創建方法 PostgreSQL 運算符 在廣播中告訴其作者之一阿列克謝·克柳金 (Alexei Klyukin) Postgres-星期二 #5我們喜歡它。

這是本文中討論的最年輕的解決方案:第一次發佈於 2018 年 1300 月。 然而,儘管正式發布的版本數量很少,但該項目已經取得了長足的進步,已經超越了Crunchy Data 解決方案的受歡迎程度,在GitHub 上擁有70 多顆星,貢獻者數量最多(XNUMX+) 。

該操作員的“幕後”使用了經過時間考驗的解決方案:

以下是 Zalando 的操作架構的呈現方式:

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗

Operator 通過自定義資源進行完全管理,自動從容器創建 StatefulSet,然後可以通過向 pod 添加各種 sidecar 來對其進行自定義。 與 Crunchy Data 的運算符相比,所有這些都是一個顯著的優點。

由於我們在考慮的 3 個選項中選擇了 Zalando 的解決方案,因此下面將立即介紹其功能的進一步描述以及應用實踐。

與 Zalando 的 Postgres Operator 一起練習

Operator 部署非常簡單:只需從 GitHub 下載最新版本並應用目錄中的 YAML 文件 表現。 或者,您也可以使用 運營商中心.

安裝後,您應該注意設置 日誌和備份存儲。 這是通過 ConfigMap 完成的 postgres-operator 在您設置運算符的命名空間中。 配置存儲庫後,您可以部署第一個 PostgreSQL 集群。

例如,我們的標準部署如下所示:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

此清單部署了一個由 3 個實例組成的集群,其中邊車的形式如下 postgres_exporter,我們從中收集應用程序指標。 正如您所看到的,一切都非常簡單,如果您願意,您可以創建幾乎無限數量的集群。

值得關注 用於管理的網絡面板 - postgres-operator-ui。 它隨操作員一起提供,允許您創建和刪除集群,以及使用操作員製作的備份。

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗
PostgreSQL 集群列表

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗
備份管理

另一個有趣的功能是支持 團隊 API。 該機制自動創建 PostgreSQL 中的角色,基於生成的用戶名列表。 之後,API 允許您返回自動創建角色的用戶列表。

問題及解決方案

然而,該運算符的使用很快就暴露出幾個顯著的缺點:

  1. 缺乏節點選擇器支持;
  2. 無法禁用備份;
  3. 使用create bases功能時,不出現默認權限;
  4. 有時沒有足夠的文檔或者已經過時。

幸運的是,其中許多問題都可以得到解決。 讓我們從最後開始 - 問題 文檔.

您很可能會遇到這樣一個事實:並不總是清楚如何註冊備份以及如何將備份存儲桶連接到操作員 UI。 文檔中順便提到了這一點,但真正的描述在 PR:

  1. 你需要保守秘密;
  2. 將其作為參數傳遞給操作員 pod_environment_secret_name 在帶有操作員設置的 CRD 中或在 ConfigMap 中(取決於您選擇安裝操作員的方式)。

然而,事實證明,目前這是不可能的。 這就是為什麼我們收集了 您的操作員版本 以及一些額外的第三方開發。 更多相關信息 - 見下文。

如果將參數傳遞給操作員進行備份,即 - wal_s3_bucket 並訪問AWS S3中的密鑰,然後它 將備份所有內容:不僅是生產基地,還有演出基地。 它不適合我們。

在使用操作符時對 Spilo(PgSQL 的基本 Docker 包裝器)的參數的描述中,結果表明您可以傳遞參數 WAL_S3_BUCKET 空,從而禁用備份。 此外,令我非常高興的是,我發現 準備好公關,我們立即將其接受到我們的叉子中。 現在很容易添加 enableWALArchiving: false 到 PostgreSQL 集群資源。

是的,可以通過運行 2 個操作員來實現不同的目的:一個用於暫存(沒有備份),第二個用於生產。 但我們還是能應付得來。

好的,我們已經學習瞭如何將對 S3 的訪問轉移到數據庫,並且備份開始進入存儲。 如何使備份頁面在 Operator UI 中工作?

Kubernetes 的 PostgreSQL 語句簡述,我們的選擇和經驗

在 Operator UI 中,您需要添加 3 個變量:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

之後,備份管理將變得可用,在我們的例子中,這將簡化分段工作,允許您從生產環境中交付切片,而無需額外的腳本。

另一個優點是使用 Teams API 進行工作,以及使用操作員工具創建數據庫和角色的廣泛機會。 然而,新興的 角色默認沒有權限。 因此,具有讀取權限的用戶無法讀取新表。

這是為什麼? 即使在代碼中 必要的 GRANT它們並不總是被應用。 有2種方法: syncPreparedDatabases и syncDatabases。 在 syncPreparedDatabases - 儘管事實上在本節中 preparedDatabases 有一個條件 defaultRoles и defaultUsers 創建角色時,不應用默認權限。 我們正在準備補丁,以便自動應用這些權利。

與我們相關的改進的最後一刻 - 修補向生成的 StatefulSet 添加節點關聯性。 我們的客戶通常更喜歡通過使用現貨實例來降低成本,這顯然不值得託管數據庫服務。 這個問題可以通過容忍來解決,但節點親和性的存在給予了更多信心。

怎麼了?

為了解決上述問題,我們將 Postgres Operator 從 Zalando 分叉為 你的存儲庫如此有用的補丁將去向何方。 為了更加方便,我們還收集了 Docker鏡像.

分叉中接受的 PR 列表:

如果社區支持這些 PR,以便他們能夠在下一版本的操作符 (1.6) 中上游,那就太好了。

獎金! 生產遷移成功案例

如果您使用 Patroni,現場製作可以在最少的停機時間內轉移給操作員。

Spilo 允許您通過 S3 存儲創建備用集群 瓦勒當 PgSQL 二進制日誌首先存儲在 S3 中,然後由副本抽出時。 但如果你有呢? 沒有 Wal-E 在舊基礎設施中使用過嗎? 這個問題的解決方案已經 有人建議 在輪轂上。

PostgreSQL 邏輯複製可以解決這個問題。 不過,我們不會詳細介紹如何創建出版物和訂閱,因為……我們的計劃失敗了。

事實上,數據庫有幾個已加載的表,其中包含數百萬行,而且這些表不斷被補充和刪除。 簡單訂閱 с copy_data,當新副本從主副本複制所有內容時,它只是無法跟上主副本。 內容複製工作了一周,但始終追不上大師。 最終幫助解決了問題 文章 Avito 的同事:您可以使用以下方式傳輸數據 pg_dump。 我將描述我們的(稍作修改的)版本的算法。

這個想法是,您可以將禁用的訂閱綁定到特定的複制槽,然後修復事務號。 有用於生產工作的複製品。 這很重要,因為副本將幫助創建一致的轉儲並繼續接收來自主服務器的更改。

描述遷移過程的後續命令將使用以下主機表示法:

  1. — 源服務器;
  2. 副本1 - 舊作品的流媒體複製品;
  3. 副本2 - 新的邏輯副本。

遷移計劃

1. 在嚮導上創建對架構中所有表的訂閱 public 基地 dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. 在master上創建複製槽:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. 停止舊副本上的複制:

psql -h replica1 -c "select pg_wal_replay_pause();"

4、從master獲取交易號:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. 從舊副本中轉儲。 我們將在多個線程中執行此操作,這將有助於加快該過程:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. 將轉儲上傳到新服務器:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. 下載轉儲後,您可以在流副本上開始復制:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. 在新的邏輯副本上創建訂閱:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. 獲取 oid 訂閱:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. 假設已收到 oid=1000。 讓我們將交易號應用到訂閱中:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10.讓我們開始復制:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. 檢查訂閱狀態,複製應該可以工作:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. 複製啟動並同步數據庫後,您可以進行切換。

13. 禁用複制後,您需要修復序列。 描述得很好 在 wiki.postgresql.org 上的文章中.

由於這個計劃,切換以最小的延遲完成。

結論

Kubernetes Operator 允許您通過減少創建 K8s 資源來簡化各種操作。 然而,在他們的幫助下實現了顯著的自動化後,值得記住的是,它也可能帶來許多意想不到的細微差別,因此請明智地選擇操作員。

在審查了 PostgreSQL 的三個最受歡迎的 Kubernetes 運算符後,我們選擇了 Zalando 的項目。 我們必須克服一些困難,但結果確實令人高興,因此我們計劃將這種體驗擴展到 PgSQL 的其他一些安裝中。 如果您有使用類似解決方案的經驗,我們將很高興在評論中看到詳細信息!

聚苯乙烯

另請閱讀我們的博客:

來源: www.habr.com

添加評論