https://songxwn.com/
简介
Pigsty 是一个更好的本地自建且开源 RDS for PostgreSQL 替代,具有以下特点:
开箱即用的 PostgreSQL 发行版,深度整合地理、时序、分布式、图、向量、分词、AI 等 150 余个扩展插件!
运行于裸操作系统之上,无需容器支持,支持主流操作系统:EL7/8/9 及其衍生发行版,Ubuntu 20.04/22.04 以及 Debian 11/12 。(推荐使用 Rocky Linux)
基于现代的 Prometheus 与 Grafana 技术栈,提供令人惊艳,无可比拟的数据库观测能力:画廊 & 演示站点
基于 patroni, haproxy, 与etcd,打造故障自愈的高可用架构:硬件故障自动切换,流量无缝衔接。
基于 pgBackRest 与可选的 MinIO 集群提供开箱即用的 PITR 时间点恢复,为软件缺陷与人为删库兜底。
基于 Ansible 提供声明式的 API 对复杂度进行抽象,以 Database-as-Code 的方式极大简化了日常运维管理操作。
Pigsty 用途广泛,可用作完整应用运行时,开发演示数据/可视化应用,大量使用 PG 的软件可用 Docker 模板一键拉起。
提供基于 Vagrant 的本地开发测试沙箱环境,与基于 Terraform 的云端自动部署方案,开发测试生产保持环境一致。
部署并监控专用的 Redis(主从,哨兵,集群),MinIO ,Etcd ,Haproxy ,MongoDB (FerretDB ) 集群
官方文档:https://pigsty.cc/doc/#/zh/README
项目地址:https://github.com/Vonng/pigsty
本教程说明
一个非常简单的入门教程,用于构建一个三节点的 PG 集群(开启 VIP ),且支持扩展时序数据库 timescaledb ,主要用于 Zabbix 的后端数据库。
基于 Pigsty 2.5.1 、Rocky Linux 9.3 编写。
安装
初始化元节点(管理监控节点)
准备一个全新的符合要求 的 Linux x86_64 ,使用带有 root 权限或有 sudo 权限的用户执行安装脚本。
(官方推荐使用 Rocky Linux 8.8 ,配置建议 2C4G 100G 硬盘)
curl https://get.pigsty.cc/latest | bash
PS:安装后会移除系统自带 yum 源,建议提前安装所需软件。
该命令会下载并解压 Pigsty 源码至用户 Home ,按提示完成 准备,配置,安装三个步骤即可完成安装。
cd ~/pigsty
# 进入 Pigsty 源码目录,完成后续 准备、配置、安装 三个步骤
./bootstrap
# 确保 Ansible 正常安装,如果存在 /tmp/pkg.tgz 离线软件包,便使用它。
./configure
# 执行环境检测,并生成相应的推荐配置文件,如果你知道如何配置 Pigsty 可以跳过。
./install.yml
# 根据生成的配置文件开始在当前节点上执行安装,使用离线安装包大概需要 10 分钟完成。
# 可以在里面修改默认信息 pigsty.yml ,如域名和默认密码等。
安装完成后,您可以通过域名或 80/443 端口通过 Nginx 访问 WEB 界面,通过 5432 端口访问元节点默认的 PostgreSQL 数据库服务。
IP 地址规划
[td]IP 地址[/td]
[td]主机名[/td]
[td]角色[/td]
172.18.77.33
pg-meta-1
元节点
172.18.77.101
pg-cu1-1
PG 集群主机节点
172.18.77.102
pg-cu1-2
PG 集群主机节点
172.18.77.103
pg-cu1-3
PG 集群主机节点
172.18.77.99
vip
Keepalived 虚拟 IP
PS:Keepalived 集群需要在同一广播域。(其实就是基于 VRRP 协议)
DNS 解析配置
[td]组件[/td]
[td]端口[/td]
[td]域名[/td]
[td]说明[/td]
[td]官方 Demo 地址[/td]
Nginx
80
h.pigsty
Web 服务总入口,本地 YUM 源
home.pigsty.cc
AlertManager
9093
a.pigsty
告警聚合/屏蔽页面
a.pigsty.cc
Grafana
3000
g.pigsty
Grafana 监控面板
demo.pigsty.cc
Prometheus
9090
p.pigsty
Prometheus 管理界面
p.pigsty.cc
你需要修改 hosts 文件,增加以上解析。或者在内网 dns 配置上述解析。解析的 IP 为元节点 IP 即可。
Pigsty 会自动给纳入管理的节点填写 hosts 文件。
172.18.77.33 h.pigsty a.pigsty p.pigsty g.pigsty # pigsty dns
#示例
访问 Web 界面
主页域名为 h.pigsty ,g.pigsty 为 Grafana ,全局应用默认账号密码为 admin/pigsty 。
(如果自己电脑要用浏览器访问,注意配置 DNS 解析或 hosts 文件)
部署三节点 PG 高可用集群
编辑 Pigsty 配置文件,增加主机节点信息
cd ~/pigsty
# 进入 pigsty 主目录,所有操作都在此目录执行。
vim pigsty.yml
# 编辑配置文件,增加三台主节点和集群配置。
增加 PG 集群和 VIP 配置信息
1 、集群名字为 pg-cu1
2 、配置 172.18.77.101 为默认主节点,其他为从节点。
3 、开启 keepalived 配置,配置 VIP 地址为 172.18.22.99 。配置每台关联 VIP 的网卡为 ens33 。(网卡名字注意修改)
4 、此段配置在 children 下增加,与默认的 pg-meta 同级别。
5 、VRRP 的 id 为 35 ,注意不要冲突。
pg-cu1:
hosts:
172.18.77.101: { pg_seq: 1, pg_role: primary }
172.18.77.102: { pg_seq: 2, pg_role: replica }
172.18.77.103: { pg_seq: 3, pg_role: replica }
vars:
pg_cluster: pg-cu1
vip_enabled: true # enable vip on this node cluster?
vip_address: 172.18.77.99 # node vip address in ipv4 format, required if vip is enabled
vip_vrid: 35 # required, integer, 1-254, should be unique among same VLAN
vip_role: backup # optional, `master/backup`, backup by default, use as init role
vip_preempt: true # optional, `true/false`, false by default, enable vip preemption
vip_interface: ens33 # node vip network interface to listen, `eth0` by default
vip_dns_suffix: '' # node vip dns name suffix, empty string by default
vip_exporter_port: 9650 # keepalived exporter listen port, 9650 by default
增加 PG 数据库、用户、HBA 配置。
1 、增加 zabbix 、grafana 数据库,Zabbix 开启 timescaledb 扩展,并配置所属用户。并与 pgbouncer 同步创建。
2 、增加 zabbix 、grafana 用户并配置密码、角色。并与 pgbouncer 同步创建。
3 、配置用户的 HBA 规则,允许任意 IP 访问,并配置 pgbouncer 和 HBA
4 、pg_libs 配置 PG 加载的插件列表,这里加载了 timescaledb 插件。
pg-cu1:
hosts:
172.18.77.101: { pg_seq: 1, pg_role: primary }
172.18.77.102: { pg_seq: 2, pg_role: replica }
172.18.77.103: { pg_seq: 3, pg_role: replica }
vars:
pg_cluster: pg-cu1
pg_databases:
- name: zabbix # 必选,`name` 是数据库定义的唯一必选字段
pgbouncer: true # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
extensions: # 可选,要安装的附加扩展: 扩展对象的数组
- { name: timescaledb } # 例如有的扩展会创建并使用固定的模式,就不需要指定模式。
owner: zabbix # 可选,数据库所有者,默认为 postgres
- name: grafana # 必选,`name` 是数据库定义的唯一必选字段
pgbouncer: true # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
owner: grafana # 可选,数据库所有者,默认为 postgres
pg_users:
- name: zabbix # 数据库用户名,必需,`name` 是用户定义的唯一必选字段
password: Passwd.zabbix # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
pgbouncer: true # 可选,默认为 false ,将此用户添加到 pgbouncer 用户列表
roles: [dbrole_admin]
comment: Zabbix # 可选,此用户/角色的说明与备注字符串
- name: grafana # 数据库用户名,必需,`name` 是用户定义的唯一必选字段
password:
pgbouncer: true # 可选,默认为 false ,将此用户添加到 pgbouncer 用户列表
roles: [dbrole_admin]
comment: grafana # 可选,此用户/角色的说明与备注字符串
pg_hba_rules:
- { user: 'zabbix' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'zabbix 用户不限制登录'}
- { user: 'grafana' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'grafana 用户不限制登录'}
pgb_hba_rules:
- { user: 'zabbix' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'zabbix 用户不限制登录'}
- { user: 'grafana' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'grafana 用户不限制登录'}
pg_libs: 'timescaledb, pg_stat_statements, auto_explain' # 加载时序数据库插件
vip_enabled: true # enable vip on this node cluster?
vip_address: 172.18.77.99 # node vip address in ipv4 format, required if vip is enabled
vip_vrid: 35 # required, integer, 1-254, should be unique among same VLAN
vip_role: backup # optional, `master/backup`, backup by default, use as init role
vip_preempt: true # optional, `true/false`, false by default, enable vip preemption
vip_interface: ens33 # node vip network interface to listen, `eth0` by default
vip_dns_suffix: '' # node vip dns name suffix, empty string by default
vip_exporter_port: 9650 # keepalived exporter listen port, 9650 by default
全部配置展示(仅参考) 用于 Zabbix 服务器的时序数据库
1 、注意全局密码已经修改为 PG-PWD-01
all:
children:
# infra cluster for proxy, monitor, alert, etc..
infra: { hosts: { 172.18.77.33: { infra_seq: 1 } } }
# etcd cluster for ha postgres
etcd: { hosts: { 172.18.77.33: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
# minio cluster, optional backup repo for pgbackrest
#minio: { hosts: { 172.18.77.33: { minio_seq: 1 } }, vars: { minio_cluster: minio } }
# postgres cluster 'pg-meta' with single primary instance
pg-meta:
hosts: { 172.18.77.33: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_databases: [ { name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [ pigsty ] ,extensions: [{name: postgis, schema: public}] }]
pg_users:
- { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [ dbrole_admin ] ,comment: pigsty admin user }
- { name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [ dbrole_readonly ] ,comment: read-only viewer for meta database }
pg_libs: 'pg_stat_statements, auto_explain' # add extra extensions to shared_preload_libraries
node_crontab: [ '00 03 * * * postgres /pg/bin/pg-backup full' ] # make a full backup every 1am
bj-zjy-pg-cu1:
hosts:
172.18.77.101: { pg_seq: 1, pg_role: primary }
172.18.77.102: { pg_seq: 2, pg_role: replica }
172.18.77.103: { pg_seq: 3, pg_role: replica }
vars:
pg_cluster: pg-cu1
pg_databases:
- name: zabbix # 必选,`name` 是数据库定义的唯一必选字段
pgbouncer: true # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
extensions: # 可选,要安装的附加扩展: 扩展对象的数组
- { name: timescaledb } # 例如有的扩展会创建并使用固定的模式,就不需要指定模式。
owner: zabbix # 可选,数据库所有者,默认为 postgres
- name: grafana # 必选,`name` 是数据库定义的唯一必选字段
pgbouncer: true # 可选,是否将此数据库添加到 pgbouncer 数据库列表?默认为 true
owner: grafana # 可选,数据库所有者,默认为 postgres
pg_users:
- name: zabbix # 数据库用户名,必需,`name` 是用户定义的唯一必选字段
password: Passwd.Zabbix # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
pgbouncer: true # 可选,默认为 false ,将此用户添加到 pgbouncer 用户列表
roles: [dbrole_admin]
comment: Zabbix # 可选,此用户/角色的说明与备注字符串
- name: grafana # 数据库用户名,必需,`name` 是用户定义的唯一必选字段
password: Passwd.grafana # 可选,密码,可以是 scram-sha-256 哈希字符串或明文
pgbouncer: true # 可选,默认为 false ,将此用户添加到 pgbouncer 用户列表
roles: [dbrole_admin]
comment: grafana # 可选,此用户/角色的说明与备注字符串
pg_hba_rules:
- { user: 'zabbix' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'zabbix 用户不限制登录'}
- { user: 'grafana' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'grafana 用户不限制登录'}
pgb_hba_rules:
- { user: 'zabbix' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'zabbix 用户不限制登录'}
- { user: 'grafana' ,db: all ,addr: 0.0.0.0/0 ,auth: pwd ,title: 'grafana 用户不限制登录'}
pg_libs: 'timescaledb, pg_stat_statements, auto_explain' # 加载时序数据库插件
vip_enabled: true # enable vip on this node cluster?
vip_address: 172.18.77.99 # node vip address in ipv4 format, required if vip is enabled
vip_vrid: 35 # required, integer, 1-254, should be unique among same VLAN
vip_role: backup # optional, `master/backup`, backup by default, use as init role
vip_preempt: true # optional, `true/false`, false by default, enable vip preemption
vip_interface: ens33 # node vip network interface to listen, `eth0` by default
vip_dns_suffix: '' # node vip dns name suffix, empty string by default
vip_exporter_port: 9650 # keepalived exporter listen port, 9650 by default
vars: # global parameters
version: v2.5.1 # pigsty version string
admin_ip: 172.18.77.33 # admin node ip address
region: china # upstream mirror region: default,china,europe
infra_portal: # domain names and upstream servers
home : { domain: h.pigsty }
grafana : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
prometheus : { domain: p.pigsty ,endpoint: "${admin_ip}:9090" }
alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9093" }
blackbox : { endpoint: "${admin_ip}:9115" }
loki : { endpoint: "${admin_ip}:3100" }
#minio : { domain: sss.pigsty ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
# if you want to use minio as backup repo instead of local fs, uncomment minio related lines
# don't forget to configure pgbackrest_repo and change credentials there!
#pgbackrest_method: minio
# if disabled, original /etc/yum.repos.d will be kept
repo_remove: true # remove existing repo on admin node during repo bootstrap
node_repo_remove: true # remove existing node repo for node managed by pigsty
# WARNING: CHANGE THESE PASSWORDS
#grafana_admin_username: admin
grafana_admin_password: PG-PWD-01
#pg_admin_username: dbuser_dba
pg_admin_password: PG-PWD-01
#pg_monitor_username: dbuser_monitor
pg_monitor_password: PG-PWD-01
#pg_replication_username: replicator
pg_replication_password: PG-PWD-01
#patroni_username: postgres
patroni_password: PG-PWD-01
#haproxy_admin_username: admin
haproxy_admin_password: PG-PWD-01
# this config template assume you are using pre-packed offline packages
# If you wish to download upstream yum packages directly from internet,
# consider using ad hoc `el7.yml`, `el8.yml`, `el9.yml` config instead.
...
配置元节点密钥免密登录主机节点
Pigsty 会在元节点自动生成一对公私钥,将其拷贝到所有主机节点。
ssh-copy-id 172.18.77.101
# 执行后输入 yes ,然后再手动输入主机节点的登录密码即可。
ssh 172.18.77.101
# 确认可直接登录即可,所有主机节点都要操作。
将集群节点纳入 Pigsty 管理并部署 PG 集群
节点纳入管理
bin/node-add pg-cu1
# 将集群 pg-test1 的 3 个主机节点纳入 Pigsty 管理
PG 集群初始化部署(注意:会根据 CPU 内存等配置自动优化 PG 参数,建议提前固定好虚拟机配置)
bin/pgsql-add pg-cu1 # 初始化一个 3 节点的 pg-cu1 可用 PG 集群
# 执行后不到 10 分钟,就将拥有一个服务接入,监控,备份 PITR ,高可用配置齐全的 PostgreSQL 数据库集群。
PG 集群架构图
硬件故障由 patroni 、etcd 和 Haproxy 提供的自愈高可用架构来兜底,在主库故障的情况下,默认会在 30 秒内执行自动故障转移( Failover )。 客户端无需修改配置重启应用:Haproxy 利用 patroni 健康检查进行流量分发,读写请求会自动分发到新的集群主库中,并避免脑裂的问题。 这一过程十分丝滑,例如在从库故障,或主动切换( switchover )的情况下,客户端只有一瞬间的有感知查询闪断。
软件故障、人为错误和 数据中心级灾难由 pgbackrest 和可选的 MinIO 集群来兜底。这为您提供了本地/云端的 PITR 能力,并在数据中心爆炸的情况下提供了跨地理区域复制,与异地容灾功能。
管理和使用
默认用户
Pigsty 也有四个默认用户(系统用户):
超级用户 (postgres),集群的所有者和创建者,与操作系统 dbsu 名称相同。
复制用户 (replicator),用于主-从复制的系统用户。
监控用户 (dbuser_monitor),用于监控数据库和连接池指标的用户。
管理用户 (dbuser_dba),执行日常操作和数据库更改的管理员用户。
这 4 个默认用户的用户名/密码通过 4 对专用参数进行定义,并在很多地方引用:
pg_dbsu:操作系统 dbsu 名称,默认为 postgres ,最好不要更改它
pg_dbsu_password:dbsu 密码,默认为空字符串意味着不设置 dbsu 密码,最好不要设置。
pg_replication_username:postgres 复制用户名,默认为 replicator
pg_replication_password:postgres 复制密码,默认为 DBUser.Replicator
pg_admin_username:postgres 管理员用户名,默认为 dbuser_dba
pg_admin_password:postgres 管理员密码的明文,默认为 DBUser.DBA
pg_monitor_username:postgres 监控用户名,默认为 dbuser_monitor
pg_monitor_password:postgres 监控密码,默认为 DBUser.Monitor
在生产部署中记得更改这些密码,不要使用默认值!
在部署前,可以在 pigsty.yml 里面修改。
配置用户
bin/pgsql-user # pgsql-user.yml -l -e username=
配置 HBA
bin/pgsql-hba # 重新加载指定集群 `` 的 hba 规则
bin/pgsql-hba ip1 ip2... # 重新加载特定实例的 hba 规则
创建数据库
bin/pgsql-db # pgsql-db.yml -l -e dbname=
数据库集群访问端口说明
[td]组件[/td]
[td]端口[/td]
[td]描述[/td]
[td]状态[/td]
[td]备注[/td]
Postgres
5432
Pigsty CMDB
默认启用
Pgbouncer
6432
Pgbouncer 连接池服务
默认启用
Patroni
8008
Patroni 高可用组件
默认启用
Haproxy Primary
5433
主连接池:读/写服务
默认启用
Haproxy Replica
5434
副本连接池:只读服务
默认启用
Haproxy Default
5436
主直连服务*
默认启用
Haproxy Offline
5438
离线直连:离线读服务
默认启用
Haproxy service
543x
PostgreSQL 定制服务
按需定制
Haproxy Admin
9101
监控指标和流量管理
默认启用
PG Exporter
9630
PG 监控指标导出器
默认启用
PGBouncer Exporter
9631
PGBouncer 监控指标导出器
默认启用
Node Exporter
9100
节点监控指标导出器
默认启用
Promtail
9080
收集数据库组件与主机日志
默认启用
vip-manager
-
将 VIP 绑定到主节点
按需启用
Docker Daemon
9323
Docker 守护进程
按需启用
keepalived
-
为整个集群绑定 L2 VIP
按需启用
Keepalived Exporter
9650
Keepalived 指标导出器
按需启用
PS:个人推荐使用 5436 端口,并通过 VIP 地址访问数据库集群。(绕过 pgbouncer )
使用 pgbouncer 则可以使用 5433 端口,并通过 VIP 地址访问集群。
默认管理员账号为 dbuser_dba 。