跳转到主要内容

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

返回本页常规视图.

管理

管理您的部署
Ansible
    使用 ansible 运行管理命令
剧本
    Pigsty 中的内置剧本
仪表板
    grafana 仪表板介绍
监控
    prometheus 和 alertmanager 介绍

Nginx 门户
    WebUI 服务的 Nginx 门户
本地仓库
    管理本地 APT / YUM 仓库
域名
    使用本地 / 公共域名
CA 和证书
    使用自签名或真实 HTTPS 证书

PGSQL
    具有 HA、PITR、IaC、ACL、监控、连接池的 PostgreSQL 集群
INFRA
    用于可观测性的 Nginx、本地仓库、DNS、NTP、可观测性技术栈
NODE
    将节点注册到期望状态并监控它,以及 VIP、HAProxy
ETCD
    可靠的分布式共识存储 (DCS),为 PGSQL HA 提供支持
MINIO
    兼容 S3 的对象存储,可选备份存储
REDIS
    高性能内存缓存,可选数据结构服务器

1 - Ansible

开始学习基本的 ansible 概念

Pigsty 使用 Ansible 实现管理控制器,这是一个开源自动化工具,用于以基础设施即代码(IaC)的方式管理大规模基础设施。 被运维人员广泛使用。


安装

Pigsty 将在引导期间尽力安装 ansible 及其依赖项。 但您始终可以手动安装它,它在大多数操作系统的官方仓库中都可用,如果使用 Pigsty,则可以用以下命令安装。

安装 Ansible

Playbooks 还需要一个弱依赖:jmespath python 包。

cd ~/pigsty; ./bootstrap
sudo apt install -y ansible python3-jmespath
sudo dnf install -y ansible python-jmespath
sudo dnf install -y ansible python3.12-jmespath
sudo yum install -y ansible python-jmespath
brew install ansible
pip3 install jmespath

请注意,目前 EL10 EPEL 仓库尚未提供完整的 Ansible 包,Pigsty PGSQL EL10 仓库中补充了这个包。

macOS

Ansible 在 macOS 上也可用。您可以使用 Homebrew 在 Mac 上安装 Ansible。 并将其用作管理节点来管理远程云服务器。 如果您在云 VPS 上部署单节点 pigsty,这很方便。但不建议在生产环境中使用。


基础知识

了解 Ansible 知识有助于使用,但 并非必须。您只需要知道如何运行 Ansible 剧本 即可。 剧本(Playbook)是包含要执行的一系列任务的可执行 YAML 文件。

运行 ./node.yml playbook 本质上是执行 ansible-playbook node.yml 命令。剧本顶部的 hashbang 使其可直接执行。 您可以使用一些参数来精细控制剧本的执行:

~/pigsty
./node.yml                         # 在所有主机上运行 node 剧本
./pgsql.yml -l pg-test             # 在 pg-test 集群上运行 pgsql 剧本
./infra.yml -t repo                # 运行 infra.yml 的子任务 repo
./pgsql-rm.yml -e pg_rm_pkg=false  # 删除 pgsql,但保留包

以下 4 个参数 需要您注意,以便有效使用 ansible:

目的 参数 描述
对象 -l|--limit <pattern> 限制在特定组/主机/模式上的执行目标
任务 -t|--tags <tags> 只运行具有特定标签的任务
参数 -e|--extra-vars <vars> 额外的命令行参数
配置 -i|--inventory <path> 使用特定的清单文件

限制主机

playbook 的执行目标可以通过 -l|--limit <selector> 限制。 当尝试在特定主机/节点或组/集群上运行 playbooks 时,这很方便。 以下是主机限制的一些示例:

./pgsql.yml                              # 在所有主机上运行(危险!)
./pgsql.yml -l pg-test                   # 在 pg-test 集群上运行
./pgsql.yml -l 10.10.10.10               # 在单个主机 10.10.10.10 上运行
./pgsql.yml -l pg-*                      # 在匹配 glob 模式 `pg-*` 的主机/组上运行
./pgsql.yml -l '10.10.10.11,&pg-test'    # 在 pg-test 组的 10.10.10.11 上运行
./pgsql-rm.yml -l 'pg-test,!10.10.10.11' # 在 pg-test 上运行,除了 10.10.10.11
./pgsql.yml -l pg-test                   # 对 pg-test 集群中的主机执行 pgsql playbook

查看 ansible 文档中的所有详细信息:Patterns: targeting hosts and groups

在没有主机限制的情况下运行 playbook 可能很危险!

缺少这个值可能很危险,因为大多数 playbooks 将在 all 主机上执行。请谨慎使用


限制任务

执行任务可以通过 -t|--tags <tags> 控制。 如果指定,将执行具有给定标签的任务,而不是整个 playbook。 以下是一些任务限制示例:

./infra.yml -t repo          # 创建仓库
./node.yml  -t node_pkg      # 安装节点包
./pgsql.yml -t pg_install    # 安装 pg 包和扩展
./etcd.yml  -t etcd_purge    # 销毁 etcd 集群
./minio.yml -t minio_alias   # 写入 minio cli 配置

要运行多个任务,指定多个标签并用逗号分隔:-t tag1,tag2

./node.yml  -t node_repo,node_pkg   # 添加仓库,然后安装包
./pgsql.yml -t pg_hba,pg_reload     # 配置,然后重新加载 pg hba 规则

额外变量

您可以使用 cli 参数在运行时覆盖配置参数,它具有最高优先级

额外的命令行参数可以通过 -e|--extra-vars KEY=VALUE 传递,可以多次使用:

# 使用另一个管理员用户创建管理员
./node.yml -e ansible_user=admin -k -K -t node_admin

# 初始化一个特定的 redis 实例:10.10.10.11:6379
./redis.yml -l 10.10.10.10 -e redis_port=6379 -t redis

# 删除 postgres,但保留包和数据
./pgsql-rm.yml -e pg_rm_pkg=false -e pg_rm_data=false

对于复杂参数,可以使用 JSON 字符串:

# 添加仓库并安装包
./node.yml -t node_install -e '{"node_repo_modules":"infra","node_packages":["duckdb"]}'

指定清单

默认配置文件是 pigsty 主目录中的 pigsty.yml

您可以使用 -i <path> 参数指定不同的清单文件路径。

./pgsql.yml -i conf/rich.yml            # 根据 rich 配置初始化一个下载了所有扩展的单节点
./pgsql.yml -i conf/ha/full.yml            # 根据 full 配置初始化一个 4 节点集群
./pgsql.yml -i conf/app/supa.yml        # 根据 supa.yml 配置初始化一个 1 节点 Supabase 部署
更改默认清单文件

要永久更改默认配置文件,请更改 ansible.cfg 中的 inventory 参数。

2 - 剧本

使用 ansible 运行 playbooks,Pigsty 中的剧本列表与说明

Pigsty 使用幂等的 Ansible playbooks 实现管理控制器。 Playbooks 需要您的 PATH 中有 ansible-playbook 可执行文件。您必须安装 ansible 才能运行 playbooks。

这里是 Pigsty 中的内置 playbooks,您也可以添加自己的。

模块 Playbook 功能
INFRA install.yml 在当前节点上一键安装 Pigsty
INFRA infra.yml 在基础设施节点上初始化 pigsty 基础设施
INFRA infra-rm.yml 从基础设施节点移除基础设施组件
INFRA cache.yml 从目标节点制作离线安装包
INFRA cert.yml 使用 pigsty 自签名 CA 颁发证书(例如用于 pg 客户端)
NODE node.yml 为 pigsty 初始化节点,将节点调整到所需状态
NODE node-rm.yml 从 pigsty 移除节点
PGSQL pgsql.yml 初始化 HA PostgreSQL 集群,或添加新副本
PGSQL pgsql-rm.yml 移除 PostgreSQL 集群,或移除副本
PGSQL pgsql-db.yml 向现有 PostgreSQL 集群添加新业务数据库
PGSQL pgsql-user.yml 向现有 PostgreSQL 集群添加新业务用户
PGSQL pgsql-pitr.yml 在现有 PostgreSQL 集群上执行时间点恢复
PGSQL pgsql-monitor.yml 使用本地导出器监控远程 postgres 实例
PGSQL pgsql-migration.yml 为现有 PostgreSQL 生成迁移手册和脚本
PGSQL slim.yml 安装最小组件的 Pigsty
REDIS redis.yml 初始化 redis 集群/节点/实例
REDIS redis-rm.yml 移除 redis 集群/节点/实例
ETCD etcd.yml 初始化 etcd 集群,或扩容新成员
ETCD etcd-rm.yml 移除 etcd 集群与数据,或移除现有成员缩容
MINIO minio.yml 初始化 minio 集群(pgbackrest 仓库可选)
MINIO minio.yml 移除 minio 集群与数据
DOCKER docker.yml 在节点上安装 docker
DOCKER app.yml 使用 docker compose 安装应用程序
FERRET mongo.yml 在节点上安装 Mongo/FerretDB

部署

特殊的 playbook install.yml 将使用临时 playbooks 部署所有内容:

Playbook 命令 分组 infra [nodes] etcd minio [pgsql]
infra.yml ./infra.yml -l infra
node.yml ./node.yml
etcd.yml ./etcd.yml -l etcd
minio.yml ./minio.yml -l minio
pgsql.yml ./pgsql.yml

3 - Nginx 入口

配置基础设施门户和 nginx 设置

Pigsty 在基础设施节点上安装 Nginx 作为 Web 服务代理,默认使用端口 80/443。 全局参数 infra_portal 配置 Nginx 代理规则和上游服务。


Nginx 服务器配置通过 infra_portal 参数指定。用户声明要通过 Nginx 代理的所有域名,以及相应的上游服务器端点或本地目录路径。

基本示例

infra_portal:  # 域名和上游服务器
  home         : { domain: h.pigsty }
  grafana      : { domain: g.pigsty, endpoint: "${admin_ip}:3000", websocket: true }
  prometheus   : { domain: p.pigsty, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty, endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

复杂示例

infra_portal:
  home         : { domain: home.pigsty.cc }
  grafana      : { domain: g.pgsty.com, endpoint: "${admin_ip}:3000", websocket: true }
  cc           : { domain: pigsty.cc, path: "/www/pigsty.cc" }
  en           : { domain: pigsty.io, path: "/www/pigsty.io" }
  prometheus   : { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059" }
  minio        : { domain: s3.pigsty.cc, endpoint: "${admin_ip}:9001", websocket: true }
  jupyter      : { domain: lab.pigsty.cc, endpoint: "${admin_ip}:8888", websocket: true }
  repo         : { domain: repo.pigsty.cc, path: "/www/repo", index: true }
  wiki         : { domain: wiki.pigsty.cc, endpoint: "${admin_ip}:9002" }
  noco         : { domain: noco.pigsty.cc, endpoint: "${admin_ip}:8080" }
  supa         : { domain: supa.pigsty.cc, endpoint: "${admin_ip}:3001" }
  dify         : { domain: dify.pigsty.cc, endpoint: "${admin_ip}:8001" }
  pg1          : { domain: pg1.pigsty.cc, endpoint: "10.10.10.11:5432", scheme: tcp }
  pg2          : { domain: pg2.pigsty.cc, endpoint: "10.10.10.12:5432", scheme: tcp }
  pg3          : { domain: pg3.pigsty.cc, endpoint: "10.10.10.13:5432", scheme: tcp }

Playbook 配置

可以使用 Ansible playbook 重新配置 Nginx:

./infra.yml -t nginx           # 完全重新配置 Nginx
./infra.yml -t nginx_config    # 重新生成 Nginx 配置文件
./infra.yml -t nginx_launch    # 重启 Nginx 服务
./infra.yml -t nginx_cert      # 重新生成 SSL 证书

服务器

infra_portal 中的每个服务器记录支持以下配置选项:

核心参数

  • domain - 可选的代理域名
  • endpoint - 上游服务地址(IP:PORT 或套接字路径)
  • path - 静态内容的本地 Web 服务器根目录
  • scheme - 协议规范(http/https/tcp/udp)

SSL/TLS 参数

  • certbot - 启用 Let’s Encrypt 证书管理
  • cert - 自定义 SSL 证书文件路径
  • key - 自定义 SSL 私钥文件路径

高级参数

  • conf - 自定义 Nginx 配置模板
  • domains - 服务的附加域名
  • index - 为静态内容启用目录列表
  • log - 自定义日志文件配置
  • websocket - 为实时应用启用 WebSocket 支持

参数使用示例

# 带目录列表的静态文件服务
repo: { domain: repo.pigsty.cc, path: "/www/repo", index: true }

# 启用 WebSocket 的服务
grafana: { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: 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 管理的证书
public_api: { domain: api.pigsty.cc, endpoint: "${admin_ip}:8080", certbot: true }

# TCP 流代理
pg_primary: { domain: pg.pigsty.cc, endpoint: "10.10.10.11:5432", scheme: tcp }

使用域名

DNS 解析方法

  1. 公共互联网域名 通过 DNS 提供商
  2. 内部网络 DNS 服务器
  3. 本地 /etc/hosts 文件修改

对于本地开发和测试,请在您的 /etc/hosts 文件中添加条目:

# 添加到 /etc/hosts
<your_public_ip_address> h.pigsty g.pigsty p.pigsty a.pigsty

<your_public_ip_address> 替换为您的实际管理节点 IP 地址。

HTTPS 配置

通过 nginx_sslmode 参数配置 HTTPS 访问,支持以下选项:

  • disabled - 仅 HTTP,无 SSL
  • self-signed - 使用自签名证书(默认)
  • provided - 使用提供的证书
  • letsencrypt - 使用 Let’s Encrypt 证书

证书管理

./infra.yml -t nginx_cert      # 重新生成 SSL 证书

HTTPS 访问方法

对于自签名证书,您可以:

  • 在浏览器中信任自签名 CA
  • 使用浏览器安全绕过选项(在 Chrome 中输入 thisisunsafe
  • 为生产环境配置适当的 CA 签名证书

服务访问示例

使用默认配置,服务可通过以下方式访问:

  • 主页http://h.pigstyhttps://h.pigsty
  • Grafana 仪表板http://g.pigstyhttps://g.pigsty
  • Prometheus 指标http://p.pigstyhttps://p.pigsty
  • Alertmanagerhttp://a.pigstyhttps://a.pigsty

最佳实践

  1. 使用域名 访问服务,而不是直接使用 IP:PORT
  2. 配置 DNS 解析 或适当更新本地 hosts 文件
  3. 为需要的服务启用 WebSocket 支持(如 Grafana、Jupyter)
  4. 在生产环境中使用 HTTPS 并配置适当的证书
  5. 合理组织服务 使用有意义的子域名命名
  6. 监控 Let’s Encrypt 证书过期时间
  7. 通过 Nginx 集中管理 Web 服务代理 以获得更好的管理体验
  8. 使用静态文件服务 用于文档和仓库浏览

4 - 本地软件源

配置本地 APT / YUM 软件仓库

快速开始

如果您想向本地仓库添加一些包,请将它们添加到:

然后运行 make repo 快捷方式来更新本地仓库和节点仓库缓存:

make repo
./infra.yml -t repo_build
./node.yml -t node_repo

使用别名

您可以使用别名来指定一组包,查看 roles/node_id/vars/<os>.<arch>.yml 了解可用的别名:

EL

node-bootstrap: "ansible python3 python3-pip python3-virtualenv python3-requests python3-jmespath python3-cryptography dnf-utils modulemd-tools createrepo_c sshpass"
infra-package:  "nginx dnsmasq etcd haproxy vip-manager node_exporter keepalived_exporter pg_exporter pgbackrest_exporter redis_exporter redis minio mcli pig"
infra-addons:   "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox_exporter nginx_exporter pev2 certbot python3-certbot-nginx"
extra-modules:  "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:  "lz4 unzip bzip2 zlib yum pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl grubby sysstat iotop htop rsync tcpdump perf flamegraph chkconfig"
node-package2:  "netcat socat ftp lrzsz net-tools ipvsadm bind-utils telnet audit ca-certificates readline vim-minimal keepalived chrony openssl openssh-server openssh-clients"
pgsql-utility:  "patroni patroni-etcd pgbouncer pgbackrest pgbadger pg_activity pg_timetable pgFormatter pg_filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb pgloader"

postgresql:     "postgresql$v*"
pgsql:          "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit"
pgsql-mini:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib"
pgsql-core:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit"
pgsql-full:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit postgresql$v-test postgresql$v-devel"
pgsql-main:     "postgresql$v postgresql$v-server postgresql$v-libs postgresql$v-contrib postgresql$v-plperl postgresql$v-plpython3 postgresql$v-pltcl postgresql$v-llvmjit pg_repack_$v* wal2json_$v* pgvector_$v*"
pgsql-client:   "postgresql$v"
pgsql-server:   "postgresql$v-server postgresql$v-libs postgresql$v-contrib"
pgsql-devel:    "postgresql$v-devel"
pgsql-basic:    "pg_repack_$v* wal2json_$v* pgvector_$v*"
# ......

Debian

node-bootstrap: "ansible python3 python3-pip python3-venv python3-jmespath dpkg-dev sshpass tnftp linux-perf"
infra-package:  "nginx dnsmasq etcd haproxy vip-manager node-exporter keepalived-exporter pg-exporter pgbackrest-exporter redis-exporter redis minio mcli pig"
infra-addons:   "grafana grafana-plugins loki logcli promtail prometheus alertmanager pushgateway blackbox-exporter nginx-exporter pev2 certbot python3-certbot-nginx"
extra-modules:  "docker-ce docker-compose-plugin ferretdb2 duckdb restic juicefs vray grafana-infinity-ds"
node-package1:  "lz4 unzip bzip2 zlib1g pv jq git ncdu make patch bash lsof wget uuid tuned nvme-cli numactl sysstat iotop htop rsync tcpdump acl chrony"
node-package2:  "netcat-openbsd socat lrzsz net-tools ipvsadm dnsutils telnet ca-certificates libreadline-dev vim-tiny keepalived openssl openssh-server openssh-client"
pgsql-utility:  "patroni pgbouncer pgbackrest pgbadger pg-activity pg-timetable pgformatter postgresql-filedump pgxnclient timescaledb-tools timescaledb-event-streamer pgcopydb pgloader"

postgresql:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-server-dev-$v"
pgsql:          "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v"
pgsql-mini:     "postgresql-$v postgresql-client-$v"
pgsql-core:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v"
pgsql-full:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-server-dev-$v"
pgsql-main:     "postgresql-$v postgresql-client-$v postgresql-plpython3-$v postgresql-plperl-$v postgresql-pltcl-$v postgresql-$v-repack postgresql-$v-wal2json postgresql-$v-pgvector"
pgsql-client:   "postgresql-client-$v"
pgsql-server:   "postgresql-$v"
pgsql-devel:    "postgresql-server-dev-$v"
pgsql-basic:    "postgresql-$v-repack postgresql-$v-wal2json postgresql-$v-pgvector"
# ......
发行版 x86_64 aarch64
Debian 11 d11.x86_64.yml -
Debian 12 d12.x86_64.yml d12.aarch64.yml
Debian 13 d13.x86_64.yml d13.aarch64.yml
Ubuntu 22.04 u22.x86_64.yml u22.aarch64.yml
Ubuntu 24.04 u24.x86_64.yml u24.aarch64.yml

参考

使用以下 Playbook 任务来管理基础设施节点上的本地软件包仓库(YUM/APT):

./infra.yml -t repo              # 从互联网或离线包创建本地仓库

./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     # 添加上游 repo/list 文件
./infra.yml     -t repo_remove       # 如果 repo_remove=true 则移除现有仓库文件
./infra.yml     -t repo_add          # 添加上游仓库文件到 /etc/yum.repos.d(或 apt)
./infra.yml     -t repo_url_pkg      # 下载 repo_url_packages 中定义的软件包
./infra.yml     -t repo_cache        # 使用 yum makecache / apt update 创建元数据缓存
./infra.yml     -t repo_boot_pkg     # 安装引导软件包(createrepo_c、yum-utils 等)
./infra.yml     -t repo_pkg          # 从上游下载软件包及依赖项
./infra.yml     -t repo_create       # 使用 createrepo_c / dpkg-dev 创建本地仓库
./infra.yml     -t repo_use          # 添加新仓库到 /etc/yum.repos.d | apt sources
./infra.yml -t repo_nginx        # 如果未运行则启动 nginx 作为文件服务器

常用命令:

./infra.yml     -t repo_upstream     # 添加 repo_upstream 中定义的上游仓库
./infra.yml     -t repo_pkg          # 下载软件包及其依赖项
./infra.yml     -t repo_create       # 创建/更新本地 yum/apt 仓库

5 - DNS 域名

为 Web 服务设置域名

安装 Pigsty 后,用户可以通过 IP + 端口访问大多数基础设施组件的 Web 界面。

假设您的节点内部 IP 是 10.10.10.10,那么默认情况下:

虽然 IP + 端口对于开发/测试环境来说工作得很好(嘿,我们有时都很懒!),但对于更严肃的部署,我强烈建议通过域名访问这些服务。

使用域名有许多优势,不需要额外费用,只需要一个简单的配置行。

让我们深入了解这些主题:


TL;DR

将此静态解析记录添加到您的 /etc/hosts(Linux/MacOS)或 C:\Windows\System32\drivers\etc\hosts(Windows):

sudo tee -a /etc/hosts <<EOF
10.10.10.10 h.pigsty g.pigsty p.pigsty a.pigsty
EOF

将占位符 IP 10.10.10.10 替换为您的 Pigsty 节点的 IP(公共/私有,只要可达即可)。

如果您在 infra_portal 中修改了默认域名,请用您的自定义域名替换它们。


为什么使用域名?

Pigsty 强烈建议使用域名而不是直接 IP+端口访问,原因如下:

  • 域名更容易记住(除非您是机器人 🤖)
  • 更灵活 — 指向不同的 IP 而无需更改配置
  • 将所有服务整合在 Nginx 后面,以获得更好的管理、审计和减少攻击面
  • 启用 HTTPS 加密以防止流量窃听
  • 在中国,对未注册域名的 HTTP 访问会被 ISP 劫持,但 HTTPS 不会
  • 通过 Nginx 代理访问绑定到 127.0.0.1 或内部 Docker 网络的服务

Pigsty 默认使用内部静态域名 — 只需在本地添加 DNS 记录,无需注册真实域名

对于面向互联网的部署,考虑使用带有免费 HTTPS 证书的真实域名。


DNS 工作原理

如果您不熟悉 HTTP/DNS 协议,这里是关于 Nginx 如何在单个端口(80 + HTTPS 443)上为多个域名提供服务的快速入门:

DNS 协议

HTTP 协议

  • HTTP 请求(HTTP/1.1+)包含带有请求域名的 Host 标头
  • 这个 Host 标头是关键的 — HTTP/1.1 规范要求客户端包含它
  • Nginx 使用 Host 标头匹配并将请求路由到不同的站点
  • 因此,一个端口可以根据 Host 值提供不同的内容

Pigsty 默认域名

Pigsty 默认配置这四个内部域名

域名 名称 端口 组件 描述
h.pigsty home 80/443 Nginx 默认服务器,本地仓库
g.pigsty grafana 3000 Grafana 监控和可视化
p.pigsty prometheus 9058 Prometheus 时间序列数据库
a.pigsty alertmanager 9059 AlertManager 警报聚合和路由

由于这些域名不使用 TLD,您需要本地静态内部动态解析。

不用担心 — 只需要一行配置! 🚀


本地静态解析

假设 Pigsty 的内部 IP 是 10.10.10.10,将此添加到您的客户端机器的 hosts 文件:

# Pigsty 核心组件和默认域名
10.10.10.10 h.pigsty g.pigsty p.pigsty a.pigsty

添加解析

客户端机器是您浏览 Pigsty 服务的地方 — 您的笔记本电脑、台式机、VM 等。

对于 Linux / macOS:sudo nano /etc/hosts 对于 Windows:以管理员身份运行记事本,编辑 C:\Windows\System32\drivers\etc\hosts

添加记录后,您可以通过这些域名访问 Pigsty Web 服务。

自定义域名

不喜欢默认域名?在安装前在 infra_portal 中修改它们:

infra_portal:
  home         : { domain: h.pigsty.xxx }
  grafana      : { domain: g.pigsty.xxx ,endpoint: "${admin_ip}:3000" ,websocket: true }
  prometheus   : { domain: p.pigsty.xxx ,endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.xxx ,endpoint: "${admin_ip}:9059" }
  blackbox     : { endpoint: "${admin_ip}:9115" }
  loki         : { endpoint: "${admin_ip}:3100" }

然后相应地更新您的 hosts 文件:

10.10.10.10 h.pigsty.xxx g.pigsty.xxx p.pigsty.xxx a.pigsty.xxx

使用您喜欢的任何域名 — 真实的或虚构的 - 只要它通过本地内部公共 DNS 解析到 Pigsty 的 IP。

附加记录

运行其他 Pigsty 扩展?也添加这些记录:

# Pigsty 扩展工具和默认域名
10.10.10.10 adm.pigsty   # pgAdmin GUI
10.10.10.10 ddl.pigsty   # Bytebase DDL 管理
10.10.10.10 cli.pigsty   # pig CLI 保留
10.10.10.10 api.pigsty   # Pigsty API 保留
10.10.10.10 lab.pigsty   # JupyterLab 保留
10.10.10.10 git.pigsty   # Gitea 保留
10.10.10.10 wiki.pigsty  # Wiki.js 保留
10.10.10.10 noco.pigsty  # NocoDB 保留
10.10.10.10 supa.pigsty  # Supabase 保留
10.10.10.10 dify.pigsty  # Dify 保留
10.10.10.10 odoo.pigsty  # Odoo 保留
10.10.10.10 mm.pigsty    # MinIO 保留

公共 IP 解析

对于云部署,解析到您的公共 IP,而不是内部 IP。

如果您的服务器有互联网访问,它通常有两个网卡 - 一个用于互联网(公共 IP),一个用于内部网络(私有 IP)。

示例:如果您的云服务器的公共 IP 是 1.2.3.4,VPC IP 是 10.10.10.10

# 对于云部署,解析到公共 IP!只需更改 IP 部分:
1.2.3.4 h.pigsty g.pigsty p.pigsty a.pigsty

内部动态解析

希望您的办公室同事通过域名访问 Pigsty?使用内部动态解析

最简单的方法:请您的网络管理员将 DNS 记录添加到您的内部 DNS 服务器。

使用内部 DNS

如果您的内部 DNS 服务器是 192.168.1.1,在 Linux/MacOS 上编辑 /etc/resolv.conf

nameserver 192.168.1.1

在 Windows 上:网络设置 → 网络适配器 → TCP/IPv4 属性 → DNS 配置

测试内部 DNS 解析:

dig h.pigsty @192.168.1.1

使用 Pigsty 的 DNS

Pigsty 基础设施模块 包括 DNS 服务器(端口 53)。

⚠️ 中国部署警告:公共服务器通常不能运行 DNS 服务(端口 53)!


本地 HTTPS 访问

对 Pigsty 的 HTTP 访问显示"不安全" - 它是明文的,容易受到 MITM 攻击。

默认情况下,Pigsty 使用本地自签名 CA 为所有 Nginx 虚拟主机颁发证书。

HTTPS 访问显示"证书错误" - 这些是自签名证书,不是来自受信任的 CA。

您的选择:

  • 忽略它,使用 HTTP 或 IP+端口(反正是内部的,对吧?😅)
  • 使用 HTTPS,点击"高级 → 仍然继续"
  • Chrome 用户:在警告时输入 thisisunsafe(魔法词!)
  • 通过将 Pigsty 的 CA 添加到您的浏览器/操作系统来信任自签名证书
  • 为 Pigsty 使用真实的 CA 证书
  • 使用带有适当 HTTPS 证书的真实域名

对于需要 HTTPS 但不想持续警告的内部访问,信任 Pigsty 的自签名 CA

对于生产环境,我们建议使用公共域名通过 certbot 获取免费的 HTTPS 证书。


信任自签名 CA

Pigsty 在初始化期间在管理节点源目录(~/pigsty)中生成自签名 CA。

要使用 HTTPS,请将 Pigsty 的 CA 证书分发到客户端信任存储(或使用真实的 CA — 昂贵!)。

Pigsty 管理的 Linux 节点自动信任 CA。对于其他 Linux 系统:

  • 信任 CA 证书
  • EL
  • Debian / Ubuntu
rm -rf /etc/pki/ca-trust/source/anchors/ca.crt
ln -s /etc/pki/ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
/bin/update-ca-trust

MacOS:双击 ca.crt,添加到钥匙串,搜索 pigsty-ca,打开并"信任"根证书。

Windows:将 ca.crt 添加到"受信任的根证书颁发机构"。

信任 Pigsty 的 CA 后,不再有"不受信任的证书"警告! 🎉


公共域名解析

使用 DNS 提供商,如 Cloudflare、Godaddy、阿里云或腾讯云 DNSPod。

需要购买域名 - 基本域名费用约为每年 10 美元。

通过提供商的控制台/API 添加 DNS 记录,将域名指向 Pigsty 的公共 IP

示例:使用域名 pigsty.xxx,添加通配符 * A 记录或单独的 A 记录:

  • h.pigsty.xxx → 1.2.3.4
  • a.pigsty.xxx → 1.2.3.4
  • p.pigsty.xxx → 1.2.3.4
  • g.pigsty.xxx → 1.2.3.4

Pigsty 包括Certbot 支持以获取免费的 HTTPS 证书(每 3 个月续订一次)。


进一步阅读

有关更高级的配置,请查看 Pigsty 文档中的 DNS、Nginx 和 HTTPS 证书管理。

6 - SSL 证书

配置真实和自签名 HTTPS 证书

Pigsty 在基础设施节点上预装了 Certbot,使您能够为 Nginx 服务器和公共域名获取免费的 Let’s Encrypt HTTPS 证书。


前提条件

在获取 Let’s Encrypt 证书之前,请确保您拥有:

  • 一个公共域名
  • 指向您服务器公共 IP 的 DNS 记录
  • 正确配置了您的域名的 Nginx

步骤 1:确定哪些域名需要证书

首先,通过在您的 infra_portal 中配置域名来确定哪些上游服务需要公共证书:

infra_portal:
  home         : { domain: h.pigsty.cc }
  grafana      : { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: true }
  prometheus   : { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058" }
  alertmanager : { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059" }
  minio        : { domain: m.pigsty.cc, endpoint: "${admin_ip}:9001", scheme: https, websocket: true }
  web          : { domain: pigsty.cc, path: "/www/web.cc" }
  repo         : { domain: repo.pigsty.cc, path: "/www/repo" }

步骤 2:将域名指向您的服务器

配置 DNS A 记录,将所有域名指向您服务器的公共 IP 地址:

# DNS 配置示例
47.83.172.23 pigsty.cc
47.83.172.23 h.pigsty.cc
47.83.172.23 g.pigsty.cc
47.83.172.23 p.pigsty.cc
47.83.172.23 a.pigsty.cc
47.83.172.23 m.pigsty.cc
47.83.172.23 repo.pigsty.cc

验证您的域名是否正确指向您的服务器:

# 测试域名解析
nslookup pigsty.cc
dig g.pigsty.cc

步骤 3:使用 Certbot 请求证书

使用 Certbot 为您的域名请求 Let’s Encrypt 证书:

交互式方法(首次)

certbot --nginx -d pigsty.cc -d repo.pigsty.cc -d g.pigsty.cc -d p.pigsty.cc -d a.pigsty.cc

在首次运行期间,您将被提示:

  • 提供用于 Let’s Encrypt 账户注册的电子邮件地址
  • 同意服务条款
  • 选择是否与电子前哨基金会分享您的电子邮件

非交互式方法

对于自动化部署,使用非交互式模式:

certbot --nginx --agree-tos --email [email protected] -n -d your-domain.com

多个域名的示例:

certbot --nginx --agree-tos --email [email protected] -n \
  -d pigsty.cc \
  -d g.pigsty.cc \
  -d p.pigsty.cc \
  -d a.pigsty.cc \
  -d repo.pigsty.cc

步骤 4:更新 Nginx 配置

成功获取证书后,通过添加 certbot: true 参数来更新您的 infra_portal 配置以使用它们:

infra_portal:
  grafana: { domain: g.pigsty.cc, endpoint: "${admin_ip}:3000", websocket: true, certbot: true }
  prometheus: { domain: p.pigsty.cc, endpoint: "${admin_ip}:9058", certbot: true }
  alertmanager: { domain: a.pigsty.cc, endpoint: "${admin_ip}:9059", certbot: true }
  web: { domain: pigsty.cc, path: "/www/web.cc", certbot: true }
  repo: { domain: repo.pigsty.cc, path: "/www/repo", certbot: true }

然后重新生成 Nginx 配置并重启服务:

./infra.yml -t nginx_config,nginx_launch

步骤 5:配置证书续期

Let’s Encrypt 证书每 90 天过期一次。设置自动续期以确保持续的 HTTPS 覆盖:

测试续期(试运行)

在设置自动续期之前,测试流程:

certbot renew --dry-run

手动续期

手动续期所有证书:

certbot renew

续期特定证书:

certbot renew --cert-name your-domain.com

自动续期

设置每月自动续期的 cron 作业:

# 添加到 crontab
crontab -e

# 添加这一行在每月第一天凌晨 2 点进行续期
0 2 1 * * certbot renew --quiet

或者,如果可用,使用 systemd 定时器:

# 启用 certbot 定时器
systemctl enable certbot.timer
systemctl start certbot.timer

证书管理命令

以下是管理证书的有用 Certbot 命令:

# 列出所有证书
certbot certificates

# 查看证书详细信息
certbot certificates --cert-name your-domain.com

# 续期特定证书
certbot renew --cert-name your-domain.com

# 删除证书
certbot delete --cert-name your-domain.com

# 扩展证书以包含新域名
certbot --nginx -d existing-domain.com -d new-domain.com

# 撤销证书
certbot revoke --cert-path /etc/letsencrypt/live/your-domain.com/cert.pem

故障排除

常见问题

  1. 域名不可访问:确保 DNS 记录正确配置并已传播
  2. 端口 80 被阻塞:Let’s Encrypt 需要端口 80 进行域名验证
  3. 速率限制:Let’s Encrypt 有速率限制;避免快速请求太多证书
  4. 防火墙问题:确保防火墙中端口 80 和 443 是开放的

验证命令

# 检查证书过期时间
openssl x509 -in /etc/letsencrypt/live/your-domain.com/cert.pem -text -noout | grep "Not After"

# 测试 SSL 配置
openssl s_client -connect your-domain.com:443 -servername your-domain.com

# 检查 Nginx 配置
nginx -t

# 重新加载 Nginx
nginx -s reload

最佳实践

  1. 在适当时使用通配符证书用于多个子域名
  2. 使用自动化警报监控证书过期
  3. 定期使用试运行测试续期流程
  4. 保留证书文件的备份
  5. 在生产部署前使用暂存环境进行测试
  6. 为证书过期日期设置监控
  7. 为团队参考记录您的域名配置

安全考虑

  • 保护私钥:确保证书私钥具有受限权限
  • 使用强 SSL 配置:使用现代 SSL 设置配置 Nginx
  • 启用 HTTP 到 HTTPS 重定向:强制安全连接
  • 实施 HSTS:添加 HTTP 严格传输安全标头
  • 定期安全审计:使用 SSL Labs 等工具测试您的 SSL 配置