使用 bitnami/postgresql-repmgr 映象快速設定 PostgreSQL HA

為少發表於2022-04-23

image

什麼是 PostgreSQL HA?

此 PostgreSQL 叢集解決方案包括 PostgreSQL 複製管理器(replication manager),這是一種用於管理 PostgreSQL 叢集上的複製(replication)和故障轉移(failover)的開源工具。

獲取此映象

獲取 Bitnami PostgreSQL HA Docker 映象的推薦方法是從 Docker Hub Registry 中提取預構建的映象。

$ docker pull bitnami/postgresql-repmgr:latest

要使用特定版本,您可以拉取版本化標籤。 您可以在 Docker Hub Registry 中檢視可用版本的列表

$ docker pull bitnami/postgresql-repmgr:[TAG]

如果您願意,您也可以自己構建映象。

$ docker build -t bitnami/postgresql-repmgr:latest 'https://github.com/bitnami/bitnami-docker-postgresql-repmgr.git#master:14/debian-10'

持久化您的應用程式

如果刪除容器,所有資料都將丟失,下次執行映象時,資料庫將重新初始化。 為避免這種資料丟失,您應該掛載一個即使在容器被刪除後仍將持續存在的卷。

對於永續性,您應該在 /bitnami/postgresql 路徑上掛載一個目錄。 如果掛載的目錄是空的,它將在第一次執行時被初始化。

$ docker run \
    -v /path/to/postgresql-repmgr-persistence:/bitnami/postgresql \
    bitnami/postgresql-repmgr:latest

此儲存庫中的 docker-compose.yml 檔案已經配置了永續性。

注意:由於這是一個非 root 容器,因此掛載的檔案和目錄必須具有 UID 1001 的適當許可權。

連線到其他容器

使用 Docker 容器網路,您的應用程式容器可以輕鬆訪問在容器內執行的 PostgreSQL 伺服器,反之亦然。

連線到同一網路的容器可以使用容器名稱作為主機名相互通訊。

使用命令列

在此示例中,我們將建立一個 PostgreSQL 客戶端例項,該例項將連線到與客戶端在同一 docker 網路上執行的伺服器例項。

Step 1: 建立 network

$ docker network create my-network --driver bridge

Step 2: 在您的 network 中啟動 postgresql-repmgr 容器

使用 docker run 命令的 --network <NETWORK> 引數將容器附加到 my-network 網路。

$ docker run --detach --rm --name pg-0 \
  --network my-network \
  --env REPMGR_PARTNER_NODES=pg-0 \
  --env REPMGR_NODE_NAME=pg-0 \
  --env REPMGR_NODE_NETWORK_NAME=pg-0 \
  --env REPMGR_PRIMARY_HOST=pg-0 \
  --env REPMGR_PASSWORD=repmgrpass \
  --env POSTGRESQL_PASSWORD=secretpass \
  bitnami/postgresql-repmgr:latest

Step 3: 執行你的 PostgreSQL client 例項

最後,我們建立一個新的容器例項來啟動 PostgreSQL client 並連線到上一步中建立的伺服器:

$ docker run -it --rm \
  --network my-network \
  bitnami/postgresql:10 \
  psql -h pg-0 -U postgres

使用 Docker Compose

如果未指定,Docker Compose 會自動設定一個新網路並將所有已部署的服務附加到該網路。 但是,我們將明確定義一個名為 my-network 的新 bridge 網路。 在此示例中,我們假設您希望從您自己的自定義應用程式映象連線到 PostgreSQL 伺服器,該映象在以下程式碼段中由服務名稱 myapp 標識。

version: '2'

networks:
  my-network:
    driver: bridge

services:
  pg-0:
    image: 'bitnami/postgresql-repmgr:latest'
    networks:
      - my-network
    environment:
      - POSTGRESQL_PASSWORD=custompassword
      - REPMGR_PASSWORD=repmgrpassword
      - REPMGR_PRIMARY_HOST=pg-0
      - REPMGR_NODE_NETWORK_NAME=pg-0
      - REPMGR_NODE_NAME=pg-0
      - REPMGR_PARTNER_NODES=pg-0
  myapp:
    image: 'YOUR_APPLICATION_IMAGE'
    networks:
      - my-network

重要的:

  1. 請使用您的應用程式映象更新上述程式碼段中的 YOUR_APPLICATION_IMAGE 佔位符
  2. 在您的應用程式容器中,使用主機名 pg-0 連線到 PostgreSQL 伺服器

使用以下命令啟動容器:

$ docker-compose up -d

配置

初始化一個新例項

第一次執行容器時,它將執行位於 /docker-entrypoint-initdb.d 的副檔名為 .sh.sql.sql.gz 的檔案。

為了將您的自定義檔案放入 docker 映象中,您可以將它們掛載為卷。

在首次執行時設定 root 和 repmgr 密碼

在上述命令中,您可能已經注意到 POSTGRESQL_PASSWORDREPMGR_PASSWORD 環境變數的使用。 第一次執行映象時傳遞 POSTGRESQL_PASSWORD 環境變數會將 postgres 使用者的密碼設定為 POSTGRESQL_PASSWORD 的值(或 POSTGRESQL_PASSWORD_FILE 中指定的檔案內容)。同樣,傳遞 REPMGR_PASSWORD 環境變數將 repmgr 使用者的密碼設定為 REPMGR_PASSWORD 的值(或 REPMGR_PASSWORD_FILE 中指定的檔案內容)。

$ docker run --name pg-0 --env REPMGR_PASSWORD=repmgrpass --env POSTGRESQL_PASSWORD=secretpass bitnami/postgresql-repmgr:latest

或通過修改此儲存庫中存在的 docker-compose.yml 檔案:

...
services:
  pg-0:
  ...
    environment:
-      - POSTGRESQL_PASSWORD=adminpassword
+      - POSTGRESQL_PASSWORD=password123
-      - REPMGR_PASSWORD=repmgrpassword
+      - REPMGR_PASSWORD=password123
  ...
  pg-1:
  ...
  environment:
-      - POSTGRESQL_PASSWORD=adminpassword
+      - POSTGRESQL_PASSWORD=password123
-      - REPMGR_PASSWORD=repmgrpassword
+      - REPMGR_PASSWORD=password123
...

Note!postgresrepmgr 使用者都是超級使用者,並且對 PostgreSQL 資料庫具有完全的管理訪問許可權。

如果要為 postgres 使用者設定非特權使用者和密碼,請參閱在首次執行時建立資料庫使用者。

首次執行時建立資料庫

通過在第一次執行映象時傳遞 POSTGRESQL_DATABASE 環境變數,將建立一個資料庫。 如果您的應用程式要求資料庫已經存在,這將非常有用,您不必使用 PostgreSQL 客戶端手動建立資料庫。

$ docker run --name pg-0 --env POSTGRESQL_DATABASE=my_database bitnami/postgresql-repmgr:latest

首次執行時建立資料庫使用者

您還可以建立一個受限資料庫使用者,該使用者僅對使用 POSTGRESQL_DATABASE 環境變數建立的資料庫具有許可權。 為此,請提供 POSTGRESQL_USERNAME 環境變數。

$ docker run --name pg-0 --env POSTGRESQL_USERNAME=my_user --env POSTGRESQL_PASSWORD=password123 --env POSTGRESQL_DATABASE=my_database bitnami/postgresql-repmgr:latest

此儲存庫中的 docker-compose.yml 檔案已配置此設定。

Note!指定 POSTGRESQL_USERNAME 時,不會為 postgres 使用者分配密碼,因此您無法以 postgres 使用者身份遠端登入 PostgreSQL 伺服器。如果您仍想使用使用者 postgres 訪問,請設定 POSTGRESQL_POSTGRES_PASSWORD 環境變數(或 POSTGRESQL_POSTGRES_PASSWORD_FILE 中指定的檔案內容)。

使用流複製和 repmgr 設定 HA PostgreSQL 叢集

使用以下環境變數,可以使用 Bitnami PostgreSQL HA Docker 映象輕鬆設定具有[流複製](Streaming replication)和 repmgrHA PostgreSQL 叢集:

  • POSTGRESQL_PASSWORD:postgres 使用者的密碼。沒有預設值。
  • POSTGRESQL_PASSWORD_FILE:包含 postgres 使用者密碼的檔案的路徑。 這將覆蓋 POSTGRESQL_PASSWORD 中指定的值。 沒有預設值。
  • REPMGR_USERNAME:repmgr 使用者的使用者名稱。預設為 repmgr
  • REPMGR_PASSWORD_FILE:包含 repmgr 使用者密碼的檔案的路徑。這將覆蓋 REPMGR_PASSWORD 中指定的值。 沒有預設值。
  • REPMGR_PASSWORD:repmgr 使用者的密碼。沒有預設值。
  • REPMGR_USE_PASSFILE:配置 repmgr 以在其配置中使用 passfilePGPASSFILE 而不是純文字密碼。
  • REPMGR_PASSFILE_PATH:密碼檔案的位置,如果它不存在,它將使用 REPMGR 憑據建立。
  • REPMGR_PRIMARY_HOST:初始主節點的主機名。沒有預設值。
  • REPMGR_PARTNER_NODES:叢集中的夥伴節點的逗號分隔列表。沒有預設值。
  • REPMGR_NODE_NAME:節點名稱。沒有預設值。
  • REPMGR_NODE_NETWORK_NAME:節點主機名。沒有預設值。
  • REPMGR_PGHBA_TRUST_ALL:這將在生成的 pg_hba.conf 中設定 auth-method。僅當您使用帶有 LDAP 身份驗證的 pgpool 時才將其設定為 yes。預設為 no

HA PostgreSQL 叢集中,您可以擁有一個主節點和零個或多個備用節點。主節點處於讀寫模式,而備用節點處於只讀模式。為獲得最佳效能,建議將讀取限制在備用節點。

注意:對於 9.6 版之前的 Postgresql,REPMGR_USE_PASSFILE 和 REPMGR_PASSFILE_PATH 將被忽略。

使用 REPMGR_PASSFILE_PATH 掛載外部密碼檔案時,還需要相應地配置 REPMGR_PASSWORD 和 REPMGR_USERNAME。

Step 1: 建立 network

$ docker network create my-network --driver bridge

Step 2: 建立初始主節點

第一步是啟動初始主節點:

$ docker run --detach --name pg-0 \
  --network my-network \
  --env REPMGR_PARTNER_NODES=pg-0,pg-1 \
  --env REPMGR_NODE_NAME=pg-0 \
  --env REPMGR_NODE_NETWORK_NAME=pg-0 \
  --env REPMGR_PRIMARY_HOST=pg-0 \
  --env REPMGR_PASSWORD=repmgrpass \
  --env POSTGRESQL_PASSWORD=secretpass \
  bitnami/postgresql-repmgr:latest

Step 3: 建立備用節點

接下來我們啟動一個備用節點:

$ docker run --detach --name pg-1 \
  --network my-network \
  --env REPMGR_PARTNER_NODES=pg-0,pg-1 \
  --env REPMGR_NODE_NAME=pg-1 \
  --env REPMGR_NODE_NETWORK_NAME=pg-1 \
  --env REPMGR_PRIMARY_HOST=pg-0 \
  --env REPMGR_PASSWORD=repmgrpass \
  --env POSTGRESQL_PASSWORD=secretpass \
  bitnami/postgresql-repmgr:latest

使用這三個命令,您現在可以啟動並執行一個兩節點 PostgreSQL 主備流複製叢集。 您可以通過新增/刪除備用節點來擴充套件叢集,而不會導致任何停機時間。

注意:叢集會完整地複製主節點,其中包括所有使用者和資料庫。

如果主節點當機,repmgr 將確保任何備用節點擔任主節點,從而保證高可用性。

注意:叢集中其他節點的配置需要更新,以便它們知道它們。這將需要重新啟動舊節點,以適應 REPMGR_PARTNER_NODES 環境變數。

使用 Docker Compose,可以使用此儲存庫中的 docker-compose.yml 檔案設定 HA PostgreSQL 叢集:

$ curl -sSL https://raw.githubusercontent.com/bitnami/bitnami-docker-postgresql-repmgr/master/docker-compose.yml > docker-compose.yml
$ docker-compose up -d

保護 PostgreSQL 流量

PostgreSQL 支援使用 SSL/TLS 協議對連線進行加密。如果您希望啟用此可選功能,您可以使用以下環境變數來配置應用程式:

  • POSTGRESQL_ENABLE_TLS:是否為流量啟用 TLS。預設為 no
  • POSTGRESQL_TLS_CERT_FILE:包含 TLS 流量證照檔案的檔案。沒有預設值。
  • POSTGRESQL_TLS_KEY_FILE:包含證照金鑰的檔案。沒有預設值。
  • POSTGRESQL_TLS_CA_FILE:包含證照 CA 的檔案。如果提供,PostgreSQL 將通過向 TLS/SSL 客戶端請求證照來對其進行身份驗證(請參閱ref)。沒有預設值。
  • POSTGRESQL_TLS_CRL_FILE:包含證照吊銷列表的檔案。沒有預設值。
  • POSTGRESQL_TLS_PREFER_SERVER_CIPHERS:是否使用伺服器的 TLS 密碼首選項而不是客戶端的。預設為 yes

啟用 TLS 時,PostgreSQL 預設支援標準流量和加密流量,但更喜歡後者。下面是一些關於如何快速設定 TLS 流量的示例:

  1. 使用 docker run
$ docker run \
    -v /path/to/certs:/opt/bitnami/postgresql/certs \
    -e POSTGRESQL_ENABLE_TLS=yes \
    -e POSTGRESQL_TLS_CERT_FILE=/opt/bitnami/postgresql/certs/postgres.crt \
    -e POSTGRESQL_TLS_KEY_FILE=/opt/bitnami/postgresql/certs/postgres.key \
    bitnami/postgresql-repmgr:latest
  1. 修改此儲存庫中存在的 docker-compose.yml 檔案:
services:
  pg-0:
  ...
    environment:
      ...
      - POSTGRESQL_ENABLE_TLS=yes
      - POSTGRESQL_TLS_CERT_FILE=/opt/bitnami/postgresql/certs/postgres.crt
      - POSTGRESQL_TLS_KEY_FILE=/opt/bitnami/postgresql/certs/postgres.key
    ...
    volumes:
      ...
      - /path/to/certs:/opt/bitnami/postgresql/certs
  ...

或者,您也可以在自定義配置檔案中提供此配置。

配置檔案

該映象在 /opt/bitnami/repmgr/conf//opt/bitnami/postgresql/conf/ 中查詢 repmgr.confpostgresql.confpg_hba.conf 檔案。您可以在 /bitnami/repmgr/conf/ 掛載一個卷,並複製/編輯 /path/to/custom-conf/ 中的配置檔案。 如果 /bitnami/repmgr/conf/ 為空,預設配置將填充到 conf/ 目錄。

/path/to/custom-conf/
└── postgresql.conf

由於帶有 Replication manager 映象的 PostgreSQL 是非 root 使用者,因此您需要為主機中的掛載目錄設定適當的許可權:

$ sudo chgrp -R root /path/to/custom-conf/
$ sudo chmod -R g+rwX /path/to/custom-conf/

Step 1: 執行 PostgreSQL 映象

執行 PostgreSQL 映象,從您的主機掛載一個目錄。

$ docker run --name pg-0 \
    -v /path/to/custom-conf/:/bitnami/repmgr/conf/ \
    bitnami/postgresql-repmgr:latest

或者使用 Docker Compose

version: '2'

services:
  pg-0:
    image: bitnami/postgresql-repmgr:latest
    ports:
      - '5432:5432'
    volumes:
      - /path/to/custom-conf/:/bitnami/repmgr/conf/
  pg-1:
    image: bitnami/postgresql-repmgr:latest
    ports:
      - '5432:5432'
    volumes:
      - /path/to/custom-conf/:/bitnami/repmgr/conf/

Step 2: 編輯配置

使用您喜歡的編輯器編輯主機上的配置。

vi /path/to/custom-conf/postgresql.conf

Step 3: 重啟 PostgreSQL

更改配置後,重新啟動 PostgreSQL 容器以使更改生效。

$ docker restart pg-0

或者使用 Docker Compose

$ docker-compose restart pg-0
$ docker-compose restart pg-1

有關配置選項的完整列表,請參閱伺服器配置手冊

允許從預設 postgresql.conf 以外的檔案載入設定。

除了使用自定義的 repmgr.confpostgresql.confpg_hba.conf,您還可以在 /bitnami/postgresql/conf/ 的卷中包含 conf.d 目錄中以 .conf 結尾的檔案。為此,預設的 postgresql.conf 包含以下部分:

##------------------------------------------------------------------------------
## CONFIG FILE INCLUDES
##------------------------------------------------------------------------------

## These options allow settings to be loaded from files other than the
## default postgresql.conf.

include_dir = 'conf.d'  # Include files ending in '.conf' from directory 'conf.d'

如果您使用自定義 postgresql.conf,您應該在配置檔案中建立(或取消註釋)上述部分,在這種情況下,結構應該類似於

/path/to/custom-conf/
└── postgresql.conf
/path/to/extra-custom-conf/
└── extended.conf

請記住為主機中的掛載目錄設定適當的許可權:

$ sudo chgrp -R root /path/to/extra-custom-conf/
$ sudo chmod -R g+rwX /path/to/extra-custom-conf/

Step 1: 執行 PostgreSQL 映象

執行 PostgreSQL 映象,從您的主機掛載一個目錄。

$ docker run --name pg-0 \
    -v /path/to/extra-custom-conf/:/bitnami/postgresql/conf/conf.d/ \
    -v /path/to/custom-conf/:/bitnami/repmgr/conf/ \
    bitnami/postgresql-repmgr:latest

或者使用 Docker Compose

version: '2'

services:
  pg-0:
    image: bitnami/postgresql-repmgr:latest
    ports:
      - '5432:5432'
    volumes:
      - /path/to/extra-custom-conf/:/bitnami/postgresql/conf/conf.d/
      - /path/to/custom-conf/:/bitnami/repmgr/conf/
  pg-1:
    image: bitnami/postgresql-repmgr:latest
    ports:
      - '5432:5432'
    volumes:
      - /path/to/extra-custom-conf/:/bitnami/postgresql/conf/conf.d/
      - /path/to/custom-conf/:/bitnami/repmgr/conf/

Step 2: 編輯配置

使用您喜歡的編輯器編輯主機上的配置。

vi /path/to/extra-custom-conf/extended.conf

Step 3: 重啟 PostgreSQL

更改配置後,重新啟動 PostgreSQL 容器以使更改生效。

$ docker restart pg-0

或者使用 Docker Compose:

$ docker-compose restart pg-0
$ docker-compose restart pg-1

環境變數

請在下表中檢視 Bitnami PostgreSQL HA 容器中可用的環境變數列表:

Environment Variable Default value
REPMGR_NODE_ID nil
REPMGR_NODE_ID_START_SEED 1000
REPMGR_NODE_NAME nil
REPMGR_NODE_NETWORK_NAME nil
REPMGR_NODE_PRIORITY 100
REPMGR_PARTNER_NODES nil
REPMGR_PRIMARY_HOST nil
REPMGR_NODE_LOCATION default
REPMGR_PRIMARY_PORT 5432
REPMGR_PORT_NUMBER 5432
REPMGR_LOG_LEVEL NOTICE
REPMGR_START_OPTIONS nil
REPMGR_CONNECT_TIMEOUT 5
REPMGR_RECONNECT_ATTEMPTS 3
REPMGR_RECONNECT_INTERVAL 5
REPMGR_USE_REPLICATION_SLOTS 1
REPMGR_MASTER_RESPONSE_TIMEOUT 20
REPMGR_DEGRADED_MONITORING_TIMEOUT 5
REPMGR_USERNAME repmgr
REPMGR_DATABASE repmgr
REPMGR_PASSWORD nil
REPMGR_PASSWORD_FILE nil
REPMGR_FENCE_OLD_PRIMARY no
REPMGR_CHILD_NODES_CHECK_INTERVAL 5
REPMGR_CHILD_NODES_CONNECTED_MIN_COUNT 1
REPMGR_CHILD_NODES_DISCONNECT_TIMEOUT 30
REPMGR_USE_PASSFILE nil
POSTGRESQL_USERNAME postgres
POSTGRESQL_DATABASE nil
POSTGRESQL_PASSWORD nil
POSTGRESQL_PASSWORD_FILE nil
POSTGRESQL_POSTGRES_PASSWORD nil
POSTGRESQL_POSTGRES_PASSWORD_FILE nil
POSTGRESQL_PORT_NUMBER 5432
POSTGRESQL_INITDB_ARGS nil
POSTGRESQL_PGCTLTIMEOUT 60
POSTGRESQL_SHUTDOWN_MODE fast
POSTGRESQL_ENABLE_TLS no
POSTGRESQL_TLS_CERT_FILE nil
POSTGRESQL_TLS_KEY_FILE nil
POSTGRESQL_TLS_CA_FILE nil
POSTGRESQL_TLS_CRL_FILE nil
POSTGRESQL_TLS_PREFER_SERVER_CIPHERS yes

日誌

Bitnami PostgreSQL HA Docker 映象將容器日誌傳送到 stdout。檢視日誌:

$ docker logs pg-0

如果您希望以不同的方式使用容器日誌,則可以使用 --log-driver 選項配置容器 logging driver。在預設配置中,docker 使用 json-file driver。

維護

升級這個映象

Bitnami 提供了 PostgreSQL HA 的最新版本,包括安全補丁,這些補丁在上游釋出後很快就會發布。我們建議您按照以下步驟升級容器。

Step 1: 獲取更新的映象

$ docker pull bitnami/postgresql-repmgr:latest

或者,如果您使用的是 Docker Compose,請將 image 屬性的值更新為 bitnami/postgresql-repmgr:latest

Step 2: 停止正在執行的容器

使用命令停止當前執行的容器

$ docker stop pg-0

或者使用 Docker Compose:

$ docker-compose stop pg-0
$ docker-compose stop pg-1

接下來,使用以下命令對持久卷 /path/to/postgresql-persistence 進行快照:

$ rsync -a /path/to/postgresql-persistence /path/to/postgresql-persistence.bkp.$(date +%Y%m%d-%H.%M.%S)

Step 3: 移除當前執行的容器

$ docker rm -v pg-0

或者使用 Docker Compose:

$ docker-compose rm -v pg-0
$ docker-compose rm -v pg-1

Step 4: 執行新映象

從新映象重新建立容器。

$ docker run --name pg-0 bitnami/postgresql-repmgr:latest

或者使用 Docker Compose:

$ docker-compose up pg-0
$ docker-compose up pg-1

更多

相關文章