跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

管理预案

基础设施组件与 Infra 集群管理 SOP:创建,销毁,扩容,缩容,证书,仓库……

本章节介绍 Pigsty 部署的日常管理和运维操作。

1 - Nginx 管理

Nginx 管理,Web 门户配置,Web Server,暴露上游服务

Pigsty 在 INFRA 节点上安装 Nginx 作为所有 Web 服务的入口,默认监听在 80/443 标准端口上。

在 Pigsty 中,你可以通过修改配置清单,让 nginx 对外提供多种服务:

  • 对外暴露 Grafana、VictoriaMetrics(VMUI)、Alertmanager、VictoriaLogs 等监控组件的 Web 界面
  • 提供静态文件服务(如软件仓库、文档站,网站等)
  • 代理自定义的应用服务(如内部应用、数据库管理界面,Docker 应用的界面等)
  • 自动签发自签名的 HTTPS 证书,或者使用 certbot 申请免费的 Let’s Encrypt 证书
  • 通过不同的子域名,使用单一端口对外暴露服务

基础配置

您可以通过 infra_portal 参数定制 Nginx 的行为:

infra_portal:
  home: { domain: i.pigsty }

infra_portal 是一个字典,每个键定义一个服务,值为服务的配置选项。 只有定义了 domain 的服务才会生成对应的 Nginx 配置文件。

  • home:特殊的默认服务器,用于处理首页和内置监控组件的反向代理
  • 代理服务:通过 endpoint 指定上游服务地址,进行反向代理
  • 静态服务:通过 path 指定本地目录,提供静态文件服务

服务器参数

基本参数

参数 说明
domain 可选的代理域名
endpoint 上游服务地址(IP:PORT 或 socket)
path 静态内容的本地目录
scheme 协议类型(http/https),默认 http
domains 额外的域名列表(别名)

SSL/TLS 选项

参数 说明
certbot 启用 Let’s Encrypt 证书管理,值为证书名称
cert 自定义证书文件路径
key 自定义私钥文件路径
enforce_https 强制跳转 HTTPS(301 重定向)

高级设置

参数 说明
config 自定义 Nginx 配置片段
index 启用目录列表(用于静态服务)
log 自定义日志文件名称
websocket 启用 WebSocket 支持
auth 启用 Basic Auth 认证
realm Basic Auth 认证提示语

配置示例

反向代理服务

grafana: { domain: g.pigsty, endpoint: "${admin_ip}:3000", websocket: true }
pgadmin: { domain: adm.pigsty, endpoint: "127.0.0.1:8885" }

静态文件与目录列表

repo: { domain: repo.pigsty.cc, path: "/www/repo", index: true }

自定义 SSL 证书

secure_app:
  domain: secure.pigsty.cc
  endpoint: "${admin_ip}:8443"
  cert: "/etc/ssl/certs/custom.crt"
  key: "/etc/ssl/private/custom.key"

使用 Let’s Encrypt 证书

grafana:
  domain: demo.pigsty.cc
  endpoint: "${admin_ip}:3000"
  websocket: true
  certbot: pigsty.demo    # 证书名称,多个域名可共用同一证书

强制 HTTPS 跳转

web.io:
  domain: en.pigsty.cc
  path: "/www/web.io"
  certbot: pigsty.doc
  enforce_https: true

自定义配置片段

web.cc:
  domain: pigsty.cc
  path: "/www/web.cc"
  domains: [ zh.pigsty.cc ]
  certbot: pigsty.doc
  config: |
    # rewrite /zh/ to /
        location /zh/ {
            rewrite ^/zh/(.*)$ /$1 permanent;
        }

管理命令

./infra.yml -t nginx           # 完整重新配置 Nginx
./infra.yml -t nginx_config    # 重新生成配置文件
./infra.yml -t nginx_launch    # 重启 Nginx 服务
./infra.yml -t nginx_cert      # 重新生成 SSL 证书
./infra.yml -t nginx_certbot   # 使用 certbot 签发证书
./infra.yml -t nginx_reload    # 重新加载 Nginx 配置

域名解析

有三种方式将域名解析到 Pigsty 服务器:

  1. 公网域名:通过 DNS 服务商配置
  2. 内网 DNS 服务器:配置内部 DNS 解析
  3. 本地 hosts 文件:修改 /etc/hosts

本地开发时,在 /etc/hosts 中添加:

<your_public_ip_address> i.pigsty

Pigsty 内置了 dnsmasq 服务,可以通过 dns_records 参数配置内部 DNS 解析。


HTTPS 配置

通过 nginx_sslmode 参数配置 HTTPS:

模式 说明
disable 仅监听 HTTP(nginx_port
enable 同时监听 HTTPS(nginx_ssl_port),默认签发自签名证书
enforce 强制跳转到 HTTPS,所有 80 端口请求都会 301 重定向

对于自签名证书,有以下几种访问方式:

  • 在浏览器中信任自签名 CA(下载地址 http://<ip>/ca.crt
  • 使用浏览器安全绕过(Chrome 中输入 “thisisunsafe”)
  • 为生产环境配置正规 CA 签发的证书或使用 Let’s Encrypt

Certbot 证书

Pigsty 支持使用 Certbot 申请免费的 Let’s Encrypt 证书。

启用 Certbot

  1. infra_portal 中为服务添加 certbot 参数,指定证书名称
  2. 配置 certbot_email 为有效的邮箱地址
  3. 设置 certbot_signtrue 在部署时自动签发
certbot_sign: true
certbot_email: your@email.com

手动签发证书

./infra.yml -t nginx_certbot   # 签发 Let's Encrypt 证书

或直接运行服务器上的脚本:

/etc/nginx/sign-cert           # 签发证书
/etc/nginx/link-cert           # 链接证书到 Nginx 配置目录

更多信息,请参阅 Certbot:申请与更新 HTTPS 证书


默认首页

Pigsty 的默认首页 home 服务器提供以下内置路由:

路径 说明
/ 首页导航
/zh 中文首页
/ui/ Grafana 监控面板
/vmetrics/ VictoriaMetrics VMUI
/vlogs/ VictoriaLogs 日志查询
/vtraces/ VictoriaTraces 链路追踪
/vmalert/ VMAlert 告警规则
/alertmgr/ AlertManager 告警管理
/blackbox/ Blackbox Exporter
/pev PostgreSQL Explain 可视化工具
/haproxy/<cluster>/ HAProxy 管理界面(如有)

这些路由允许通过单一入口访问所有监控组件,无需配置多个域名。


最佳实践

  • 使用域名而非 IP:PORT 访问服务
  • 正确配置 DNS 解析或 hosts 文件
  • 为实时应用启用 WebSocket(如 Grafana、Jupyter)
  • 生产环境启用 HTTPS
  • 使用有意义的子域名组织服务
  • 监控 Let’s Encrypt 证书过期时间
  • 利用 config 参数添加自定义 Nginx 配置

完整示例

以下是 Pigsty 公开演示站点 demo.pigsty.cc 使用的 Nginx 配置:

infra_portal:
  home         : { domain: i.pigsty }
  cc           : { domain: pigsty.cc      ,path: "/www/pigsty.cc"   ,cert: /etc/cert/pigsty.cc.crt ,key: /etc/cert/pigsty.cc.key }
  minio        : { domain: m.pigsty.cc    ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
  postgrest    : { domain: api.pigsty.cc  ,endpoint: "127.0.0.1:8884" }
  pgadmin      : { domain: adm.pigsty.cc  ,endpoint: "127.0.0.1:8885" }
  pgweb        : { domain: cli.pigsty.cc  ,endpoint: "127.0.0.1:8886" }
  bytebase     : { domain: ddl.pigsty.cc  ,endpoint: "127.0.0.1:8887" }
  jupyter      : { domain: lab.pigsty.cc  ,endpoint: "127.0.0.1:8888" ,websocket: true }
  gitea        : { domain: git.pigsty.cc  ,endpoint: "127.0.0.1:8889" }
  wiki         : { domain: wiki.pigsty.cc ,endpoint: "127.0.0.1:9002" }
  noco         : { domain: noco.pigsty.cc ,endpoint: "127.0.0.1:9003" }
  supa         : { domain: supa.pigsty.cc ,endpoint: "10.10.10.10:8000" ,websocket: true }
  dify         : { domain: dify.pigsty.cc ,endpoint: "10.10.10.10:8001" ,websocket: true }
  odoo         : { domain: odoo.pigsty.cc ,endpoint: "127.0.0.1:8069"   ,websocket: true }
  mm           : { domain: mm.pigsty.cc   ,endpoint: "10.10.10.10:8065" ,websocket: true }

2 - 软件仓库

使用 SOW 创建和维护 Pigsty 本地 RPM/APT 软件仓库,理解完成标记、ModuleMD 与强制重建语义。

Pigsty 的 REPO 角色会下载所需软件包,并在 /www/pigsty 创建可由 Nginx 提供服务的本地 YUM/APT 仓库。当前候选软件包版本为 SOW 0.3.0,源码统一使用 SOW 生成两类仓库元数据,不再分别调用 createrepo_cmodifyrepo_cdpkg-scanpackages


快速开始

将软件包加入 repo_packagesrepo_extra_packages,然后执行:

./infra.yml -t repo_build   # 仅当仓库不存在时下载并构建
./node.yml -t node_repo     # 刷新各节点的软件仓库配置与缓存

如果 /www/pigsty/repo_complete 已存在,默认 repo_build 会跳过构建。需要强制重建时必须显式覆盖:

./infra.yml -t repo_build -e repo_build=true

只重建已有软件包的元数据,不下载新包:

./infra.yml -t repo_create

SOW 前置条件

repo_createcache_create 都要求目标节点上已经安装 sow。全新在线构建会把 infra 自动加入 repo_modules,从 Pigsty INFRA 上游仓库安装 SOW。

早于此次改造的离线包或本地仓库可能不含 SOW。使用旧介质重建前,应先刷新离线包/本地仓库,或从 Pigsty INFRA 仓库安装当前候选的 SOW 0.3.0;不能假定旧环境仍可回退到 createrepo_c

全新安装时,如果 /www 不存在,角色会创建 /data/nginx 并令 /www 指向它;已经存在的目录或符号链接会被保留,不会被强制替换。


构建流程

任务 作用
repo_check 检查 repo_complete,判断本地仓库是否已完成
repo_prepare 配置并使用已有仓库
repo_dir 创建 /www/pigsty 与 ACME 目录
repo_upstream 备份/添加上游 YUM 或 APT 定义
repo_url_pkg 下载 URL 直链软件包
repo_cache 执行 yum makecacheapt update
repo_boot_pkg 安装 sow 以及 RPM 平台所需的 dnf-utils / yum-utils
repo_pkg 下载软件包及依赖
repo_create 执行 SOW,清理并原子发布仓库元数据
repo_use 写入本机的 Pigsty local repo 定义
repo_nginx 在没有现有服务时启动临时 Nginx

repo_create 的实际命令是:

sow create --pigsty --timeout 10m -- /www/pigsty

--pigsty 会清理不需要或容易冲突的软件包,并在元数据完整生成后再原子发布结果。典型结构如下:

/www/pigsty/
├── *.rpm / *.deb
├── repodata/            # RPM 仓库
├── Packages             # APT 仓库
├── Packages.gz
└── repo_complete        # 仓库文件的 SHA-256 校验清单与完成标记

不要把 repo_complete 当作空哨兵文件;它包含 SHA-256 校验内容。该文件存在表示 SOW 已完整发布本地仓库元数据,但不证明远端镜像、签名仓库或离线包已经同步完成。


DNF 模块流

Pigsty 不再为聚合本地仓库伪造 modules.yaml / ModuleMD 元数据。系统上游仓库保留原生 DNF 模块过滤;只有确实需要替代 EL 模块流的软件源,才在 repo_upstreammeta 中显式设置:

- name: example
  module: pgsql
  # ... releases、arch、baseurl ...
  meta: { module_hotfixes: 1 }

Pigsty 聚合本地仓库自身会以 module_hotfixes=1 配置,避免本地 PostgreSQL 软件包被系统模块流隐藏。这与生成虚假的 ModuleMD 是两回事。


软件包别名

默认 repo_packages 使用以下别名组:

[node-bootstrap, infra-package, infra-addons, node-package1,
 node-package2, node-package3, pgsql-utility, extra-modules]

其中 node-bootstrap 包含 Ansible、Python 依赖、SOW 与 SSH 工具;infra-package 包含 Nginx、etcd、HAProxy、Victoria exporters、Redis/Valkey、Silo、mcli、SOW 与 Pig。具体包名会随操作系统映射,始终以 roles/node_id/vars/<os>.<arch>.yml 为准。


常用命令

./infra.yml -t repo                         # 检查、准备或构建,并启动仓库服务
./infra.yml -t repo_check,repo_prepare      # 只检查并使用已有仓库
./infra.yml -t repo_upstream                # 刷新上游仓库定义
./infra.yml -t repo_pkg                     # 下载配置的软件包及依赖
./infra.yml -t repo_create                  # 用 SOW 重建现有目录元数据
./infra.yml -t repo_build -e repo_build=true  # 强制执行完整构建阶段
./infra.yml -t repo_nginx                   # 配置/启动仓库 Nginx
./node.yml -t node_repo                     # 刷新受管节点仓库缓存
./cache.yml                                 # 用 SOW 重建元数据后制作离线包

3 - 域名管理

配置本地或公网域名访问 Pigsty 服务

使用域名代替 IP 地址访问 Pigsty 的各项 Web 服务。


快速开始

将以下静态解析记录添加到 /etc/hosts

10.10.10.10 i.pigsty

将 IP 地址替换为实际 Pigsty 节点的 IP。


为什么使用域名

  • 比 IP 地址更易于记忆
  • 灵活指向不同 IP
  • 通过 Nginx 统一管理服务
  • 支持 HTTPS 加密
  • 防止某些地区的 ISP 劫持
  • 允许通过代理访问内部绑定的服务

DNS 机制

DNS 协议:将域名解析为 IP 地址。多个域名可以指向同一个 IP。

HTTP 协议:使用 Host 头将请求路由到同一端口(80/443)上的不同站点。


默认域名

Pigsty 预定义了以下默认域名:

域名 服务 端口 用途
i.pigsty Nginx 80/443 默认首页、本地仓库与统一入口
m.pigsty Silo 9001 对象存储控制台

Grafana、VictoriaMetrics、Alertmanager 默认通过 i.pigsty 下的 /ui//vmetrics//alertmgr/ 子路径访问。若需要 g.pigstyp.pigstya.pigsty 这类独立域名,请在 infra_portaldns_records 中显式配置。


解析方式

本地静态解析

在客户端机器的 /etc/hosts 中添加条目:

# Linux/macOS
sudo vim /etc/hosts

# Windows
notepad C:\Windows\System32\drivers\etc\hosts

添加内容:

10.10.10.10 i.pigsty m.pigsty

内网动态解析

Pigsty 内置了 dnsmasq 服务作为内网 DNS 服务器。配置被管理的节点使用 INFRA 节点作为 DNS 服务器:

node_dns_servers: ['${admin_ip}']   # 使用 INFRA 节点作为 DNS 服务器
node_dns_method: add                # 将其添加到现有 DNS 服务器列表

通过 dns_records 参数配置 dnsmasq 解析的域名记录:

dns_records:
  - "${admin_ip} i.pigsty"
  - "${admin_ip} m.pigsty supa.pigsty api.pigsty adm.pigsty cli.pigsty ddl.pigsty"

公网域名

购买域名并添加 DNS A 记录指向公网 IP:

  1. 在域名服务商处购买域名(如 example.com
  2. 配置 A 记录指向服务器公网 IP
  3. infra_portal 中使用真实域名

内置 DNS 服务

Pigsty 在 INFRA 节点上运行 dnsmasq 作为 DNS 服务器。

相关参数

参数 默认值 说明
dns_enabled true 是否启用 DNS 服务
dns_port 53 DNS 监听端口
dns_records 见下文 默认 DNS 记录列表

默认的 DNS 记录:

dns_records:
  - "${admin_ip} i.pigsty"
  - "${admin_ip} m.pigsty supa.pigsty api.pigsty adm.pigsty cli.pigsty ddl.pigsty"

动态 DNS 注册

Pigsty 会自动为 PostgreSQL 集群和实例注册 DNS 记录:

  • 实例级 DNS<pg_instance> 指向实例 IP(如 pg-meta-1
  • 集群级 DNS<pg_cluster> 指向主库 IP 或 VIP(如 pg-meta

集群级 DNS 目标由 pg_dns_target 参数控制:

说明
auto 自动选择:有 VIP 用 VIP,否则用主库 IP
primary 始终指向主库 IP
vip 始终指向 VIP(需启用 VIP)
none 不注册集群 DNS
<ip> 指定固定 IP 地址

通过 pg_dns_suffix 可为集群 DNS 添加后缀。


节点 DNS 配置

Pigsty 管理被纳管节点的 DNS 配置。

静态 hosts 记录

通过 node_etc_hosts 配置静态 /etc/hosts 记录:

node_etc_hosts:
  - "${admin_ip} i.pigsty"
  - "${admin_ip} sss.pigsty"      # 可选:Silo S3 接入域名
  - "10.10.10.20 db.example.com"

DNS 服务器配置

参数 默认值 说明
node_dns_method add DNS 配置方式
node_dns_servers ['${admin_ip}'] DNS 服务器列表
node_dns_options 见下文 resolv.conf 选项

node_dns_method 可选值:

说明
add 添加到现有 DNS 服务器列表前面
overwrite 完全覆盖 DNS 服务器配置
none 不修改 DNS 配置

默认的 DNS 选项:

node_dns_options:
  - options single-request-reopen timeout:1

HTTPS 证书

Pigsty 默认使用自签名证书。可选方案包括:

  • 忽略警告,使用 HTTP
  • 信任自签名 CA 证书(下载地址 http://<ip>/ca.crt
  • 使用真实 CA 或通过 Certbot 获取免费公网域名证书

详见 CA 与证书 文档。


扩展域名

Pigsty 扩展预留了以下域名用于各种应用服务:

域名 用途
adm.pigsty PgAdmin 管理界面
ddl.pigsty Bytebase DDL 管理
cli.pigsty PgWeb 命令行界面
api.pigsty PostgREST API 服务
lab.pigsty Jupyter 实验环境
git.pigsty Gitea Git 服务
wiki.pigsty Wiki.js 文档
noco.pigsty NocoDB
supa.pigsty Supabase
dify.pigsty Dify AI
odoo.pigsty Odoo ERP
mm.pigsty Mattermost

使用这些域名需要在 infra_portal 中配置相应的服务。


管理命令

./infra.yml -t dns            # 完整配置 DNS 服务
./infra.yml -t dns_config     # 重新生成 dnsmasq 配置
./infra.yml -t dns_record     # 更新默认 DNS 记录
./infra.yml -t dns_launch     # 重启 dnsmasq 服务

./node.yml -t node_hosts      # 配置节点 /etc/hosts
./node.yml -t node_resolv     # 配置节点 DNS 解析器

./pgsql.yml -t pg_dns         # 注册 PostgreSQL DNS 记录
./pgsql.yml -t pg_dns_ins     # 仅注册实例级 DNS
./pgsql.yml -t pg_dns_cls     # 仅注册集群级 DNS

4 - 模块管理

Infra 模块本身的管理 SOP:定义,创建,销毁,扩容,缩容

本文介绍 INFRA 模块的日常管理操作,包括安装、卸载、扩容、以及各组件的管理维护。


安装 Infra 模块

使用 infra.yml 剧本在 infra 分组上安装 INFRA 模块:

./infra.yml     # 在 infra 分组上安装 INFRA 模块

卸载 Infra 模块

使用 infra-rm.yml 剧本从 infra 分组上卸载 INFRA 模块:

./infra-rm.yml -l infra # 全量移除:注销、停服、删配置/环境/数据并卸载软件包

该剧本没有防误删开关,且全量执行会删除 infra_datanginx_datanginx_home(默认 /www)和 /var/lib/grafana。 如果只需要停止服务或注销目标,应使用 -t service-t deregister;执行前请阅读 移除剧本的完整范围 并备份所需数据。


扩容 Infra 模块

在配置清单中为新节点分配 infra_seq 并加入 infra 分组:

all:
  children:
    infra:
      hosts:
        10.10.10.10: { infra_seq: 1 }  # 原有节点
        10.10.10.11: { infra_seq: 2 }  # 新节点

使用限制选项 -l 仅在新节点上执行剧本:

./infra.yml -l 10.10.10.11    # 在新节点上安装 INFRA 模块

管理本地软件仓库

本地软件仓库相关的管理任务:

./infra.yml -t repo              # 从互联网或离线包创建仓库
./infra.yml -t repo_upstream     # 添加上游仓库
./infra.yml -t repo_pkg          # 下载包及依赖
./infra.yml -t repo_create       # 创建本地 yum/apt 仓库

完整子任务列表:

./infra.yml -t repo_dir          # 创建本地软件仓库
./infra.yml -t repo_check        # 检查本地软件仓库是否存在
./infra.yml -t repo_prepare      # 直接使用已有仓库
./infra.yml -t repo_build        # 从上游构建仓库
./infra.yml -t repo_upstream     # 添加上游仓库
./infra.yml -t repo_remove       # 删除现有仓库文件
./infra.yml -t repo_add          # 添加仓库到系统目录
./infra.yml -t repo_url_pkg      # 从互联网下载包
./infra.yml -t repo_cache        # 创建元数据缓存
./infra.yml -t repo_boot_pkg     # 安装引导包
./infra.yml -t repo_pkg          # 下载包及依赖
./infra.yml -t repo_create       # 创建本地仓库
./infra.yml -t repo_use          # 添加新建仓库到系统
./infra.yml -t repo_nginx        # 启动 nginx 文件服务器

管理 Nginx

Nginx 相关的管理任务:

./infra.yml -t nginx                       # 重置 Nginx 组件
./infra.yml -t nginx_index                 # 重新渲染首页
./infra.yml -t nginx_config,nginx_reload   # 重新渲染配置并重载

申请 HTTPS 证书:

./infra.yml -t nginx_certbot,nginx_reload -e certbot_sign=true

管理基础设施组件

基础设施各组件的管理命令:

./infra.yml -t infra           # 配置基础设施
./infra.yml -t infra_user      # 设置操作系统用户
./infra.yml -t infra_dir       # 创建基础设施目录
./infra.yml -t infra_env       # 配置环境变量
./infra.yml -t infra_pkg       # 安装软件包
./infra.yml -t infra_cert      # 颁发证书
./infra.yml -t dns             # 配置 DNSMasq
./infra.yml -t nginx           # 配置 Nginx
./infra.yml -t victoria        # 配置 VictoriaMetrics/Logs/Traces
./infra.yml -t alertmanager    # 配置 AlertManager
./infra.yml -t blackbox        # 配置 Blackbox Exporter
./infra.yml -t grafana         # 配置 Grafana
./infra.yml -t infra_register  # 注册到 VictoriaMetrics/Grafana

常用维护命令:

./infra.yml -t nginx_index                        # 重新渲染首页
./infra.yml -t nginx_config,nginx_reload          # 重新配置并重载
./infra.yml -t vmetrics_config,vmetrics_launch    # 重新生成 VictoriaMetrics 配置并重启
./infra.yml -t vlogs_config,vlogs_launch          # 更新 VictoriaLogs 配置
./infra.yml -t grafana_provision                  # 重新加载 Grafana 仪表盘与数据源定义

管理 Grafana 密码

Grafana 有两个密码参数:grafana_admin_password(默认 pigsty)和 grafana_view_password(默认 DBUser.Viewer):

参数 渲染到的配置文件
grafana_admin_password /etc/grafana/grafana.ini/infra/env/pigsty
grafana_view_password /etc/grafana/provisioning/datasources/pigsty.yml

这两个密码一旦初始化之后,就只能通过 grafana 界面进行修改。

Pigsty 会在初始化 Grafana 监控面板,注册 Grafana 数据源的时候,使用 grafana_admin_password。 所以如果你通过 Grafana GUI 修改了这个密码,请相应调整配置文件里面的配置。另外,您可以使用以下命令渲染新的密码到环境变量中。

./infra.yml -t env_var            # 重新渲染环境变量

grafana_view_password 是 Grafana 中默认的 Meta PostgreSQL 数据源用户 dbuser_view 的密码。 如果你修改了这个密码,请在 Grafana 数据源管理界面中同步修改密码。

5 - CA 与证书

管理 Pigsty 自签名 CA、服务证书与面向公网的 Certbot 证书。

Pigsty 默认在管理节点维护一套自签名证书颁发机构(CA),为 PostgreSQL、Patroni、etcd、Silo、Nginx 和其他内部服务签发证书。面向公网的 Nginx 入口可以按 infra_portal 配置改用 Certbot/Let’s Encrypt 证书。

保护 CA 私钥

files/pki/ca/ca.key 是整个部署的信任根私钥。不要打印、提交、上传或通过不受保护的渠道传输它;应将它与 ca.crt 成对加密备份,并严格限制读权限。


自签名 CA

infra.ymlca 阶段在 执行 Ansible 的管理节点本地 创建或复用 CA,不是在远端 Infra 节点生成私钥。默认路径如下:

files/pki/
├── ca/                       # CA 私钥、证书与 OpenSSL CA 状态
│   ├── ca.key
│   └── ca.crt
├── csr/                      # 证书签名请求
├── misc/                     # cert.yml 签发的通用证书
├── etcd/
├── infra/
├── kafka/
├── minio/                    # MINIO 模块(Silo)证书
├── mongo/
├── mysql/
├── nginx/
└── pgsql/

核心默认值与 v4.5.0 角色一致:

参数 默认值 含义
ca_create true ca.key 缺失时是否允许创建
ca_cn pigsty-ca CA 证书的 Common Name
cert_validity 7300d 一般内部服务/客户端证书的默认有效期(20 年)
nginx_cert_validity 397d Nginx 自签名 HTTPS 证书有效期

CA 证书在角色中固定为 36500d(约 100 年)。这些长期证书适用于受控内部信任域,不代表它们会被公网浏览器信任;客户端仍需显式信任 ca.crt。公网入口应使用公开受信 CA 签发的证书。

初始化本地 CA 阶段:

./infra.yml -t ca

实际执行 ./infra.yml -t ca 会在缺失时创建密钥或证书,属于 PKI 状态变更;执行前应确认管理节点、配置与现有 CA 备份。


使用外部 CA

如需复用企业 CA:

  1. pigsty.yml 设置 ca_create: false
  2. 在管理节点预先放置匹配的一对 files/pki/ca/ca.keyfiles/pki/ca/ca.crt
  3. 设置目录/文件权限,并用公钥摘要确认私钥与证书匹配。
chmod 700 files/pki/ca
chmod 600 files/pki/ca/ca.key
chmod 644 files/pki/ca/ca.crt

# 两条命令输出的公钥摘要应一致;不会输出私钥内容
openssl pkey -in files/pki/ca/ca.key -pubout -outform PEM | openssl sha256
openssl x509 -in files/pki/ca/ca.crt -pubkey -noout | openssl sha256

ca_create: false 只阻止在私钥缺失时自动生成新私钥。如果 ca.key 存在但 ca.crt 缺失,角色仍会用该私钥重新生成一个自签名 CA 证书;因此必须成对恢复两者,不要依赖自动补齐证书。

执行 CA 阶段前,应核对将要使用的文件、现有 CA 备份与管理节点。


备份与恢复 CA

至少保留以下内容:

  • files/pki/ca/ca.keyca.crt
  • ca.srlindex.txt、CRL 等 CA 状态文件(若已用于签发/撤销管理)
  • 备份时间、CA 证书 SHA-256 指纹与恢复说明
# 只查看公开 CA 证书的标识与指纹
openssl x509 -in files/pki/ca/ca.crt -noout -subject -issuer -dates -fingerprint -sha256

备份必须加密并保存到受控的离线介质或密钥管理系统;不要留下未加密的 tar 包。恢复时先放到隔离临时目录,核对文件数量、类型、权限、公钥匹配与证书指纹,再替换目标文件。

丢失 ca.key 不会让已签发证书立刻无法验证:只要客户端仍信任 ca.crt,既有证书可继续验证到失效或撤销。但您将无法用原 CA 签发、续发或撤销证书,通常需要建立新 CA、重新签发全部证书并滚动更新信任链。


使用 cert.yml 签发证书

cert.yml 只在管理节点本地运行,使用 Pigsty CA 签发通用证书。请显式传入 cn,避免使用脚本中的通用默认值:

./cert.yml -e cn=dbuser_dba

默认输出为:

files/pki/misc/<cn>.key   # 0600
files/pki/misc/<cn>.crt   # 0600
files/pki/csr/<cn>.csr
参数 默认值 说明
cn pigsty Common Name;实际使用时应显式指定
san [DNS:localhost, IP:127.0.0.1] Subject Alternative Names
org pigsty Organization
unit pigsty Organizational Unit
expire 7300d 有效期
key files/pki/misc/<cn>.key 私钥输出路径
crt files/pki/misc/<cn>.crt 证书输出路径

高级示例:

# 签发带 DNS/IP SAN 的证书,SAN 必须使用 JSON 列表传入
./cert.yml -e cn=myservice \
  -e '{"san":["DNS:myservice.local","DNS:myservice","IP:10.10.10.50"]}'

# 签发一年期证书
./cert.yml -e cn=myservice \
  -e '{"san":["DNS:myservice.local","DNS:myservice","IP:10.10.10.50"]}' \
  -e expire=365d

# 自定义 key/crt 时必须同时给出两者
./cert.yml -e cn=custom \
  -e key=/secure/path/custom.key \
  -e crt=/secure/path/custom.crt

签发后验证证书,不要查看或复制私钥内容:

openssl x509 -in files/pki/misc/myservice.crt -noout -subject -issuer -dates -ext subjectAltName
openssl verify -CAfile files/pki/ca/ca.crt files/pki/misc/myservice.crt

PostgreSQL 客户端证书的 cn 必须与 HBA/cert 认证预期的数据库角色一致。将证书、私钥与根证书安装到客户端时,私钥应为 0600,且连接串使用 sslmode=verify-full 时,目标主机名必须出现在服务器证书 SAN 中。


信任 CA 证书

仅分发公开的 ca.crt,绝不分发 ca.key。安装前先通过独立可信渠道核对 SHA-256 指纹。

Debian / Ubuntu

sudo cp ca.crt /usr/local/share/ca-certificates/pigsty-ca.crt
sudo update-ca-certificates

RHEL / Rocky / AlmaLinux

sudo cp ca.crt /etc/pki/ca-trust/source/anchors/pigsty-ca.crt
sudo update-ca-trust

macOS

sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ca.crt

Windows(管理员 PowerShell)

Import-Certificate -FilePath .\ca.crt -CertStoreLocation Cert:\LocalMachine\Root

Infra Nginx 默认可在 http://<infra_ip>/ca.crt 提供公开 CA 证书。下载后仍应核对指纹;HTTP 传输本身不能证明证书真实性。


Nginx 与 Let’s Encrypt

每个 infra_portal 条目都可以指定 certbot 证书名称。Pigsty 的 /etc/nginx/sign-cert 使用 Certbot webroot 模式,聚合同一证书名下的 domaindomains,签发后由 /etc/nginx/link-cert 将证书链接到 Nginx。

前置条件:

  • 公网 DNS A/AAAA 记录准确指向目标 Infra 节点。
  • 公网可访问 HTTP-01 所需的 80 端口;Nginx 已提供 ACME webroot。
  • certbot_email 是有效邮箱,Certbot 软件包已安装。
  • infra_portal 的域名、额外域名与证书名准确无误。
certbot_email: dba@example.com
infra_portal:
  home:
    domain: example.com
    domains: [www.example.com]
    certbot: example.com
  grafana:
    domain: grafana.example.com
    endpoint: "${admin_ip}:3000"
    websocket: true
    certbot: grafana.example.com

更新 Nginx 配置并签发证书:

dig +short example.com
./infra.yml -l infra -t nginx_config,nginx_launch

./infra.yml -l infra -t nginx_certbot,nginx_reload -e certbot_sign=true
必须单独验证签发结果

v4.5.0 的 nginx_certbot 任务设置了 ignore_errors: true。Playbook 继续执行或总体成功不代表证书已签发;必须检查 Certbot 状态、证书文件、Nginx 配置和真实 TLS 握手。

certbot certificates
test -r /etc/letsencrypt/live/example.com/fullchain.pem
nginx -t
openssl s_client -connect example.com:443 -servername example.com </dev/null

续期调度由所用发行版的 Certbot 软件包决定,不要在未检查现有 timer/cron 前重复添加任务:

systemctl list-timers --all | grep -i certbot
certbot renew --dry-run

Certbot 更新磁盘上的证书后,Nginx 还需要 reload 才会加载新证书。应配置并验证续期 deploy hook(例如 systemctl reload nginx),或建立等价的受管流程;完成一次真实或 staging 续期演练后再视为自动续期可用。


故障排查与验收

现象 核对项
浏览器不信任内部证书 客户端是否安装了正确 ca.crt;主机名是否在 SAN;系统时间是否准确
verify-full 失败 连接主机名、证书 SAN、证书链与根证书是否一致
Certbot HTTP-01 失败 DNS、80 端口、Nginx ACME webroot、代理/CDN 与速率限制
Playbook 成功但仍是旧证书 nginx_certbot 错误是否被忽略;link-cert 链接与 Nginx reload 是否完成
权限错误 私钥 0600(部署后的 Nginx key 为 0640 root:nginx);证书/目录属主是否正确
CA 轮换后服务互信失败 是否按客户端信任 → 服务证书 → 服务重载的顺序完成滚动更新

最终验收应分别证明:证书内容与 SAN 正确、链验证成功、服务实际加载新证书、目标客户端信任、续期任务存在且 dry-run 成功。生成了文件或 playbook 返回成功,都不能替代这些检查。

6 - Grafana 高可用部署:使用 PostgreSQL 后端数据库

使用 PostgreSQL 而不是 SQLite 作为 Grafana 后端使用的远程存储数据库,获取更好的性能与可用性。

您可以使用 PostgreSQL 作为 Grafana 后端使用的数据库。

这是了解 Pigsty 部署系统使用方式的好机会,完成此教程,您会了解:


太长不看

vi pigsty.yml # 取消注释DB/User定义:dbuser_grafana  grafana 
bin/pgsql-user  pg-meta  dbuser_grafana
bin/pgsql-db    pg-meta  grafana

psql postgres://dbuser_grafana:DBUser.Grafana@meta:5436/grafana -c \
  'CREATE TABLE t(); DROP TABLE t;' # 检查连接串可用性
  
vi /etc/grafana/grafana.ini # 修改 [database] type url
systemctl restart grafana-server

创建数据库集群

我们可以在 pg-meta 上定义一个新的数据库 grafana,也可以在新的机器节点上创建一个专用于 Grafana 的数据库集群:pg-grafana

定义集群

如果需要创建新的专用数据库集群 pg-grafana,部署在 10.10.10.1110.10.10.12 两台机器上,可以使用以下配置文件:

pg-grafana: 
  hosts: 
    10.10.10.11: {pg_seq: 1, pg_role: primary}
    10.10.10.12: {pg_seq: 2, pg_role: replica}
  vars:
    pg_cluster: pg-grafana
    pg_databases:
      - name: grafana
        owner: dbuser_grafana
        revokeconn: true
        comment: grafana primary database
    pg_users:
      - name: dbuser_grafana
        password: DBUser.Grafana
        pgbouncer: true
        roles: [dbrole_admin]
        comment: admin user for grafana database

创建集群

使用以下命令完成数据库集群 pg-grafana 的创建:pgsql.yml

./pgsql.yml -l pg-grafana    # 初始化pg-grafana集群

该命令是 Ansible Playbook pgsql.yml,用于创建数据库集群。

定义在 pg_userspg_databases 中的业务用户与业务数据库会在集群初始化时自动创建,因此使用该配置时,集群创建完毕后,(在没有 DNS 支持的情况下)您可以使用以下连接串 访问 数据库(任一即可):

postgres://dbuser_grafana:DBUser.Grafana@10.10.10.11:5432/grafana # 主库直连
postgres://dbuser_grafana:DBUser.Grafana@10.10.10.11:5436/grafana # 直连default服务
postgres://dbuser_grafana:DBUser.Grafana@10.10.10.11:5433/grafana # 连接串读写服务

postgres://dbuser_grafana:DBUser.Grafana@10.10.10.12:5432/grafana # 主库直连
postgres://dbuser_grafana:DBUser.Grafana@10.10.10.12:5436/grafana # 直连default服务
postgres://dbuser_grafana:DBUser.Grafana@10.10.10.12:5433/grafana # 连接串读写服务

因为默认情况下 Pigsty 安装在 单个元节点 上,接下来的步骤我们会在已有的 pg-meta 数据库集群上创建 Grafana 所需的用户与数据库,而并非使用这里创建的 pg-grafana 集群。


创建Grafana业务用户

通常业务对象管理的惯例是:先创建用户,再创建数据库。 因为如果为数据库配置了 owner,数据库对相应的用户存在依赖。

定义用户

要在 pg-meta 集群上创建用户 dbuser_grafana,首先将以下用户定义添加至 pg-meta集群定义 中:

添加位置:all.children.pg-meta.vars.pg_users

- name: dbuser_grafana
  password: DBUser.Grafana
  comment: admin user for grafana database
  pgbouncer: true
  roles: [ dbrole_admin ]

如果您在这里定义了不同的密码,请在后续步骤中将相应参数替换为新密码

创建用户

使用以下命令完成 dbuser_grafana 用户的创建(任一均可)。

bin/pgsql-user pg-meta dbuser_grafana # 在pg-meta集群上创建`dbuser_grafana`用户

实际上调用了 Ansible Playbook pgsql-user.yml 创建用户

./pgsql-user.yml -l pg-meta -e pg_user=dbuser_grafana  # Ansible

dbrole_admin 角色具有在数据库中执行 DDL 变更的权限,这正是 Grafana 所需要的。


创建Grafana业务数据库

定义数据库

创建业务数据库的方式与业务用户一致,首先在 pg-meta 的集群定义中添加新数据库 grafana定义

添加位置:all.children.pg-meta.vars.pg_databases

- { name: grafana, owner: dbuser_grafana, revokeconn: true }

创建数据库

使用以下命令完成 grafana 数据库的创建(任一均可)。

bin/pgsql-db pg-meta grafana # 在`pg-meta`集群上创建`grafana`数据库

实际上调用了 Ansible Playbook pgsql-db.yml 创建数据库

./pgsql-db.yml -l pg-meta -e pg_database=grafana # 实际执行的Ansible剧本

使用Grafana业务数据库

检查连接串可达性

您可以使用不同的 服务接入 方式访问数据库,例如:

postgres://dbuser_grafana:DBUser.Grafana@meta:5432/grafana # 直连
postgres://dbuser_grafana:DBUser.Grafana@meta:5436/grafana # default服务
postgres://dbuser_grafana:DBUser.Grafana@meta:5433/grafana # primary服务

这里,我们将使用通过负载均衡器直接访问主库的 Default服务 访问数据库。

首先检查连接串是否可达,以及是否有权限执行 DDL 命令。

psql postgres://dbuser_grafana:DBUser.Grafana@meta:5436/grafana -c \
  'CREATE TABLE t(); DROP TABLE t;'

直接修改Grafana配置

为了让 Grafana 使用 Postgres 数据源,您需要编辑 /etc/grafana/grafana.ini,并修改配置项:

[database]
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
;password =
;url =

将默认的配置项修改为:

[database]
type = postgres
url =  postgres://dbuser_grafana:DBUser.Grafana@meta/grafana

随后重启 Grafana 即可:

systemctl restart grafana-server

从监控系统中看到新增的 grafana 数据库已经开始有活动,则说明 Grafana 已经开始使用 Postgres 作为首要后端数据库了。 但一个新的问题是,Grafana 中原有的 Dashboards 与 Datasources 都消失了!这里需要重新导入 监控面板Postgres数据源


管理Grafana监控面板

您可以使用管理用户前往 Pigsty 目录下的 files/grafana 目录,执行 grafana.py init 重新加载 Pigsty 监控面板。

cd ~/pigsty/files/grafana
./grafana.py init    # 使用当前目录下的Dashboards初始化Grafana监控面板

执行结果:

vagrant@meta:~/pigsty/files/grafana
$ ./grafana.py init
Grafana API: admin:pigsty @ http://10.10.10.10:3000
init dashboard : home.json
init folder pgcat
init dashboard: pgcat / pgcat-table.json
init dashboard: pgcat / pgcat-bloat.json
init dashboard: pgcat / pgcat-query.json
init folder pgsql
init dashboard: pgsql / pgsql-replication.json
init dashboard: pgsql / pgsql-table.json
init dashboard: pgsql / pgsql-activity.json
init dashboard: pgsql / pgsql-cluster.json
init dashboard: pgsql / pgsql-node.json
init dashboard: pgsql / pgsql-database.json
init dashboard: pgsql / pgsql-xacts.json
init dashboard: pgsql / pgsql-overview.json
init dashboard: pgsql / pgsql-session.json
init dashboard: pgsql / pgsql-tables.json
init dashboard: pgsql / pgsql-instance.json
init dashboard: pgsql / pgsql-queries.json
init dashboard: pgsql / pgsql-alert.json
init dashboard: pgsql / pgsql-service.json
init dashboard: pgsql / pgsql-persist.json
init dashboard: pgsql / pgsql-proxy.json
init dashboard: pgsql / pgsql-query.json
init folder pglog
init dashboard: pglog / pglog-instance.json
init dashboard: pglog / pglog-analysis.json
init dashboard: pglog / pglog-session.json

该脚本会通过 Grafana API 导入仪表盘。你可以使用环境变量显式指定 Grafana 访问参数:

export GRAFANA_ENDPOINT=http://10.10.10.10:3000
export GRAFANA_USERNAME=admin
export GRAFANA_PASSWORD=pigsty

题外话,使用 grafana.py clean 会清空目标监控面板,使用 grafana.py load 会加载当前目录下所有监控面板,当 Pigsty 的监控面板发生变更,可以使用这两个命令升级所有的监控面板。

管理Postgres数据源

当使用 pgsql.yml 创建新 PostgreSQL 集群,或使用 pgsql-db.yml 创建新业务数据库时,Pigsty 会在 Grafana 中注册新的 PostgreSQL 数据源,您可以使用默认的监控用户通过 Grafana 直接访问目标数据库实例。应用 pgcat 的绝大部分功能有赖于此。

要注册 Postgres 数据库数据源,可以使用 pgsql.yml 中的 add_ds 任务(或使用更全面的 pg_register):

./pgsql.yml -t add_ds             # 重新注册当前环境中所有 PostgreSQL 数据源
./pgsql.yml -t add_ds -l pg-test  # 仅重新注册 pg-test 集群的数据源

一步到位更新Grafana

您可以直接通过修改 Pigsty 配置文件,更改 Grafana 使用的后端数据源,一步到位的完成切换 Grafana 后端数据库的工作。编辑 pigsty.ymlgrafana_pgurl 参数,将其修改为:

grafana_pgurl: postgres://dbuser_grafana:DBUser.Grafana@meta:5436/grafana

然后重新执行 infra.yml 中的 grafana 任务,即可完成 Grafana 升级

./infra.yml -t grafana