跳转到主要内容

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

返回本页常规视图.

节点

将 Linux 机器主机注册到期望状态

要部署 模块,您必须通过在 Linux 服务器上安装 NODE 模块将它们注册到 pigsty 中。

架构
    架构、核心概念、身份管理
配置
    配置节点身份
参数
    使用 64 个参数自定义节点组件
管理
    设置 VIP,管理监控节点目标
剧本
    可在节点模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于节点模块的常见问题

1 - 架构

节点类型、架构与核心概念

“节点”是可通过 SSH 访问、 并提供裸 Linux 环境的资源。它可以是物理机、虚拟机,也可以是带有 systemdsudosshd 的类操作系统容器。

Pigsty 中有三类节点;在单节点部署中,它们是同一台机器。

节点类型 说明
管理节点 安装 Pigsty 并发出管理命令的节点
基础设施节点 安装 INFRA 模块的节点
普通节点 所有由 Pigsty 管理的节点,包括管理与基础设施节点

示例

下面的四节点沙箱包含四个普通节点,其中 10.10.10.10 同时是基础设施节点和管理节点。

all:
  children:
    infra:   { hosts: { 10.10.10.10: { infra_seq: 1 } } }  # <--- 标记为基础设施节点
    etcd:    { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    pg-meta: { hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }, vars: { pg_cluster: pg-meta } }
    pg-test:
      hosts:
        10.10.10.11: { pg_seq: 1, pg_role: primary }
        10.10.10.12: { pg_seq: 2, pg_role: replica }
        10.10.10.13: { pg_seq: 3, pg_role: replica }
      vars: { pg_cluster: pg-test }
  vars:
    admin_ip: 10.10.10.10    # <--- 标记管理节点

普通节点

普通节点默认启用以下组件:

组件 端口 说明 默认状态
node_exporter 9100 节点监控指标导出器 启用
haproxy 9101 HAProxy 管理与指标端口 启用
promtail 9080 日志采集代理 启用

以下组件为可选项,可通过参数启用:

组件 端口 说明 默认状态
docker 9323 容器服务及指标端口 禁用
keepalived - 管理节点集群二层 VIP 禁用
keepalived_exporter 9650 监控 Keepalived 状态 禁用

管理节点

管理节点是最先安装 Pigsty、并发出全部控制命令的节点。 每套 Pigsty 部署只有一个管理节点,由 admin_ip 指定;配置时会将其设置为管理节点的主 IP。

保护管理节点访问

管理节点需要通过免密 sshsudo 管理其他节点。未经授权的访问风险 很高,请妥善保护管理节点。

管理节点是最先安装 Pigsty 的节点

管理节点用于向其他节点发出命令,通常与第一个 INFRA 节点重合。

本地笔记本也可作为管理节点

可以在本地笔记本或 Mac 上准备 Pigsty 与 Ansible,并从本机发出管理命令。


基础设施节点

一套部署可以有一个或多个 INFRA 节点;生产环境建议至少两个。配置清单中的 infra 分组指定这些节点,并在其上安装 INFRA 模块。

组件 端口 域名 说明
nginx 80 h.pigsty Web 服务入口与 YUM/APT 仓库
alertmanager 9059 a.pigsty 告警聚合与投递
prometheus 9058 p.pigsty 监控时序数据库
grafana 3000 g.pigsty 可视化平台
loki 3100 - 日志收集服务器
pushgateway 9091 - 一次性任务指标入口
blackbox_exporter 9115 - 黑盒探测
dnsmasq 53 - DNS 服务
chronyd 123 - NTP 服务
ansible - - 执行 Playbook

PGSQL 节点

安装 PGSQL 模块的节点称为 PGSQL 节点。节点与 PostgreSQL 实例按 1:1 部署;node_id_from_pg 可让 节点复用 PostgreSQL 实例身份。

组件 端口 说明 状态
postgres 5432 由 Patroni 管理的 PostgreSQL 服务 启用
pgbouncer 6432 连接池 启用
patroni 8008 PostgreSQL 高可用组件 启用
primary @ haproxy 5433 主库连接池,读写服务 启用
replica @ haproxy 5434 从库连接池,只读服务 启用
default @ haproxy 5436 主库直连服务 启用
offline @ haproxy 5438 离线实例直连服务 启用
pg_exporter 9630 PostgreSQL 指标导出器 启用
pgbouncer_exporter 9631 PgBouncer 指标导出器 启用
pgbackrest_exporter 9854 pgBackRest 指标导出器 启用
vip-manager - 将 VIP 绑定到主库 禁用

2 - 配置

节点身份、DNS、VIP、数据目录和 haproxy 服务

您不需要显式定义节点集群和节点实例。 它通常由其他数据库 模块 的集群定义暗示。 如果您定义了一个 PGSQL 集群,它会隐式定义一个节点集群。

但在某些情况下,您可能希望使用显式命名的节点集群/实例。 例如运行专用用途的节点组(例如,haproxy 组、节点缓冲池等)


身份参数

Pigsty 使用节点的主要 IPv4 地址(inventory_hostname)作为其身份。

名称 类型 级别 必要性 注释
inventory_hostname ip - 必需 节点 IP
nodename string I 可选 节点名称
node_cluster string C 可选 节点集群名称

nodenamenode_cluster 可以用作监控目的的可选次要身份。

节点集群示例
node-test:
  hosts:
    10.10.10.11: { nodename: node-test-1 }
    10.10.10.12: { nodename: node-test-2 }
    10.10.10.13: { nodename: node-test-3 }
  vars:
    node_cluster: node-test

当您只想监控这些节点而不是在其上运行数据库时,这会很有用。


借用身份

因为 Pigsty 在 NODE 和 PG 实例之间使用 1:1 映射(每个节点只有一个 PG 实例), 节点的身份可以从相应的 PG 实例借用:

名称 标签 级别 借用身份 注释
nodename ins I {{ pg_cluster }}-{{ pg_seq }} PG 实例名称
node_cluster cls C {{ pg_cluster }} PG 集群名称

这是默认行为,在监控系统中让 PG 和 NODE 具有相同的 cls / ins 身份标签很方便。 这可以通过将 node_id_from_pg 参数覆盖为 false 来禁用。

如果没有定义相应的 PG 实例,也没有明确定义 nodenamenode_cluster, 节点将被标记为 clsnodesins 为当前主机名。


SSH 连接

inventory_hostnameAnsible 用于通过 SSH 连接到节点。

如果您的节点无法通过 ssh <inventory_hostname> 简单访问,可以使用 ssh 别名 和更多 ansible 连接参数(甚至不同的 IP)。 但 inventory_hostname 仍然是节点的核心身份。

ssh 参数示例
node-test:
  hosts:
    10.10.10.11: { nodename: node-test-1 , ansible_host: node-1 }
    10.10.10.12: { nodename: node-test-2 , ansible_host: 192.168.0.1 , ansible_port: 2222 , ansible_user: root }
  vars:
    node_cluster: node-test

3 - 参数

65 个参数用于定制节点

NODE 模块有 10 个部分,65 个参数。


参数

名称 部分 类型 级别 注释
nodename NODE_ID string I 节点实例身份,如果缺失则使用主机名,可选
node_cluster NODE_ID string C 节点集群身份,如果缺失则使用 ’nodes’,可选
nodename_overwrite NODE_ID bool C 使用 nodename 覆盖节点的主机名?
nodename_exchange NODE_ID bool C 在 play 主机间交换节点名?
node_id_from_pg NODE_ID bool C 如果适用,使用 postgres 身份作为节点身份?
node_write_etc_hosts NODE_DNS bool G/C/I 修改目标节点上的 /etc/hosts
node_default_etc_hosts NODE_DNS string[] G /etc/hosts 中的静态 DNS 记录
node_etc_hosts NODE_DNS string[] C /etc/hosts 中的额外静态 DNS 记录
node_dns_method NODE_DNS enum C 如何处理 DNS 服务器:add、none、overwrite
node_dns_servers NODE_DNS string[] C /etc/resolv.conf 中的动态名称服务器
node_dns_options NODE_DNS string[] C /etc/resolv.conf 中的 DNS 解析选项
node_repo_modules NODE_PACKAGE string C 节点上要添加的上游仓库,默认为本地
node_repo_remove NODE_PACKAGE bool C 移除节点上现有的仓库?
node_packages NODE_PACKAGE string[] C 当前节点要安装的包
node_default_packages NODE_PACKAGE string[] G 所有节点上要安装的默认包
node_disable_firewall NODE_TUNE bool C 禁用节点防火墙?默认为 true
node_disable_selinux NODE_TUNE bool C 禁用节点 selinux?默认为 true
node_disable_numa NODE_TUNE bool C 禁用节点 numa,需要重启
node_disable_swap NODE_TUNE bool C 禁用节点交换分区,谨慎使用
node_static_network NODE_TUNE bool C 重启后保留 DNS 解析器设置
node_disk_prefetch NODE_TUNE bool C 在 HDD 上设置磁盘预取以提高性能
node_kernel_modules NODE_TUNE string[] C 此节点上要启用的内核模块
node_hugepage_count NODE_TUNE int C 2MB 大页数量,优先于比率
node_hugepage_ratio NODE_TUNE float C 节点内存大页比率,默认 0 禁用
node_overcommit_ratio NODE_TUNE float C 节点内存过量使用比率,默认 0 禁用
node_tune NODE_TUNE enum C 节点调优配置文件:none、oltp、olap、crit、tiny
node_sysctl_params NODE_TUNE dict C 除调优外的 k:v 格式 sysctl 参数
node_data NODE_ADMIN path C 节点主数据目录,默认为 /data
node_admin_enabled NODE_ADMIN bool C 在目标节点上创建管理员用户?
node_admin_uid NODE_ADMIN int C 节点管理员用户的 uid 和 gid
node_admin_username NODE_ADMIN username C 节点管理员用户名,默认为 dba
node_admin_ssh_exchange NODE_ADMIN bool C 在节点集群间交换管理员 SSH 密钥
node_admin_pk_current NODE_ADMIN bool C 将当前用户的 SSH 公钥添加到管理员 authorized_keys
node_admin_pk_list NODE_ADMIN string[] C 要添加到管理员用户的 SSH 公钥
node_aliases NODE_ADMIN dict C 要添加的额外 shell 别名,k:v 字典
node_timezone NODE_TIME string C 设置节点时区,空字符串跳过
node_ntp_enabled NODE_TIME bool C 启用 chronyd 时间同步服务?
node_ntp_servers NODE_TIME string[] C /etc/chrony.conf 中的 NTP 服务器
node_crontab_overwrite NODE_TIME bool C 覆盖还是追加到 /etc/crontab
node_crontab NODE_TIME string[] C /etc/crontab 中的 crontab 条目
vip_enabled NODE_VIP bool C 在此节点集群上启用 VIP?
vip_address NODE_VIP ip C IPv4 格式的节点 VIP 地址,如果启用 VIP 则必需
vip_vrid NODE_VIP int C 必需,整数,1-254,在同一 VLAN 中应唯一
vip_role NODE_VIP enum I 可选,master/backup,默认为 backup,用作初始角色
vip_preempt NODE_VIP bool C/I 可选,true/false,默认为 false,启用 VIP 抢占
vip_interface NODE_VIP string C/I 节点 VIP 监听的网络接口,默认为 eth0
vip_dns_suffix NODE_VIP string C 节点 VIP DNS 名称后缀,默认为空字符串
vip_exporter_port NODE_VIP port C keepalived 导出器监听端口,默认为 9650
haproxy_enabled HAPROXY bool C 在此节点上启用 haproxy?
haproxy_clean HAPROXY bool G/C/A 清理所有现有的 haproxy 配置?
haproxy_reload HAPROXY bool A 配置后重新加载 haproxy?
haproxy_auth_enabled HAPROXY bool G 为 haproxy 管理页面启用身份验证
haproxy_admin_username HAPROXY username G haproxy 管理员用户名,默认为 admin
haproxy_admin_password HAPROXY password G haproxy 管理员密码,默认为 pigsty
haproxy_exporter_port HAPROXY port C haproxy 管理/导出器端口,默认为 9101
haproxy_client_timeout HAPROXY interval C 客户端连接超时,默认为 24h
haproxy_server_timeout HAPROXY interval C 服务器端连接超时,默认为 24h
haproxy_services HAPROXY service[] C 要在节点上公开的 haproxy 服务列表
node_exporter_enabled NODE_EXPORTER bool C 在此节点上设置 node_exporter?
node_exporter_port NODE_EXPORTER port C node exporter 监听端口,默认为 9100
node_exporter_options NODE_EXPORTER arg C node_exporter 的额外服务器选项
promtail_enabled PROMTAIL bool C 启用 promtail 日志收集器?
promtail_clean PROMTAIL bool G/A 初始化期间清除现有的 promtail 状态文件?
promtail_port PROMTAIL port C promtail 监听端口,默认为 9080
promtail_positions PROMTAIL path C promtail 位置状态文件路径

NODE

Node 模块将目标节点调优到所需状态,并将它们集成到 Pigsty 监控系统中。


NODE_ID

每个节点都有身份参数,这些参数通过 <cluster>.hosts<cluster>.vars 中的参数配置。详情请查看 NODE Identity


nodename

名称:nodename,类型:string,级别:I

节点实例身份,如果缺失则使用主机名,可选

无默认值,Null 或空字符串表示 nodename 将设置为节点的当前主机名。

如果 node_id_from_pgtrue(默认)且 nodename 未明确定义,nodename 将首先尝试使用 ${pg_cluster}-${pg_seq},如果此节点上未定义 PGSQL,则回退到默认的 HOSTNAME

如果 nodename_overwritetrue,节点名称也将用作 HOSTNAME。


node_cluster

名称:node_cluster,类型:string,级别:C

节点集群身份,如果缺失则使用 ’nodes’,可选

默认值:nodes

如果 node_id_from_pgtrue(默认)且 node_cluster 未明确定义,node_cluster 将首先尝试使用 ${pg_cluster},如果此节点上未定义 PGSQL,则回退到默认的 HOSTNAME


nodename_overwrite

名称:nodename_overwrite,类型:bool,级别:C

使用 nodename 覆盖节点的主机名?

默认值为 true,非空节点名 nodename 将覆盖当前节点的主机名。

nodename 参数未定义或为空字符串,但 node_id_from_pgtrue 时,节点名称将尝试使用 {{ pg_cluster }}-{{ pg_seq }},借用 1:1 PostgreSQL 实例的实例名身份。

如果 nodename 未定义、为空或空字符串且 node_id_from_pgfalse,则不对主机名进行任何更改。


nodename_exchange

名称:nodename_exchange,类型:bool,级别:C

在 play 主机间交换节点名?

默认值为 false

启用此参数时,在执行 node.yml playbook 的同一组节点之间交换节点名称,写入 /etc/hosts


node_id_from_pg

名称:node_id_from_pg,类型:bool,级别:C

如果适用,使用 postgres 身份作为节点身份?

默认值为 true

如果适用,借用 PostgreSQL 集群和实例身份。

如果 postgres 和节点之间存在 1:1 关系,使用相同的身份很有用。


NODE_DNS

Pigsty 为节点配置静态 DNS 记录和动态 DNS 解析器。

如果您已经有 DNS 服务器,请将 node_dns_method 设置为 none 以禁用动态 DNS 设置。

node_write_etc_hosts: true        # 修改目标节点上的 `/etc/hosts`?
node_default_etc_hosts:           # `/etc/hosts` 中的静态 DNS 记录
  - "${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"
node_etc_hosts: []                # `/etc/hosts` 中的额外静态 DNS 记录
node_dns_method: add              # 如何处理 DNS 服务器:add、none、overwrite
node_dns_servers: ['${admin_ip}'] # `/etc/resolv.conf` 中的动态名称服务器
node_dns_options:                 # `/etc/resolv.conf` 中的 DNS 解析选项
  - options single-request-reopen timeout:1

node_write_etc_hosts

名称:node_write_etc_hosts,类型:bool,级别:G|C|I

修改目标节点上的 /etc/hosts

例如,docker VM 默认无法修改 /etc/hosts,因此您可以将此值设置为 false 以禁用修改。


node_default_etc_hosts

名称:node_default_etc_hosts,类型:string[],级别:G

/etc/hosts 中的静态 DNS 记录

默认值:

["${admin_ip} h.pigsty a.pigsty p.pigsty g.pigsty"]

node_default_etc_hosts 是一个数组。每个元素都是格式为 <ip> <name> 的 DNS 记录。

它用于全局静态 DNS 记录。您可以为每个集群使用 node_etc_hosts 来设置临时记录。

确保在 DNS 名称服务器启动之前,将类似 10.10.10.10 h.pigsty a.pigsty p.pigsty g.pigsty 的 DNS 记录写入 /etc/hosts,以确保可以使用域名访问本地 yum 仓库。


node_etc_hosts

名称:node_etc_hosts,类型:string[],级别:C

/etc/hosts 中的额外静态 DNS 记录

默认值:[]

node_default_etc_hosts 相同,但是额外添加的。


node_dns_method

名称:node_dns_method,类型:enum,级别:C

如何处理 DNS 服务器:add、none、overwrite

默认值:add

  • add:将 node_dns_servers 中的记录追加到 /etc/resolv.conf 并保留现有的 DNS 服务器。(默认)
  • overwrite:用 node_dns_servers 中的记录覆盖 /etc/resolv.conf
  • none:如果在生产环境中提供了 DNS 服务器,可以跳过 DNS 服务器配置。

node_dns_servers

名称:node_dns_servers,类型:string[],级别:C

/etc/resolv.conf 中的动态名称服务器

默认值:["${admin_ip}"],管理节点上的默认名称服务器将作为第一个名称服务器添加到 /etc/resolv.conf


node_dns_options

名称:node_dns_options,类型:string[],级别:C

/etc/resolv.conf 中的 DNS 解析选项,默认值:

- options single-request-reopen timeout:1

NODE_PACKAGE

本节讨论要安装的上游 yum 仓库和软件包。

node_repo_modules: local          # 要在节点上添加的上游仓库,默认为本地
node_repo_remove: true            # 移除节点上现有的仓库?
node_packages: [openssh-server]   # 要安装最新版本的当前节点软件包
#node_default_packages: []        # 要在基础设施节点上安装的默认软件包,(默认值从 node_id/vars 加载)

node_repo_modules

名称:node_repo_modules,类型:string,级别:C/A

要在节点上添加的上游仓库,默认值:local

此参数指定要添加到节点的上游仓库。它用于过滤 repo_upstream 条目,只有具有相同 module 值的条目才会添加到节点的软件源。这类似于 repo_modules 参数。


node_repo_remove

名称:node_repo_remove,类型:bool,级别:C/A

移除节点上现有的仓库?

默认值为 true,因此 Pigsty 将在添加上游仓库之前将 /etc/yum.repos.d 中的现有仓库文件移动到备份目录:/etc/yum.repos.d/backup。在 Debian/Ubuntu 上,Pigsty 将备份并移动 /etc/apt/sources.list(.d)/etc/apt/backup


node_packages

名称:node_packages,类型:string[],级别:C

要在当前节点上安装的软件包,默认值:[openssh-server]

每个元素都是逗号分隔的软件包名称列表,除了 node_default_packages 之外,还将在当前节点上安装。

此参数中指定的软件包将升级到最新版本,默认值为 [openssh-server],默认升级 sshd 以避免 SSH CVE。

此参数通常用于安装对当前节点/集群而言是临时的额外软件包。


node_default_packages

名称:node_default_packages,类型:string[],级别:G

要在所有节点上安装的默认软件包,未定义默认值。

此参数是字符串数组,每个字符串都是逗号分隔的软件包名称列表,默认情况下将在所有节点上安装。

此参数没有默认值,您可以明确指定它,或者如果要使用默认值则将其留空。

当将其留空时,Pigsty 将根据您的操作系统使用 roles/node_id/vars 中定义的 node_packages_default 的默认值。

对于 EL 系统,默认值为:

- lz4,unzip,bzip2,pv,jq,git,ncdu,make,patch,bash,lsof,wget,uuid,tuned,nvme-cli,numactl,sysstat,iotop,htop,rsync,tcpdump
- python3,python3-pip,socat,lrzsz,net-tools,ipvsadm,telnet,ca-certificates,openssl,keepalived,etcd,haproxy,chrony
- zlib,yum,audit,bind-utils,readline,vim-minimal,node_exporter,grubby,openssh-server,openssh-clients

对于 debian / ubuntu 节点,明确使用此默认值:

- lz4,unzip,bzip2,pv,jq,git,ncdu,make,patch,bash,lsof,wget,uuid,tuned,nvme-cli,numactl,sysstat,iotop,htop,rsync,tcpdump
- python3,python3-pip,socat,lrzsz,net-tools,ipvsadm,telnet,ca-certificates,openssl,keepalived,etcd,haproxy,chrony
- zlib1g,acl,dnsutils,libreadline-dev,vim-tiny,node-exporter,openssh-server,openssh-client

NODE_TUNE

在节点上配置调优模板、功能、内核模块、sysctl 参数。

node_disable_firewall: true       # 禁用节点防火墙?默认为 true
node_disable_selinux: true        # 禁用节点 selinux?默认为 true
node_disable_numa: false          # 禁用节点 numa,需要重启
node_disable_swap: false          # 禁用节点交换分区,谨慎使用
node_static_network: true         # 重启后保留 DNS 解析器设置
node_disk_prefetch: false         # 在 HDD 上设置磁盘预取以提高性能
node_kernel_modules: [ softdog, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]
node_hugepage_count: 0            # 2MB 大页数量,优先于比率
node_hugepage_ratio: 0            # 节点内存大页比率,0 禁用它(默认)
node_overcommit_ratio: 0          # 节点内存过量使用比率,0 禁用它(默认)
node_tune: oltp                   # 节点调优配置文件:none、oltp、olap、crit、tiny
node_sysctl_params: { }           # 除调优外的 k:v 格式 sysctl 参数

node_disable_firewall

名称:node_disable_firewall,类型:bool,级别:C

禁用节点防火墙?默认为 true

默认值为 true


node_disable_selinux

名称:node_disable_selinux,类型:bool,级别:C

禁用节点 selinux?默认为 true

默认值为 true


node_disable_numa

名称:node_disable_numa,类型:bool,级别:C

禁用节点 numa,需要重启

默认值为 false

布尔标志,默认不关闭。请注意,关闭 NUMA 需要重启机器才能生效!

如果您不知道如何设置 CPU 亲和性,建议关闭 NUMA。


node_disable_swap

名称:node_disable_swap,类型:bool,级别:C

禁用节点交换分区,谨慎使用

默认值为 false

不建议关闭 SWAP。但是,当您的节点用于 Kubernetes 部署时,应该禁用 SWAP。

如果有足够的内存并且数据库独占部署,可能会略微提高性能。


node_static_network

名称:node_static_network,类型:bool,级别:C

重启后保留 DNS 解析器设置,默认值为 true

启用静态网络意味着机器重启不会因 NIC 更改而覆盖您的 DNS Resolv 配置。建议在生产环境中启用。


node_disk_prefetch

名称:node_disk_prefetch,类型:bool,级别:C

在 HDD 上设置磁盘预取以提高性能

默认值为 false,使用 HDD 时考虑启用此功能。


node_kernel_modules

名称:node_kernel_modules,类型:string[],级别:C

要在此节点上启用的内核模块

默认值:

node_kernel_modules: [ softdog, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]

由内核模块名称组成的数组,声明需要在节点上安装的内核模块。


node_hugepage_count

名称:node_hugepage_count,类型:int,级别:C

2MB 大页数量,优先于比率,默认为 0

优先于 node_hugepage_ratio。如果给出非零值,将写入 /etc/sysctl.d/hugepage.conf

如果 node_hugepage_countnode_hugepage_ratio 都为 0(默认),大页将完全禁用。

负值不起作用,高于节点内存 90% 的数字将上限到节点内存的 90%。

如果不为零,它应该略大于 pg_shared_buffer_ratio


node_hugepage_ratio

名称:node_hugepage_ratio,类型:float,级别:C

节点内存大页比率,0 禁用它(默认),有效范围:0 ~ 0.40

默认值:0,将设置 vm.nr_hugepages=0 并且根本不使用 HugePage。

此内存的百分比将分配为 HugePage,并为 PostgreSQL 保留。

如果不为零,它应该等于或略大于 pg_shared_buffer_ratio

例如,如果您为 postgres 共享缓冲区使用默认的 25% 内存,您可以将此值设置为 0.27 ~ 0.30,浪费的大页可以稍后使用 /pg/bin/pg-tune-hugepage 回收。


node_overcommit_ratio

名称:node_overcommit_ratio,类型:int,级别:C

节点内存过量使用比率,0 禁用它(默认)。这是一个从 0 到 100+ 的整数。

默认值:0,将设置 vm.overcommit_memory=0,否则将使用 vm.overcommit_memory=2,此值将用作 vm.overcommit_ratio

建议在专用 pgsql 节点上设置使用 vm.overcommit_ratio。例如 50 ~ 100。


node_tune

名称:node_tune,类型:enum,级别:C

节点调优配置文件:none、oltp、olap、crit、tiny

默认值:oltp

  • tiny:微型虚拟机(1 ~ 3 核,1 ~ 8 GB 内存)
  • oltp:优化延迟的常规 OLTP 模板
  • olap:优化吞吐量的常规 OLAP 模板
  • crit:核心金融业务模板,优化脏页数量

通常,数据库调优模板 pg_conf 应该与节点调优模板配对:node_tune


node_sysctl_params

名称:node_sysctl_params,类型:dict,级别:C

除调优外的 k:v 格式 sysctl 参数

默认值:{}

字典 K-V 结构,Key 是内核 sysctl 参数名称,Value 是参数值。

您也可以使用调优配置文件定义 sysctl 参数。


NODE_ADMIN

本节讨论管理员用户及其凭据。

node_data: /data                  # 节点主数据目录,默认为 `/data`
node_admin_enabled: true          # 在目标节点上创建管理员用户?
node_admin_uid: 88                # 节点管理员用户的 uid 和 gid
node_admin_username: dba          # 节点管理员用户名,默认为 `dba`
node_admin_ssh_exchange: true     # 在节点集群间交换管理员 SSH 密钥
node_admin_pk_current: true       # 将当前用户的 SSH 公钥添加到管理员 authorized_keys
node_admin_pk_list: []            # 要添加到管理员用户的 SSH 公钥

node_data

名称:node_data,类型:path,级别:C

节点主数据目录,默认为 /data

默认值:/data

如果指定,此路径将用作主数据磁盘挂载点。如果路径不存在,将创建目录并抛出警告。

数据目录由 root 拥有,模式为 0777


node_admin_enabled

名称:node_admin_enabled,类型:bool,级别:C

在目标节点上创建管理员用户?

默认值为 true

在每个节点上创建管理员用户(免密 sudo 和 ssh),默认创建名为 dba (uid=88) 的管理员用户,可以从元节点通过 SSH 免密访问环境中的其他节点并执行 sudo。


node_admin_uid

名称:node_admin_uid,类型:int,级别:C

节点管理员用户的 uid 和 gid

默认值:88


node_admin_username

名称:node_admin_username,类型:username,级别:C

节点管理员用户名,默认为 dba

默认值:dba


node_admin_ssh_exchange

名称:node_admin_ssh_exchange,类型:bool,级别:C

在节点集群间交换管理员 SSH 密钥

默认值为 true

启用时,Pigsty 将在 playbook 执行期间在成员之间交换 SSH 公钥,允许管理员 node_admin_username 从不同节点相互访问。


node_admin_pk_current

名称:node_admin_pk_current,类型:bool,级别:C

将当前用户的 SSH 公钥添加到管理员 authorized_keys

默认值为 true

启用时,在当前节点上,当前用户的 SSH 公钥(~/.ssh/id_rsa.pub)被复制到目标节点管理员用户的 authorized_keys

在生产环境中部署时,请务必注意此参数,它将当前执行命令的用户的默认公钥安装到所有机器的管理员用户。


node_admin_pk_list

名称:node_admin_pk_list,类型:string[],级别:C

要添加到管理员用户的 SSH 公钥

默认值:[]

数组的每个元素都是一个字符串,包含写入管理员用户 ~/.ssh/authorized_keys 的密钥,具有相应私钥的用户可以作为管理员用户登录。

在生产环境中部署时,请务必注意此参数,并且只将受信任的密钥添加到此列表。


node_aliases

名称:node_aliases,类型:dict,级别:C/I

要添加到管理员用户 shell 配置文件的额外别名

默认值:{}

您可以向其添加额外的 shell 别名,pigsty 将这些别名添加到目标节点上的 /etc/profile.d/node.alias.sh 文件:

node_aliases:
  g:   git
  d:   docker

这将生成:

alias g="git"
alias d="docker"

NODE_TIME

node_timezone: ''                 # 设置节点时区,空字符串跳过
node_ntp_enabled: true            # 启用 chronyd 时间同步服务?
node_ntp_servers:                 # `/etc/chrony.conf` 中的 NTP 服务器
  - pool pool.ntp.org iburst
node_crontab_overwrite: true      # 覆盖还是追加到 `/etc/crontab`?
node_crontab: [ ]                 # `/etc/crontab` 中的 crontab 条目

node_timezone

名称:node_timezone,类型:string,级别:C

设置节点时区,空字符串跳过

默认值为空字符串,不会更改默认时区(通常为 UTC)


node_ntp_enabled

名称:node_ntp_enabled,类型:bool,级别:C

启用 chronyd 时间同步服务?

默认值为 true,因此 Pigsty 将使用 node_ntp_servers 覆盖节点的 /etc/chrony.conf

如果您已经配置了 NTP 服务器,只需设置为 false 即可保持不变。


node_ntp_servers

名称:node_ntp_servers,类型:string[],级别:C

/etc/chrony.conf 中的 NTP 服务器,默认值:["pool pool.ntp.org iburst"]

只有当 node_ntp_enabled 为 true 时才生效。

您可以使用 ${admin_ip} 与管理节点上的 NTP 服务器同步时间,而不是公共 NTP 服务器。

node_ntp_servers: [ 'pool ${admin_ip} iburst' ]

node_crontab_overwrite

名称:node_crontab_overwrite,类型:bool,级别:C

覆盖还是追加到 /etc/crontab

默认值为 true,pigsty 将以覆盖模式渲染 node_crontab 中的记录,而不是追加到其中。


node_crontab

名称:node_crontab,类型:string[],级别:C

/etc/crontab 中的 crontab 条目

默认值:[]


NODE_VIP

您可以在一个节点集群之间绑定可选的 L2 VIP,默认情况下是禁用的。

L2 VIP 只能在同一 L2 LAN 中使用,这可能会对您的网络拓扑产生额外限制。

如果启用,您必须为每个节点集群手动分配 vip_addressvip_vrid

用户有责任确保地址 / vrid 在同一 LAN 中是唯一的

vip_enabled: false                # 在此节点集群上启用 VIP?
# vip_address:         [IDENTITY] # IPv4 格式的节点 VIP 地址,如果启用 VIP 则必需
# vip_vrid:            [IDENTITY] # 必需,整数,1-254,在同一 VLAN 中应唯一
vip_role: backup                  # 可选,`master/backup`,默认为 backup,用作初始角色
vip_preempt: false                # 可选,`true/false`,默认为 false,启用 VIP 抢占
vip_interface: eth0               # 节点 VIP 监听的网络接口,默认为 `eth0`
vip_dns_suffix: ''                # 节点 VIP DNS 名称后缀,默认为空字符串
vip_exporter_port: 9650           # keepalived 导出器监听端口,默认为 9650

vip_enabled

名称:vip_enabled,类型:bool,级别:C

在此节点集群上启用 VIP?默认值为 false,表示不为此节点集群创建 L2 VIP。

L2 VIP 只能在同一 L2 LAN 中使用,这可能会对您的网络拓扑产生额外限制。


vip_address

名称:vip_address,类型:ip,级别:C

IPv4 格式的节点 VIP 地址,如果节点 vip_enabled必需

无默认值。此参数必须明确分配并在您的 LAN 中唯一。


vip_vrid

名称:vip_vrid,类型:int,级别:C

整数,1-254,在同一 VLAN 中应唯一,如果节点 vip_enabled必需

无默认值。此参数必须明确分配并在您的 LAN 中唯一。


vip_role

名称:vip_role,类型:enum,级别:I

节点 VIP 角色,可以是 masterbackup,将用作初始 keepalived 状态。


vip_preempt

名称:vip_preempt,类型:bool,级别:C/I

可选,true/false,默认为 false,启用 VIP 抢占

默认值为 false,表示当备份具有比活跃主服务器更高的优先级时不会发生抢占。


vip_interface

名称:vip_interface,类型:string,级别:C/I

节点 VIP 监听的网络接口,默认为 eth0

它应该是节点的相同主要内网接口,即您在清单文件中使用的 IP 地址。

如果您的节点有不同的接口,您可以在实例变量上覆盖它。


vip_dns_suffix

名称:vip_dns_suffix,类型:string,级别:C/I

节点 VIP DNS 名称后缀,默认为空字符串。它将用作节点 VIP 的 DNS 名称。


vip_exporter_port

名称:vip_exporter_port,类型:port,级别:C/I

keepalived 导出器监听端口,默认为 9650。


HAPROXY

默认情况下,HAProxy 安装在每个节点上,以 NodePort 方式公开服务。

它由 PGSQL Service 使用。

haproxy_enabled: true             # 在此节点上启用 haproxy?
haproxy_clean: false              # 清理所有现有的 haproxy 配置?
haproxy_reload: true              # 配置后重新加载 haproxy?
haproxy_auth_enabled: true        # 为 haproxy 管理页面启用身份验证
haproxy_admin_username: admin     # haproxy 管理员用户名,默认为 `admin`
haproxy_admin_password: pigsty    # haproxy 管理员密码,默认为 `pigsty`
haproxy_exporter_port: 9101       # haproxy 管理/导出器端口,默认为 9101
haproxy_client_timeout: 24h       # 客户端连接超时,默认为 24h
haproxy_server_timeout: 24h       # 服务器端连接超时,默认为 24h
haproxy_services: []              # 要在节点上公开的 haproxy 服务列表

haproxy_enabled

名称:haproxy_enabled,类型:bool,级别:C

在此节点上启用 haproxy?

默认值为 true


haproxy_clean

名称:haproxy_clean,类型:bool,级别:G/C/A

清理所有现有的 haproxy 配置?

默认值为 false


haproxy_reload

名称:haproxy_reload,类型:bool,级别:A

配置后重新加载 haproxy?

默认值为 true,它将在配置更改后重新加载 haproxy。

如果您希望在应用之前检查,您可以使用 cli 参数关闭此功能并检查它。


haproxy_auth_enabled

名称:haproxy_auth_enabled,类型:bool,级别:G

为 haproxy 管理页面启用身份验证

默认值为 true,这将需要管理页面的 http 基本身份验证。

不建议禁用它,因为您的流量控制将被暴露。


haproxy_admin_username

名称:haproxy_admin_username,类型:username,级别:G

haproxy 管理员用户名,默认为 admin


haproxy_admin_password

名称:haproxy_admin_password,类型:password,级别:G

haproxy 管理员密码,默认为 pigsty

请在您的生产环境中更改它!


haproxy_exporter_port

名称:haproxy_exporter_port,类型:port,级别:C

haproxy 管理/导出器端口,默认为 9101


haproxy_client_timeout

名称:haproxy_client_timeout,类型:interval,级别:C

客户端连接超时,默认为 24h


haproxy_server_timeout

名称:haproxy_server_timeout,类型:interval,级别:C

服务器端连接超时,默认为 24h


haproxy_services

名称:haproxy_services,类型:service[],级别:C

要在节点上公开的 haproxy 服务列表,默认值:[]

每个元素都是一个服务定义,这是一个临时 haproxy 服务示例:

haproxy_services:                   # haproxy 服务列表

  # 公开 pg-test 只读副本
  - name: pg-test-ro                # [必需] 服务名称,唯一
    port: 5440                      # [必需] 服务端口,唯一
    ip: "*"                         # [可选] 服务监听地址,默认为 "*"
    protocol: tcp                   # [可选] 服务协议,默认为 'tcp'
    balance: leastconn              # [可选] 负载均衡算法,默认为 roundrobin(或 leastconn)
    maxconn: 20000                  # [可选] 最大允许前端连接,默认为 20000
    default: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'
    options:
      - option httpchk
      - option http-keep-alive
      - http-check send meth OPTIONS uri /read-only
      - http-check expect status 200
    servers:
      - { name: pg-test-1 ,ip: 10.10.10.11 , port: 5432 , options: check port 8008 , backup: true }
      - { name: pg-test-2 ,ip: 10.10.10.12 , port: 5432 , options: check port 8008 }
      - { name: pg-test-3 ,ip: 10.10.10.13 , port: 5432 , options: check port 8008 }

它将渲染到 /etc/haproxy/<service.name>.cfg 并在重新加载后生效。


NODE_EXPORTER

node_exporter_enabled: true       # 在此节点上设置 node_exporter?
node_exporter_port: 9100          # node exporter 监听端口,默认为 9100
node_exporter_options: '--no-collector.softnet --no-collector.nvme --collector.tcpstat --collector.processes'

node_exporter_enabled

名称:node_exporter_enabled,类型:bool,级别:C

在此节点上设置 node_exporter?默认值为 true


node_exporter_port

名称:node_exporter_port,类型:port,级别:C

node exporter 监听端口,默认为 9100


node_exporter_options

名称:node_exporter_options,类型:arg,级别:C

node_exporter 的额外服务器选项,默认值:--no-collector.softnet --no-collector.nvme --collector.tcpstat --collector.processes

默认情况下,Pigsty 启用 tcpstatprocesses 收集器并禁用 nvmesoftnet 指标收集器。


PROMTAIL

Promtail 将从其他模块收集日志,并将它们发送到 LOKI

  • INFRA:基础设施日志,仅在基础设施节点上收集。
    • nginx-access/var/log/nginx/access.log
    • nginx-error/var/log/nginx/error.log
    • grafana/var/log/grafana/grafana.log
  • NODES:主机节点日志,在所有节点上收集。
    • syslog/var/log/messages
    • dmesg/var/log/dmesg
    • cron/var/log/cron
  • PGSQL:PostgreSQL 日志,当节点使用 pg_cluster 定义时收集。
    • postgres/pg/log/postgres/*
    • patroni/pg/log/patroni.log
    • pgbouncer/pg/log/pgbouncer/pgbouncer.log
    • pgbackrest/pg/log/pgbackrest/*.log
  • REDIS:Redis 日志,当节点使用 redis_cluster 定义时收集。
    • redis/var/log/redis/*.log

日志目录可根据 pg_log_dirpatroni_log_dirpgbouncer_log_dirpgbackrest_log_dir 自定义

promtail_enabled: true            # 启用 promtail 日志收集器?
promtail_clean: false             # 初始化期间清除现有的 promtail 状态文件?
promtail_port: 9080               # promtail 监听端口,默认为 9080
promtail_positions: /var/log/positions.yaml # promtail 位置状态文件路径

promtail_enabled

名称:promtail_enabled,类型:bool,级别:C

启用 promtail 日志收集器?

默认值为 true


promtail_clean

名称:promtail_clean,类型:bool,级别:G/A

初始化期间清除现有的 promtail 状态文件?

默认值为 false,如果您选择清理,Pigsty 将删除由 promtail_positions 定义的现有状态文件,这意味着 Promtail 将重新收集当前节点上的所有日志并再次将它们发送到 Loki。


promtail_port

名称:promtail_port,类型:port,级别:C

promtail 监听端口,默认为 9080

默认值:9080


promtail_positions

名称:promtail_positions,类型:path,级别:C

promtail 位置状态文件路径

默认值:/var/log/positions.yaml

Promtail 记录所有日志的消费偏移量,定期写入由 promtail_positions 指定的文件。

4 - 管理

节点管理标准操作程序

节点管理 SOP,添加和移除节点,设置管理员,绑定 VIP 和其他杂项

以下是 NODE 模块的一些常见管理任务。


添加节点

要将节点添加到 Pigsty,您需要对该节点具有免密 ssh/sudo 访问权限

# ./node.yml -l <cls|ip|group>        # 底层 playbook
# bin/node-add <selector|ip...>       # 将集群/节点添加到 pigsty
bin/node-add node-test                # 初始化节点集群 'node-test'
bin/node-add 10.10.10.10              # 初始化节点 '10.10.10.10'

移除节点

要从 Pigsty 中移除节点,您可以使用以下命令:

# ./node-rm.yml -l <cls|ip|group>    # 底层 playbook
# bin/node-rm <selector|ip...>       # 从 pigsty 中移除节点:
bin/node-rm node-test                # 移除节点集群 'node-test'
bin/node-rm 10.10.10.10              # 移除节点 '10.10.10.10'

创建管理员

如果当前用户对节点没有免密 ssh/sudo 访问权限,您可以使用其他管理员用户来引导节点:

node.yml -t node_admin -k -K -e ansible_user=<another admin>   # 为另一个管理员输入 ssh/sudo 密码

绑定 VIP

您可以使用 vip_enabled 在节点集群上绑定可选的 L2 VIP。

proxy:
  hosts:
    10.10.10.29: { nodename: proxy-1 }
    10.10.10.30: { nodename: proxy-2 } # , vip_role: master }
  vars:
    node_cluster: proxy
    vip_enabled: true
    vip_vrid: 128
    vip_address: 10.10.10.99
    vip_interface: eth1
./node.yml -l proxy -t node_vip     # 首次启用
./node.yml -l proxy -t vip_refresh  # 刷新 VIP 配置(例如指定主节点)

其他任务

# Play
./node.yml -t node                            # 初始化节点本身(不包括 haproxy 监控)
./node.yml -t haproxy                         # 在节点上设置 haproxy 以暴露服务
./node.yml -t monitor                         # 设置 node_exporter 和 promtail 用于指标和日志
./node.yml -t node_vip                        # 为节点集群 L2 VIP 启用 keepalived
./node.yml -t vip_config,vip_reload           # 刷新 L2 VIP 配置
./node.yml -t haproxy_config,haproxy_reload   # 刷新节点集群上的 haproxy 服务定义
./node.yml -t register_prometheus             # 将节点注册到 Prometheus
./node.yml -t register_nginx                  # 将 haproxy 管理页面 URL 注册到基础设施节点上的 Nginx

# Task
./node.yml -t node-id        # 生成节点身份
./node.yml -t node_name      # 设置主机名
./node.yml -t node_hosts     # 设置 /etc/hosts 记录
./node.yml -t node_resolv    # 设置 DNS 解析器
./node.yml -t node_firewall  # 设置防火墙和 selinux
./node.yml -t node_ca        # 添加和信任 CA 证书
./node.yml -t node_repo      # 添加上游仓库
./node.yml -t node_pkg       # 安装 yum 包
./node.yml -t node_feature   # 设置 numa、grub、静态网络
./node.yml -t node_kernel    # 启用内核模块
./node.yml -t node_tune      # 设置调优配置文件
./node.yml -t node_sysctl    # 设置额外的 sysctl 参数
./node.yml -t node_profile   # 写入 /etc/profile.d/node.sh
./node.yml -t node_ulimit    # 设置资源限制
./node.yml -t node_data      # 设置主数据目录
./node.yml -t node_admin     # 设置管理员用户和 SSH 密钥
./node.yml -t node_timezone  # 设置时区
./node.yml -t node_ntp       # 设置 NTP 服务器/客户端
./node.yml -t node_crontab   # 添加/覆写 crontab 任务
./node.yml -t node_vip       # 为节点集群设置可选的 L2 VRRP VIP

节点调优

Pigsty 为不同的工作负载预定义了四个调优配置文件:

配置文件 描述 场景
TINY 针对小型虚拟机运行优化 规格 < 4c8g
OLTP 针对延迟优化 默认,事务处理
OLAP 针对吞吐量优化 分析性工作负载
CRIT 针对可靠性优化 金融、关键业务

您也可以在节点上使用 tuned-adm 命令管理调优配置文件:

tuned-adm list             # 列出可用配置文件
tuned-adm active           # 显示当前配置文件
tuned-adm profile          # 列出活动配置文件
tuned-adm profile <name>   # 切换到配置文件 <name>
tuned-adm verify           # 列出活动配置文件
cat /var/log/tuned/tuned.log  # 显示调优日志

内核模块

您可以在 node.yml 中使用 node_kernel_modules 管理内核模块。

要手动管理内核模块,您可以在节点上使用以下命令:

lsmod                   # 列出已加载的内核模块
modprobe <module>       # 加载内核模块 <module>

5 - 剧本

使用 Ansible playbooks 自动化节点生命周期管理

Pigsty 提供两个用于节点管理的 playbooks:

剧本 目的 用法 范围
node.yml 将节点添加到 pigsty ./node.yml -l <target> 单个节点或集群
node-rm.yml 从 pigsty 中移除节点 ./node-rm.yml -l <target> 单个节点或集群

node.yml

node.yml playbook 将裸机计算资源转换为 Pigsty 基础设施中完全配置、监控和服务就绪的节点。这个全面的自动化处理从基本操作系统配置到高级监控设置的所有内容。

node-id       : generate node identity
node_name     : setup hostname
node_hosts    : setup /etc/hosts records
node_resolv   : setup dns resolver
node_firewall : setup firewall & selinux
node_ca       : add & trust ca certificate
node_repo     : add upstream repo
node_pkg      : install yum packages
node_feature  : setup numa, grub, static network
node_kernel   : enable kernel modules
node_tune     : setup tuned profile
node_sysctl   : setup additional sysctl parameters
node_profile  : write /etc/profile.d/node.sh
node_ulimit   : setup resource limits
node_data     : setup main data dir
node_admin    : setup admin user and ssh key
node_timezone : setup timezone
node_ntp      : setup ntp server/clients
node_crontab  : add/overwrite crontab tasks
node_vip      : setup optional l2 vrrp vip for node cluster
  - vip_install
  - vip_config
  - vip_launch
  - vip_reload
haproxy       : setup haproxy on node to expose services
  - haproxy_install
  - haproxy_config
  - haproxy_launch
  - haproxy_reload
monitor       : setup node_exporter & promtail for metrics & logs
  - haproxy_register
  - vip_dns
  - node_exporter
    - node_exporter_config
    - node_exporter_launch
  - vip_exporter
    - vip_exporter_config
    - vip_exporter_launch
  - node_register
  - promtail
    - promtail_clean
    - promtail_config
    - promtail_install
    - promtail_launch

asciicast


node-rm.yml

node-rm.yml playbook 执行从 Pigsty 基础设施中干净、全面地移除节点。此自动化确保所有服务、配置和监控集成都正确注销和清理,防止孤立资源并保持系统卫生。

register       : remove register from prometheus & nginx
  - prometheus : remove registered prometheus monitor target
  - nginx      : remove nginx proxy record for haproxy admin
vip            : remove node keepalived if enabled
haproxy        : remove haproxy load balancer
node_exporter  : remove monitoring exporter
vip_exporter   : remove keepalived_exporter if enabled
promtail       : remove loki log agent
profile        : remove /etc/profile.d/node.sh

6 - 监控

使用节点和 Linux 操作系统指标进行主机监控

仪表板

NODE 模块有 6 个仪表板。

NODE Overview:所有节点概览

NODE Cluster:特定节点集群的详细信息

NODE Instance:单个节点实例的详细信息

NODE Alert:所有节点集群/实例的关键指标概览

NODE VIP:节点集群上 L2 VIP 的详细信息

NODE Haproxy:haproxy 负载均衡器的详细信息


告警规则

以下是节点模块的默认告警规则:

################################################################
#                         Node Alert                           #
################################################################
- name: node-alert
  rules:

    #==============================================================#
    #                          Aliveness                           #
    #==============================================================#
    # node exporter is dead indicate node is down
    - alert: NodeDown
      expr: node_up < 1
      for: 1m
      labels: { level: 0, severity: CRIT, category: node }
      annotations:
        summary: "CRIT NodeDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          node_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # haproxy the load balancer
    - alert: HaproxyDown
      expr: haproxy_up < 1
      for: 1m
      labels: { level: 0, severity: CRIT, category: node }
      annotations:
        summary: "CRIT HaproxyDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          haproxy_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-haproxy?var-ins={{ $labels.ins }}

    # promtail the logging agent
    - alert: PromtailDown
      expr: promtail_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN PromtailDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          promtail_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # docker the container engine
    - alert: DockerDown
      expr: docker_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN DockerDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          docker_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}

    # keepalived daemon
    - alert: KeepalivedDown
      expr: keepalived_up < 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: "WARN KeepalivedDown {{ $labels.ins }}@{{ $labels.instance }}"
        description: |
          keepalived_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} < 1
          http://g.pigsty/d/node-instance?var-ins={{ $labels.ins }}



    #==============================================================#
    #                          Node : CPU                          #
    #==============================================================#
    # cpu usage high : 1m avg cpu usage > 70% for 3m
    - alert: NodeCpuHigh
      expr: node:ins:cpu_usage_1m > 0.70
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeCpuHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:cpu_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 70%

    # OPTIONAL: one core high
    # OPTIONAL: throttled
    # OPTIONAL: frequency
    # OPTIONAL: steal

    #==============================================================#
    #                       Node : Schedule                        #
    #==============================================================#
    # node load high : 1m avg standard load > 100% for 3m
    - alert: NodeLoadHigh
      expr: node:ins:stdload1 > 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeLoadHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:stdload1[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 100%


    #==============================================================#
    #                        Node : Memory                         #
    #==============================================================#
    # available memory < 10%
    - alert: NodeOutOfMem
      expr: node:ins:mem_avail < 0.10
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeOutOfMem {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:mem_avail[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} < 10%

    # commit ratio > 90%
    #- alert: NodeMemCommitRatioHigh
    #  expr: node:ins:mem_commit_ratio > 0.90
    #  for: 1m
    #  labels: { level: 1, severity: WARN, category: node }
    #  annotations:
    #    summary: 'WARN NodeMemCommitRatioHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
    #    description: |
    #      node:ins:mem_commit_ratio[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # OPTIONAL: EDAC Errors

    #==============================================================#
    #                        Node : Swap                           #
    #==============================================================#
    # swap usage > 1%
    - alert: NodeMemSwapped
      expr: node:ins:swap_usage > 0.01
      for: 5m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeMemSwapped {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:swap_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 1%

    #==============================================================#
    #                     Node : File System                       #
    #==============================================================#

    # filesystem usage > 90%
    - alert: NodeFsSpaceFull
      expr: node:fs:space_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFsSpaceFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:fs:space_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # inode usage > 90%
    - alert: NodeFsFilesFull
      expr: node:fs:inode_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFsFilesFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:fs:inode_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # file descriptor usage > 90%
    - alert: NodeFdFull
      expr: node:ins:fd_usage > 0.90
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeFdFull {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          node:ins:fd_usage[ins={{ $labels.ins }}] = {{ $value  | printf "%.2f" }} > 90%

    # OPTIONAL: space predict 1d
    # OPTIONAL: filesystem read-only
    # OPTIONAL: fast release on disk space

    #==============================================================#
    #                          Node : Disk                         #
    #==============================================================#
    # read latency > 32ms (typical on pci-e ssd: 100µs)
    - alert: NodeDiskSlow
      expr: node:dev:disk_read_rt_1m{device="dfa"} > 0.032 or node:dev:disk_write_rt_1m{device="dfa"} > 0.032
      for: 1m
      labels: { level: 2, severity: INFO, category: node }
      annotations:
        summary: 'INFO NodeReadSlow {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.6f" }}'
        description: |
          node:dev:disk_read_rt_1m[ins={{ $labels.ins }}] = {{ $value  | printf "%.6f" }} > 32ms

    # OPTIONAL: raid card failure
    # OPTIONAL: read/write traffic high
    # OPTIONAL: read/write latency high

    #==============================================================#
    #                        Node : Network                        #
    #==============================================================#
    # OPTIONAL: unusual network traffic
    # OPTIONAL: interface saturation high

    #==============================================================#
    #                        Node : Protocol                       #
    #==============================================================#

    # rate(node:ins:tcp_error[1m]) > 1
    - alert: NodeTcpErrHigh
      expr: rate(node:ins:tcp_error[1m]) > 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeTcpErrHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.2f" }}'
        description: |
          rate(node:ins:tcp_error{ins={{ $labels.ins }}}[1m]) = {{ $value  | printf "%.2f" }} > 1

    # node:ins:tcp_retrans_ratio1m > 1e-4
    - alert: NodeTcpRetransHigh
      expr: node:ins:tcp_retrans_ratio1m > 1e-2
      for: 1m
      labels: { level: 2, severity: INFO, category: node }
      annotations:
        summary: 'INFO NodeTcpRetransHigh {{ $labels.ins }}@{{ $labels.instance }} {{ $value  | printf "%.6f" }}'
        description: |
          node:ins:tcp_retrans_ratio1m[ins={{ $labels.ins }}] = {{ $value  | printf "%.6f" }} > 1%

    # OPTIONAL: tcp conn high
    # OPTIONAL: udp traffic high
    # OPTIONAL: conn track

    #==============================================================#
    #                          Node : Time                         #
    #==============================================================#

    - alert: NodeTimeDrift
      expr: node_timex_sync_status != 1
      for: 1m
      labels: { level: 1, severity: WARN, category: node }
      annotations:
        summary: 'WARN NodeTimeDrift {{ $labels.ins }}@{{ $labels.instance }}'
        description: |
          node_timex_status[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} != 0 or
          node_timex_sync_status[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} != 1


    # time drift > 64ms
    # - alert: NodeTimeDrift
    #   expr: node:ins:time_drift > 0.064
    #   for: 1m
    #   labels: { level: 1, severity: WARN, category: node }
    #   annotations:
    #     summary: 'WARN NodeTimeDrift {{ $labels.ins }}@{{ $labels.instance }}'
    #     description: |
    #       abs(node_timex_offset_seconds)[ins={{ $labels.ins }}]) = {{ $value | printf "%.6f" }} > 64ms

7 - FAQ

常见问题解答

如何配置 NTP 服务?

如果未配置 NTP,请使用公共 NTP 服务或与管理节点同步时间。

如果您的节点已经配置了 NTP,您可以通过将 node_ntp_enabled 设置为 false 来保持不变。

否则,如果您有互联网访问权限,您可以使用公共 NTP 服务,如 pool.ntp.org

如果您没有互联网访问权限,至少您可以使用以下方式与管理节点同步时间:

node_ntp_servers:                 # /etc/chrony.conf 中的 NTP 服务器
  - pool cn.pool.ntp.org iburst
  - pool ${admin_ip} iburst       # 假设非管理节点没有互联网访问权限

如何强制在节点上同步时间?

使用 chronyc 同步时间。您必须首先配置 NTP 服务。

ansible all -b -a 'chronyc -a makestep'     # 同步时间

您可以将 all 替换为任何组或主机 IP 地址来限制执行范围。


远程节点无法通过 SSH 命令访问。

如果目标机器隐藏在 SSH 跳板机后面,或者进行了一些自定义以至于无法使用 ssh ip 直接访问,请考虑使用 Ansible 连接参数。可以使用 ansible_portansible_host 指定 SSH 别名的额外 SSH 端口。

pg-test:
  vars: { pg_cluster: pg-test }
  hosts:
    10.10.10.11: {pg_seq: 1, pg_role: primary, ansible_host: node-1 }
    10.10.10.12: {pg_seq: 2, pg_role: replica, ansible_port: 22223, ansible_user: admin }
    10.10.10.13: {pg_seq: 3, pg_role: offline, ansible_port: 22224 }

远程节点 SSH 和 SUDO 需要密码

在执行部署和更改时,使用的管理员用户必须对所有节点具有 sshsudo 权限。不需要免密。

您可以在执行 playbook 时通过 -k|-K 参数传入 ssh 和 sudo 密码,甚至可以通过 -eansible_host=<another_user> 使用另一个用户运行 playbook。但是,Pigsty 强烈建议为管理员用户配置 SSH 免密登录和免密 sudo


使用现有管理员用户创建管理员用户。

这将使用该节点上的现有管理员用户创建由 node_admin_username 指定的管理员用户。

./node.yml -k -K -e ansible_user=<another_admin> -t node_admin

使用 HAProxy 公开节点服务

您可以在 node.yml 中使用 haproxy_services 公开服务。

这是使用它公开 MinIO 服务的示例:公开 MinIO 服务


为什么我的节点 /etc/yum.repos.d/* 被清除了?

Pigsty 将尝试在基础设施节点上的本地 yum 仓库中包含所有依赖项。此仓库文件将根据 node_repo_modules 添加。现有的仓库文件将根据 node_repo_remove 的默认值默认删除。这将防止节点使用互联网仓库或一些愚蠢的问题。

如果您想在节点初始化期间保留现有的仓库文件,只需将 node_repo_remove 设置为 false

如果您想在基础设施节点本地仓库引导期间保留现有的仓库文件,只需将 repo_remove 设置为 false


为什么我的 shell 提示符改变了,如何恢复?

pigsty 提示符在 /etc/profile.d/node.sh 中使用环境变量 PS1 定义。

要恢复您现有的提示符,只需删除该文件并重新登录。


腾讯 OpenCloudOS 兼容性问题

OpenCloudOS 没有 softdog 模块,在全局变量上覆盖 node_kernel_modules

node_kernel_modules: [ ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh ]