「在 Kubernetes 上執行 Pgpool-Il」實現 PostgreSQL 查詢(讀)負載均衡和連線池

為少發表於2022-02-28

介紹如何在 Kubernetes 上執行 Pgpool-II 實現 PostgreSQL查詢負載均衡和連線池。

介紹

因為 PostgreSQL 是一個有狀態的應用程式,並且管理 PostgreSQL 有非常具體的要求(例如備份、恢復、自動故障轉移等),Kubernetes 的內建功能無法處理這些任務。 因此,需要一個擴充套件 Kubernetes 功能以建立和管理 PostgreSQLOperator

PostgreSQL operator 有好幾種,比如 Crunchy PostgreSQL OperatorZalando PostgreSQL OperatorKubeDB。但是,這些 operator 不提供查詢負載均衡功能。

結合 PostgreSQL OperatorPgpool-IIKubernetes 上部署具有查詢負載均衡和連線池能力的 PostgreSQL 叢集。Pgpool-II 可以與上面提到的任何 PostgreSQL Operator 結合使用。

架構

前提條件

在開始配置過程之前,請檢查以下前提條件。

  • 確保你有一個 Kubernetes 叢集,並且安裝了 kubectl
  • PostgreSQL OperatorPostgreSQL cluster 已安裝。

部署 Pgpool-II

Kubernetes 不需要 Pgpool-II 的健康檢查、自動故障轉移、watchdog 和線上恢復功能。 您只需要啟用負載平衡和連線池。

Pgpool-II pod 應該使用以下最低配置:

backend_hostname0 = '<primary service name>'
backend_hostname1 = '<replica service name>'
backend_port0 = '5432'
backend_port1 = '5432'
backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 = 'DISALLOW_TO_FAILOVER'

failover_on_backend_error = off

sr_check_period = 10                         (when using streaming replication check)
sr_check_user='username of PostgreSQL user'  (when using streaming replication check)

load_balance_mode = on
connection_cache = on
listen_addresses = '*'

有兩種配置 Pgpool-II 的方法。

  1. 使用環境變數
  2. 使用 ConfigMap

您可能需要在生產環境中配置客戶端身份驗證和更多引數。在生產環境中,我們建議使用 ConfigMap 來配置 pgpool.confpool_hba.conf

使用環境變數配置 Pgpool-II

Kubernetes 環境變數可以傳遞給 pod 中的容器。您可以在部署清單中定義環境變數來配置 Pgpool-II 的引數。pgpool-deploy-minimal.yaml 是一個示例清單,包括環境變數的最小設定。您可以下載 pgpool-deploy-minimal.yaml 並修改此清單中的環境變數。

$ curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy-minimal.yaml

PGPOOL_PARAMS_ 開頭的環境變數可以轉換為 Pgpool-II 的配置引數,這些值可以覆蓋預設設定。

Kubernetes 上,您只需要指定兩個後端節點。根據您的 PostgreSQL 叢集資訊更新 pgpool-deploy-minimal.yaml。將主服務名稱指定為 backend_hostname0。將副本服務名稱指定為 backend_hostname1。因為故障轉移由 Kubernetes 管理,所以將 DISALLOW_TO_FAILOVER 標誌指定給兩個節點的 backend_flag,並將 ALWAYS_PRIMARY 標誌指定給 backend_flag0。 backend_data_directory 的設定不是必需的。

例如,清單中定義的以下環境變數,

env:
- name: PGPOOL_PARAMS_BACKEND_HOSTNAME0
  value: "mypostgres"
- name: PGPOOL_PARAMS_BACKEND_HOSTNAME1
  value: "mypostgres-replica"
- name: PGPOOL_PARAMS_BACKEND_FLAG0
  value: "ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER"
- name: PGPOOL_PARAMS_BACKEND_FLAG1
  value: "DISALLOW_TO_FAILOVER"

將在 pgpool.conf 中轉換為以下配置引數。

backend_hostname0 = 'mypostgres'
backend_hostname1 = 'mypostgres-replica'
backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 = 'DISALLOW_TO_FAILOVER'

然後,您需要定義包含 PostgreSQL 使用者的使用者名稱和密碼的環境變數,用於客戶端身份驗證。

配置清單後,執行以下命令部署 Pgpool-II

kubectl apply -f pgpool-deploy-minimal.yaml

使用 ConfigMap 配置 Pgpool-II

或者,您可以使用 Kubernetes ConfigMap 來儲存整個 pgpool.confpool_hba.confConfigMap 可以作為卷掛載到 Pgpool-II 的容器中。

您可以從以下儲存庫下載定義 ConfigMapDeployment 的示例清單檔案。

curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-configmap.yaml
curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy.yaml

定義 ConfigMap 的清單採用以下格式。您可以根據您的配置偏好對其進行更新。要使用 pool_hba.conf 進行客戶端身份驗證,您需要開啟 enable_pool_hba。 預設為關閉。

apiVersion: v1
kind: ConfigMap
metadata:
  name: pgpool-config
  labels:
    name: pgpool-config
data:
  pgpool.conf: |-
    listen_addresses = '*'
    port = 9999
    socket_dir = '/var/run/pgpool'
    pcp_listen_addresses = '*'
    pcp_port = 9898
    pcp_socket_dir = '/var/run/pgpool'
    backend_hostname0 = 'postgres'
...
  pool_hba.conf: |-
    local   all         all                               trust
    host    all         all         127.0.0.1/32          trust
    host    all         all         ::1/128               trust
    hostssl all         all         0.0.0.0/0             md5

然後,您需要定義包含 PostgreSQL 使用者的使用者名稱和密碼的環境變數,用於客戶端身份驗證。

執行以下命令建立 ConfigMap 並部署引用此 ConfigMapPgpool-II pod。

kubectl apply -f pgpool-configmap.yaml
kubectl apply -f pgpool-deploy.yaml

部署 Pgpool-II 後,您可以使用 kubectl get podkubectl get svc 命令檢視 Pgpool-II pod 和服務。

Pgpool-II 配置

後端設定

Kubernetes 上,您只需要指定兩個後端節點。指定主服務名稱為 backend_hostname0,副本服務名稱為 ackend_hostname1

backend_hostname0 = '<primary service name>'
backend_hostname1 = '<replica service name>'
backend_port0 = '5432'
backend_port1 = '5432'

自動故障轉移

Pgpool-II 能夠定期連線到已配置的 PostgreSQL 後端並檢查 PostgreSQL 的狀態。 如果檢測到錯誤,Pgpool-II 將觸發故障轉移。在 Kubernetes 上,Kubernetes 會監控 PostgreSQLPod,如果一個 Pod 當機,Kubernetes 會重啟一個新的 Pod。您需要禁用 Pgpool-II 的自動故障轉移,因為 Kubernetes 不需要 Pgpool-II 的自動故障轉移。

PostgreSQL node 0 指定為主節點 (ALWAYS_PRIMARY),因為即使主節點或副本 pod 擴充套件、重新啟動或發生故障轉移,服務名稱也不會更改。

backend_flag0 ='ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 ='DISALLOW_TO_FAILOVER'
failover_on_backend_error = off

將密碼註冊到 pool_passwd

Pgpool-II 使用包含 PostgreSQL 使用者密碼的 pool_passwd 檔案執行身份驗證。

Pgpool-II pod 啟動時,Pgpool-II 自動執行 pg_md5 命令,根據 <some string>_USERNAME<some string>_PASSWORD 格式定義的環境變數生成 pool_passwd

代表 PostgreSQL 使用者的使用者名稱和密碼的環境變數必須按以下格式定義:

username: <some string>_USERNAME
password: <some string>_PASSWORD

使用 Secret 定義環境變數是保證使用者憑據安全的推薦方法。在大多數 PostgreSQL Operators 中,建立 PostgreSQL 叢集時會自動建立幾個定義 PostgreSQL 使用者憑據的 Secret。 使用 kubectl get secret 命令檢查現有的 Secret

例如,建立 mypostgres-postgres-secret 來儲存 postgres 使用者的使用者名稱和密碼。 要引用這個 secret,您可以定義如下環境變數:

env:
- name: POSTGRES_USERNAME
  valueFrom:
     secretKeyRef:
       name: mypostgres-postgres-secret
       key: username
- name: POSTGRES_PASSWORD
  valueFrom:
     secretKeyRef:
       name: mypostgres-postgres-secret
       key: password

啟動 Pgpool-II pod 時,會在 /opt/pgpool-II/etc 下自動生成 pool_passwdpcp.conf

$ kubectl exec <pgpool pod> -it -- cat /opt/pgpool-II/etc/pool_passwd
postgres:md53175bce1d3201d16594cebf9d7eb3f9d

$ kubectl exec <pgpool pod> -it -- cat /opt/pgpool-II/etc/pcp.conf
postgres:e8a48653851e28c69d0506508fb27fc5

流複製檢查

Pgpool-II 能夠定期連線到已配置的 PostgreSQL 後端並檢查複製延遲。要使用此功能,需要 sr_check_usersr_check_password。如果 sr_check_password 留空,Pgpool-II 將嘗試從 pool_passwd 獲取 sr_check_user 的密碼。

下面是一個使用 postgres 使用者每隔 10 秒連線到 PostgreSQL 以執行流式複製檢查的示例。因為 sr_check_password 留空,所以 Pgpool-II 會從 pool_passwd 中獲取 postgres 使用者的密碼。

sr_check_period = 10
sr_check_user='postgres'

建立 secret 儲存 sr_check_user 中指定的 PostgreSQL 使用者的使用者名稱和密碼,並配置環境變數以引用建立的 Secret。 在大多數 PostgreSQL Operators 中,建立 PostgreSQL 叢集時會自動建立幾個定義 PostgreSQL 使用者憑據的 secret。使用 kubectl get secret 命令檢查現有的 secret

例如,下面的環境變數引用了 Secret mypostgres-postgres-secret

env:
- name: POSTGRES_USERNAME
  valueFrom:
     secretKeyRef:
       name: mypostgres-postgres-secret
       key: username
- name: POSTGRES_PASSWORD
  valueFrom:
     secretKeyRef:
       name: mypostgres-postgres-secret
       key: password

但是,在 Kubernetes 上,Pgpool-II 連線到任何副本,而不是連線到所有副本。 即使有多個副本,Pgpool-II 也將它們作為一個副本進行管理。因此,Pgpool-II 可能無法正確確定複製延遲。要禁用此功能,請配置以下引數:

sr_check_period = 0

SSL 設定

開啟 ssl 以啟用 SSL 連線。

ssl = on

ssl = on 時,在 Pgpool-II 啟動時,會在 /opt/pgpool-II/certs/ 下自動生成私鑰檔案和證書檔案。 ssl_keyssl_cert 會自動配置私鑰檔案和證書檔案的路徑。

此外,要僅允許 SSL 連線,請將以下記錄新增到 pool_hba.conf 中。

hostssl    all         all         0.0.0.0/0             md5

帶監控的 Pgpool-II

Pgpool-II ExporterPgpool-II 指標的 Prometheus 匯出器。

示例清單 pgpool-deploy-metrics.yaml 用於在 Pgpool-II Pod 中部署 Pgpool-II 容器和 Pgpool-II Exporter 容器。

spec:
  containers:
  - name: pgpool
    image: pgpool/pgpool
  ...
  - name: pgpool-stats
    image: pgpool/pgpool2_exporter
  ...

下載示例清單 pgpool-deploy-metrics.yaml

$ curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy-metrics.yaml

然後,配置 Pgpool-IIPgpool-II Exporter。以下是 Pgpool-II Exporter 容器中用於連線 Pgpool-II 的環境變數的設定。

env:
- name: POSTGRES_USERNAME
  valueFrom:
    secretKeyRef:
      name: mypostgres-postgres-secret
      key: username
- name: POSTGRES_PASSWORD
  valueFrom:
    secretKeyRef:
      name: mypostgres-postgres-secret
      key: password
- name: PGPOOL_SERVICE
  value: "localhost"
- name: PGPOOL_SERVICE_PORT
  value: "9999"

配置 Pgpool-IIPgpool-II Exporter 後,部署 Pgpool-II Pod

kubectl apply -f pgpool-configmap.yaml
kubectl apply -f pgpool-deploy-metrics.yaml

更多

雲原生 PostgreSQL - CrunchyData PGO 教程:建立、連線、刪除 Postgres 叢集

相關文章