猪圈 Pigsty-PG 私有 RDS 集群搭建教程

271 天前
 Songxwn

博客

https://songxwn.com/

简介

Pigsty 是一个更好的本地自建且开源 RDS for PostgreSQL 替代,具有以下特点:

官方文档: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 地址规划

IP 地址 主机名 角色
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 解析配置

组件 端口 域名 说明 官方 Demo 地址
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 也有四个默认用户(系统用户):

这 4 个默认用户的用户名/密码通过 4 对专用参数进行定义,并在很多地方引用:

在生产部署中记得更改这些密码,不要使用默认值! 在部署前,可以在 pigsty.yml 里面修改。

配置用户

bin/pgsql-user <cls> <username>    # pgsql-user.yml -l <cls> -e username=<username>

配置 HBA

bin/pgsql-hba <cls>                 # 重新加载指定集群 `<cls>` 的 hba 规则
bin/pgsql-hba <cls> ip1 ip2...      # 重新加载特定实例的 hba 规则

创建数据库

bin/pgsql-db <cls> <dbname>    # pgsql-db.yml -l <cls> -e dbname=<dbname>

数据库集群访问端口说明

组件 端口 描述 状态 备注
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 。

1988 次点击
所在节点    程序员
3 条回复
defunct9
271 天前
以前启用了 postgres 的 timescale 时序功能,把 prometheus 的时序信息保存到 postgres 做长期备份,本地 prometheus 的只保留 1 个月,结果磁盘占用量 postgres 过大了,随放弃。
coinbase
259 天前
为什么不用 Docker 容器化呢?
coinbase
259 天前
coinbase@MacBook-Pro ~/pigsty> ./bootstrap

bootstrap pigsty v2.5.1 begin
[ OK ] region = china
[FAIL] kernel = Darwin, not supported, Linux only

macOS 上测试都没法测试😂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1016150

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX