越來越多的客戶收到這樣的請求:“我們想要像 Amazon RDS 一樣的產品,但更便宜”; “我們希望它像 RDS 一樣,但無處不在,在任何基礎設施中。” 為了在 Kubernetes 上實現這樣的託管解決方案,我們研究了 PostgreSQL 最受歡迎的運算符(Stolon、Crunchy Data 和 Zalando 的運算符)的當前狀態並做出了選擇。
這篇文章是我們從理論角度(對解決方案的回顧)和實踐角度(選擇什麼以及結果)的經驗。 但首先,讓我們定義一下 RDS 潛在替代品的一般要求是什麼……
什麼是RDS
根據我們的經驗,當人們談論 RDS 時,他們指的是託管 DBMS 服務:
- 易於設置;
- 能夠使用快照並從中恢復(最好支持
PITR ); - 允許您創建主從拓撲;
- 擁有豐富的擴展列表;
- 提供審核和用戶/訪問管理。
一般來說,執行任務的方法可能有很大不同,但條件 Ansible 的路徑離我們並不近。 (2GIS 的同事得出了類似的結論,因為
Operator 是 Kubernetes 生態中解決此類問題的普遍接受的方法。 Flant 的技術總監已經告訴我們,關於 Kubernetes 內運行的數據庫的更多詳細信息,
NB:為了快速創建簡單的運算符,我們建議您關注我們的開源實用程序
PostgreSQL 有幾種流行的 K8s 運算符:
- 匍匐莖;
- Crunchy 數據 PostgreSQL 操作符;
- Zalando Postgres 運算符。
讓我們更仔細地看看它們。
運營商選擇
除了上面已經提到的重要功能之外,作為 Kubernetes 的基礎設施工程師,我們還期望運營商提供以下功能:
- 從 Git 部署並使用
定制資源 ; - Pod 反親和力支持;
- 安裝節點關聯性或節點選擇器;
- 設置公差;
- 調整選項的可用性;
- 易於理解的技術甚至命令。
在不詳細介紹每一點的情況下(在閱讀整篇文章後,如果您仍然對它們有疑問,請在評論中詢問),我會一般性地指出,需要這些參數來更微妙地描述集群節點的專業化以便為特定應用訂購它們。 這樣我們就可以達到性能和成本之間的最佳平衡。
現在 - PostgreSQL 操作員本身。
1.匍匐莖
事實上,Stolon 是深思熟慮的建築的一個很好的例子:
該運營商的設備可以在報告中找到詳細信息或
然而,斯多隆 stolonctl
、部署 - 通過 Helm-chart,自定義的在 ConfigMap 中定義。
一方面,事實證明該運算符並不是真正的運算符(因為它不使用 CRD)。 但另一方面,它是一個靈活的系統,允許您按照自己想要的方式配置 K8s 中的資源。
總而言之,對於我們個人來說,為每個數據庫啟動單獨的圖表似乎不是最好的方法。 所以我們開始尋找替代方案。
2. Crunchy Data PostgreSQL 操作符
Crunchy Data PostgreSQL Operator 架構也滿足規定的要求:
管理是通過實用程序 pgo
然而,它反過來又為 Kubernetes 生成自定義資源。 因此,運營商讓我們作為潛在用戶感到高興:
- 通過CRD進行控制;
- 方便的用戶管理(也可以通過CRD);
- 與其他組件集成
脆脆的數據容器套件 - PostgreSQL 容器映像的專門集合以及使用它的實用程序(包括 pgBackRest、pgAudit、contrib 的擴展等)。
然而,嘗試開始使用 Crunchy Data 中的運算符發現了幾個問題:
- 不存在容忍的可能性——僅提供了nodeSelector。
- 儘管我們正在部署有狀態應用程序,但創建的 Pod 是部署的一部分。 與 StatefulSet 不同,Deployments 無法創建磁盤。
最後一個缺陷導致了有趣的時刻:在測試環境中,我們設法用一個磁盤運行 3 個副本 本地存儲,結果操作員報告 3 個副本正在工作(儘管事實並非如此)。
該操作員的另一個特點是它與各種輔助系統的現成集成。 例如,安裝 pgAdmin 和 pgBounce 很容易,並且在
然而,Kubernetes 生成的資源的奇怪選擇導致我們找到了不同的解決方案。
3. Zalando Postgres 操作員
Zalando 產品早已為我們所知:我們有使用 Zalenium 的經驗,當然,我們也嘗試過
這是本文中討論的最年輕的解決方案:第一次發佈於 2018 年 1300 月。 然而,儘管正式發布的版本數量很少,但該項目已經取得了長足的進步,已經超越了Crunchy Data 解決方案的受歡迎程度,在GitHub 上擁有70 多顆星,貢獻者數量最多(XNUMX+) 。
該操作員的“幕後”使用了經過時間考驗的解決方案:
以下是 Zalando 的操作架構的呈現方式:
Operator 通過自定義資源進行完全管理,自動從容器創建 StatefulSet,然後可以通過向 pod 添加各種 sidecar 來對其進行自定義。 與 Crunchy Data 的運算符相比,所有這些都是一個顯著的優點。
由於我們在考慮的 3 個選項中選擇了 Zalando 的解決方案,因此下面將立即介紹其功能的進一步描述以及應用實踐。
與 Zalando 的 Postgres Operator 一起練習
Operator 部署非常簡單:只需從 GitHub 下載最新版本並應用目錄中的 YAML 文件
安裝後,您應該注意設置 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 個實例組成的集群,其中邊車的形式如下
值得關注 用於管理的網絡面板 -
PostgreSQL 集群列表
備份管理
另一個有趣的功能是支持
問題及解決方案
然而,該運算符的使用很快就暴露出幾個顯著的缺點:
- 缺乏節點選擇器支持;
- 無法禁用備份;
- 使用create bases功能時,不出現默認權限;
- 有時沒有足夠的文檔或者已經過時。
幸運的是,其中許多問題都可以得到解決。 讓我們從最後開始 - 問題 文檔.
您很可能會遇到這樣一個事實:並不總是清楚如何註冊備份以及如何將備份存儲桶連接到操作員 UI。 文檔中順便提到了這一點,但真正的描述在
- 你需要保守秘密;
- 將其作為參數傳遞給操作員
pod_environment_secret_name
在帶有操作員設置的 CRD 中或在 ConfigMap 中(取決於您選擇安裝操作員的方式)。
然而,事實證明,目前這是不可能的。 這就是為什麼我們收集了
如果將參數傳遞給操作員進行備份,即 - wal_s3_bucket
並訪問AWS S3中的密鑰,然後它 將備份所有內容:不僅是生產基地,還有演出基地。 它不適合我們。
在使用操作符時對 Spilo(PgSQL 的基本 Docker 包裝器)的參數的描述中,結果表明您可以傳遞參數 WAL_S3_BUCKET
空,從而禁用備份。 此外,令我非常高興的是,我發現 enableWALArchiving: false
到 PostgreSQL 集群資源。
是的,可以通過運行 2 個操作員來實現不同的目的:一個用於暫存(沒有備份),第二個用於生產。 但我們還是能應付得來。
好的,我們已經學習瞭如何將對 S3 的訪問轉移到數據庫,並且備份開始進入存儲。 如何使備份頁面在 Operator UI 中工作?
在 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
創建角色時,不應用默認權限。 我們正在準備補丁,以便自動應用這些權利。
與我們相關的改進的最後一刻 -
怎麼了?
為了解決上述問題,我們將 Postgres Operator 從 Zalando 分叉為
分叉中接受的 PR 列表:
如果社區支持這些 PR,以便他們能夠在下一版本的操作符 (1.6) 中上游,那就太好了。
獎金! 生產遷移成功案例
如果您使用 Patroni,現場製作可以在最少的停機時間內轉移給操作員。
Spilo 允許您通過 S3 存儲創建備用集群
PostgreSQL 邏輯複製可以解決這個問題。 不過,我們不會詳細介紹如何創建出版物和訂閱,因為……我們的計劃失敗了。
事實上,數據庫有幾個已加載的表,其中包含數百萬行,而且這些表不斷被補充和刪除。 copy_data
,當新副本從主副本複制所有內容時,它只是無法跟上主副本。 內容複製工作了一周,但始終追不上大師。 最終幫助解決了問題 pg_dump
。 我將描述我們的(稍作修改的)版本的算法。
這個想法是,您可以將禁用的訂閱綁定到特定的複制槽,然後修復事務號。 有用於生產工作的複製品。 這很重要,因為副本將幫助創建一致的轉儲並繼續接收來自主服務器的更改。
描述遷移過程的後續命令將使用以下主機表示法:
- 主 — 源服務器;
- 副本1 - 舊作品的流媒體複製品;
- 副本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. 禁用複制後,您需要修復序列。 描述得很好
由於這個計劃,切換以最小的延遲完成。
結論
Kubernetes Operator 允許您通過減少創建 K8s 資源來簡化各種操作。 然而,在他們的幫助下實現了顯著的自動化後,值得記住的是,它也可能帶來許多意想不到的細微差別,因此請明智地選擇操作員。
在審查了 PostgreSQL 的三個最受歡迎的 Kubernetes 運算符後,我們選擇了 Zalando 的項目。 我們必須克服一些困難,但結果確實令人高興,因此我們計劃將這種體驗擴展到 PgSQL 的其他一些安裝中。 如果您有使用類似解決方案的經驗,我們將很高興在評論中看到詳細信息!
聚苯乙烯
另請閱讀我們的博客:
- «
數據庫和 Kubernetes(概述和視頻報告) “; - «
Postgres 星期二 #5:PostgreSQL 和 Kubernetes。 持續集成/持續交付。 測試自動化 “; - «
關於 K8s 中的 Redis 操作員的一個故事以及用於分析該數據庫中的數據的實用程序的簡短回顧 “。
來源: www.habr.com