暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【译】pgstef 的博客;;;pgBackRest 和 TLS 连接

原创 剩余价值 2022-05-07
1057

原文作者:Stefan Fercot 于 2022 年2 月 21 日发表

原文链接:https://pgstef.github.io/2022/02/21/pgbackrest_tls_server.html


pgstef 的博客



pgBackRest 和 TLS 连接

Stefan Fercot 于 2022 年2 月 21 日发表。

TLS 服务器是使用 SSH 与远程主机进行协议连接的替代方案。它已于2022 年 1 月 3 日在2.37版本中推送。

在这个演示设置中,存储库主机将被称为backup-srv和Streaming Replication中的 3 个 PostgreSQL 节点: pg1-srvpg2-srvpg3-srv。所有节点都将在 Rocky Linux 8 上运行。

如果你熟悉 Vagrant,这里有一个Vagrantfile使用这些名称启动 4 个虚拟机的简单方法:

# Vagrantfile
Vagrant.configure(2) do |config|
    config.vm.box = 'rockylinux/8'
    config.vm.provider 'libvirt' do |lv|
        lv.cpus = 1
        lv.memory = 1024
    end

    # share the default vagrant folder
    config.vm.synced_folder ".", "/vagrant", type: "nfs"

    nodes  = 'backup-srv', 'pg1-srv', 'pg2-srv', 'pg3-srv'
    nodes.each do |node|
        config.vm.define node do |conf|
            conf.vm.hostname = node
        end
    end
end

安装

在所有服务器上,首先配置 PGDG 存储库:

$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
$ sudo dnf -qy module disable postgresql

然后,在pg1-srvpg2-srvpg3-srv上安装 PostgreSQL :

$ sudo dnf install -y postgresql14-server postgresql14-contrib

在pg1-srv创建一个基本的 PostgreSQL 实例:

$ export PGSETUP_INITDB_OPTIONS="--data-checksums"
$ sudo /usr/pgsql-14/bin/postgresql-14-setup initdb
$ sudo systemctl enable postgresql-14
$ sudo systemctl start postgresql-14

安装 pgBackRest 并检查它的版本:

$ sudo dnf install -y epel-release
$ sudo dnf install -y pgbackrest
$ pgbackrest version
pgBackRest 2.37

在存储库主机上创建专用用户

创建用户以pgbackrest拥有备份和存档存储库。任何用户都可以拥有存储库,但最好不要使用postgres以避免混淆。

在backup-srv上创建用户和存储库位置:

$ sudo groupadd pgbackrest
$ sudo adduser -g pgbackrest -n pgbackrest
$ sudo chown pgbackrest: /var/log/pgbackrest
$ sudo mkdir /backup_space
$ sudo chown pgbackrest: /backup_space

出于本演示的目的,我们创建了/backup_space用于在本地存储我们的备份和存档。存储库可以位于 配置官方文档中描述的各种支持的类型上。


证书生成

TLS 服务器实现依赖于证书。

可以在 此处找到有关如何生成证书并使用它来验证 PostgreSQL 连接的一个很好的实用示例。

基于该示例,让我们生成我们的证书:

$ mkdir certs && cd certs
$ openssl req -new -x509 -days 365 -nodes -out ca.crt -keyout ca.key -subj "/CN=root-ca"
$ openssl req -new -nodes -out backup-srv.csr -keyout backup-srv.key -subj "/CN=backup-srv"
$ openssl req -new -nodes -out pg1-srv.csr -keyout pg1-srv.key -subj "/CN=pg1-srv"
$ openssl req -new -nodes -out pg2-srv.csr -keyout pg2-srv.key -subj "/CN=pg2-srv"
$ openssl req -new -nodes -out pg3-srv.csr -keyout pg3-srv.key -subj "/CN=pg3-srv"
$ openssl x509 -req -in backup-srv.csr -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out backup-srv.crt
$ openssl x509 -req -in pg1-srv.csr -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out pg1-srv.crt
$ openssl x509 -req -in pg2-srv.csr -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out pg2-srv.crt
$ openssl x509 -req -in pg3-srv.csr -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out pg3-srv.crt
$ rm *.csr

然后,您必须在每台服务器上部署它 ( ca.crt++ server_name.crtserver_name.key

这是在 vagrant 主机之间使用共享文件夹的示例:

# on backup-srv
$ sudo -u pgbackrest mkdir ~pgbackrest/certs
$ sudo cp `hostname`.* ~pgbackrest/certs
$ sudo cp ca.crt ~pgbackrest/certs
$ sudo chown -R pgbackrest: ~pgbackrest/certs
$ sudo chmod -R og-rwx ~pgbackrest/certs

# on pg1-srv, pg2-srv and pg3-srv
$ sudo -u postgres mkdir ~postgres/certs
$ sudo cp `hostname`.* ~postgres/certs
$ sudo cp ca.crt ~postgres/certs
$ sudo chown -R postgres: ~postgres/certs
$ sudo chmod -R og-rwx ~postgres/certs

配置

我们现在将为我们的节准备配置,名为demo.

更新backup-srv pgBackRest 配置文件:

# /etc/pgbackrest.conf
[global]
# repo details
repo1-path=/backup_space
repo1-retention-full=2

# general options
process-max=2
log-level-console=info
log-level-file=debug
start-fast=y
delta=y

# tls server options
tls-server-address=*
tls-server-cert-file=/home/pgbackrest/certs/backup-srv.crt
tls-server-key-file=/home/pgbackrest/certs/backup-srv.key
tls-server-ca-file=/home/pgbackrest/certs/ca.crt
tls-server-auth=pg1-srv=demo
tls-server-auth=pg2-srv=demo
tls-server-auth=pg3-srv=demo

[demo]
pg1-host=pg1-srv
pg1-path=/var/lib/pgsql/14/data
pg1-host-type=tls
pg1-host-cert-file=certs/backup-srv.crt
pg1-host-key-file=certs/backup-srv.key
pg1-host-ca-file=certs/ca.crt

更新pg1-srvpg2-srvpg3-srv pgBackRest 配置文件:

# /etc/pgbackrest.conf
[global]
repo1-host=backup-srv
repo1-host-user=pgbackrest
repo1-host-type=tls
repo1-host-cert-file=/var/lib/pgsql/certs/pg1-srv.crt
repo1-host-key-file=/var/lib/pgsql/certs/pg1-srv.key
repo1-host-ca-file=/var/lib/pgsql/certs/ca.crt

# general options
process-max=2
log-level-console=info
log-level-file=debug

# tls server options
tls-server-address=*
tls-server-cert-file=/var/lib/pgsql/certs/pg1-srv.crt
tls-server-key-file=/var/lib/pgsql/certs/pg1-srv.key
tls-server-ca-file=/var/lib/pgsql/certs/ca.crt
tls-server-auth=backup-srv=demo

[demo]
pg1-path=/var/lib/pgsql/14/data

(备注:显然,通过pg2 -srv上的pg2-srvpg3-srv的 pg3-srv 调整 pg1-srv。)

这个想法是在每个主机上运行一个 TLS 服务器来服务来自另一个主机的请求。例如,在backup存储库主机上运行的命令将充当 PostgreSQL 节点上运行的 TLS 服务器的客户端。在 PostgreSQL 节点上运行的archive-push命令将充当存储库主机上运行的 TLS 服务器的客户端。

server命令可用于启动 TLS 服务器并将运行直到被 SIGINT 信号 (Control+C) 终止。

如果 PGDG软件包尚未完成,请在backup-srv服务器 上创建一个服务文件:

# /etc/systemd/system/pgbackrest.service
[Unit]
Description=pgBackRest Server
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
User=pgbackrest
Restart=always
RestartSec=1
ExecStart=/usr/bin/pgbackrest server
ExecReload=kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

启动服务器并检查它是否正在运行:

$ sudo systemctl daemon-reload
$ sudo systemctl enable pgbackrest
$ sudo systemctl start pgbackrest
$ pgbackrest server-ping

server-ping命令仅用作活动性检查,因为没有尝试进行身份验证。

tls-*更改配置时不要忘记终止/重新启动进程。

现在,使用以下配置在pg1-srvpg2-srvpg3-srv上应用相同的步骤(服务配置和启动):

# /etc/systemd/system/pgbackrest.service
[Unit]
Description=pgBackRest Server
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
User=postgres
Restart=always
RestartSec=1
ExecStart=/usr/bin/pgbackrest server
ExecReload=kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

现在,让我们在文件中配置 PostgreSQL 归档postgresql.conf(在pg1-srv上):

listen_addresses = '*'
archive_mode = on
archive_command = 'pgbackrest --stanza=demo archive-push %p'

在进行这些更改之后和执行备份之前,必须重新启动 PostgreSQL 实例。

$ sudo systemctl restart postgresql-14.service

让我们最后创建节并检查backup-srv上的配置:

$ sudo -iu pgbackrest pgbackrest --stanza=demo stanza-create
...
P00   INFO: stanza-create command end: completed successfully

$ sudo -iu pgbackrest pgbackrest --stanza=demo check
...
P00   INFO: check command end: completed successfully

执行备份

如果一切正常,我们现在可以进行第一次备份:

$ sudo -iu pgbackrest pgbackrest --stanza=demo --type=full backup
P00   INFO: backup command begin 2.37: ..
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested
                                                             immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000003, lsn = 0/3000028
P00   INFO: check archive for prior segment 000000010000000000000002
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000003, lsn = 0/3000100
P00   INFO: check archive for segment(s) 000000010000000000000003:000000010000000000000003
P00   INFO: new backup label = 20220218-080535F
P00   INFO: full backup size = 25.2MB, file total = 951
P00   INFO: backup command end: completed successfully

info然后可以从正确配置 pgBackRest 的任何服务器执行该命令:

# From the PostgreSQL node
$ sudo -iu postgres pgbackrest --stanza=demo info
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (14): 000000010000000000000001/000000010000000000000003

        full backup: 20220218-080535F
            timestamp start/stop: 2022-02-18 08:05:35 / 2022-02-18 08:05:42
            wal start/stop: 000000010000000000000003 / 000000010000000000000003
            database size: 25.2MB, database backup size: 25.2MB
            repo1: backup set size: 3.2MB, backup size: 3.2MB

# From the backup server
$ sudo -iu pgbackrest pgbackrest --stanza=demo info
stanza: demo
    status: ok
    cipher: none

    db (current)
        wal archive min/max (14): 000000010000000000000001/000000010000000000000003

        full backup: 20220218-080535F
            timestamp start/stop: 2022-02-18 08:05:35 / 2022-02-18 08:05:42
            wal start/stop: 000000010000000000000003 / 000000010000000000000003
            database size: 25.2MB, database backup size: 25.2MB
            repo1: backup set size: 3.2MB, backup size: 3.2MB

为流复制准备服务器

pg1-srv上,为复制创建一个特定用户:

$ sudo -iu postgres psql
postgres=# CREATE ROLE replic_user WITH LOGIN REPLICATION PASSWORD 'mypwd';

配置pg_hba.conf

host   replication   replic_user   pg2-srv   scram-sha-256
host   replication   replic_user   pg3-srv   scram-sha-256

重新加载配置:

$ sudo systemctl reload postgresql-14.service

~postgres/.pgpasspg2-srvpg3-srv上配置:

$ sudo -iu postgres
$ echo "*:*:replication:replic_user:mypwd" >> ~postgres/.pgpass
$ chown postgres: ~postgres/.pgpass
$ chmod 0600 ~postgres/.pgpass

设置备用服务器

调整/etc/pgbackrest.confpg2 -srvpg3-srv以添加recovery-option。这个想法是使用 restore 命令自动配置流复制连接字符串。

recovery-option=primary_conninfo=host=pg1-srv user=replic_user

info然后,通过执行命令确保配置正确。它应该打印与上面相同的输出。

恢复从pg2-srvpg3-srv上的pg1-srv服务器获取的备份:

$ sudo -iu postgres pgbackrest --stanza=demo --type=standby restore
P00   INFO: restore command begin 2.37: ...
P00   INFO: repo1: restore backup set 20220218-080535F, recovery will start at ...
P00   INFO: write updated /var/lib/pgsql/14/data/postgresql.auto.conf
P00   INFO: restore global/pg_control
(performed last to ensure aborted restores cannot be started)
P00   INFO: restore size = 25.2MB, file total = 951
P00   INFO: restore command end: completed successfully

恢复将向postgresql.auto.conf文件添加额外信息:

# Recovery settings generated by pgBackRest restore on ...
primary_conninfo = 'host=pg1-srv user=replic_user'
restore_command = 'pgbackrest --stanza=demo archive-get %f "%p"'

--type=standby选项创建standby.signalPostgreSQL 在待机模式下启动所需的内容。我们现在要做的就是启动 PostgreSQL 实例:

$ sudo systemctl enable postgresql-14
$ sudo systemctl start postgresql-14

如果复制设置正确,您应该会在pg1-srv服务器上看到这些进程:

# ps -ef |grep postgres
postgres 26108   1 ... /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
postgres 26506 26108 ... postgres: walsender replic_user ... streaming 0/4000CE0
postgres 26507 26108 ... postgres: walsender replic_user ... streaming 0/4000CE0

我们现在有一个 3 节点集群,它使用流复制和存档恢复作为安全网。


从备用服务器进行备份

将以下设置添加到backup-srv上的 pgBackRest 配置文件的[demo]节部分:

pg2-host=pg2-srv
pg2-path=/var/lib/pgsql/14/data
pg2-host-type=tls
pg2-host-cert-file=certs/backup-srv.crt
pg2-host-key-file=certs/backup-srv.key
pg2-host-ca-file=certs/ca.crt
pg3-host=pg3-srv
pg3-path=/var/lib/pgsql/14/data
pg3-host-type=tls
pg3-host-cert-file=certs/backup-srv.crt
pg3-host-key-file=certs/backup-srv.key
pg3-host-ca-file=certs/ca.crt
backup-standby=y

现在,执行备份,从配置中找到的第一个备用服务器获取数据:

$ sudo -iu pgbackrest pgbackrest --stanza=demo --type=full backup
P00   INFO: backup command begin 2.37: ...
P00   INFO: execute non-exclusive pg_start_backup(): backup begins after the requested
                                                             immediate checkpoint completes
P00   INFO: backup start archive = 000000010000000000000005, lsn = 0/5000028
P00   INFO: wait for replay on the standby to reach 0/5000028
P00   INFO: replay on the standby reached 0/5000028
P00   INFO: check archive for prior segment 000000010000000000000004
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL segments to archive
P00   INFO: backup stop archive = 000000010000000000000005, lsn = 0/5000138
P00   INFO: check archive for segment(s) 000000010000000000000005:000000010000000000000005
P00   INFO: new backup label = 20220218-082239F
P00   INFO: full backup size = 25.2MB, file total = 951
P00   INFO: backup command end: completed successfully

结论

TLS 服务器为远程操作提供了 SSH 的替代方案。这项新功能将完美适应容器化世界,在该世界中它可以显着提高性能和用户体验。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论