正如我在上一篇文章中提到的,有四种方法可以在 AWS 上分配虚拟 IP:
- 分配弹性 IP
- 分配辅助私有 IP
- 更新路由表
- 更新 Route53 记录
这篇文章描述了如何使用“更新路由表”的方法来配置和管理 AWS 上的虚拟 IP。
架构
在这篇文章中,我们在一个区域内的多个可用区中创建了三个 Pgpool-II 实例。
我们假设应用程序在同一个 VPC 中运行。下图显示了应用程序架构,应用程序实例位于公共子网中,Pgpool-II 实例位于私有子网中。
先决条件
在开始之前,请确保:
- 您创建了一个具有一个公有子网和三个私有子网的 PVC,并且每个私有子网位于不同的可用区中。
- 您已经创建了四个 EC2 实例。
- 您已经在每个 Pgpool-II 实例中安装了 Pgpool-II。
postgres您已经在每个 Pgpool-II 实例中创建了一个 Unix 用户。在本教程中,我们使用 Unix 用户运行 Ppgool-IIpostgres。- 您已经创建了一个 PostgreSQL 集群。
- 选择一个 IPv4 地址作为应用程序用来连接到 Pgpool-II 的虚拟 IP。此 IP 地址不应属于 VPC 的 IP 地址范围。
在这篇文章中,我们使用以下配置:
| 应用实例 | Pgpool-II #1 实例 | Pgpool-II #2 实例 | Pgpool-II #3 实例 | |
|---|---|---|---|---|
| 专有网络 | 10.0.0.0/16 | |||
| 虚拟IP | 20.0.0.50 | |||
| 子网 | 10.0.1.0/24 | 10.0.11.0/24 | 10.0.12.0/24 | 10.0.13.0/24 |
| 可用区 | us-west-2a | us-west-2a | us-west-2b | us-west-2c |
| 私有IP | 10.0.1.10 | 10.0.11.10 | 10.0.12.10 | 10.0.13.10 |
| 安全组 | SSH TCP 22 | 所有流量 所有 所有 10.0.0.0/16 | ||
安装和配置 AWS CLI
在本教程中,我们使用 AWS CLI 访问 AWS 服务和修改路由表。运行 AWS CLI 命令时,AWS CLI 需要凭证才能访问 AWS 服务。
本节介绍如何配置凭据设置。
在配置 AWS CLI 凭证之前,您需要有一个 AWS 账户和访问密钥。如果您没有任何现有的访问密钥,请从 AWS 管理控制台生成访问密钥。
在所有 Pgpool-II 实例上运行以下命令。
安装 AWS CLI。
[ec2-user@all pgpool instances]$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
[ec2-user@all pgpool instances]$ unzip awscliv2.zip
[ec2-user@all pgpool instances]$ sudo ./aws/install运行aws configure命令在 Pgpool-II 启动用户的主目录中创建配置和凭据文件。在本教程中,我们使用 Unix 用户运行 Pgpool-II postgres。
[ec2-user@all pgpool instances]$ sudo su - postgres
[postgres@all pgpool instances]$ aws configure
AWS Access Key ID [None]: <Your AWS Access Key ID>
AWS Secret Access Key [None]: <Your AWS Secret Access Key>
Default region name [None]: us-west-2
Default output format [None]: json确认 AWS CLI 是否配置正确。如果以下命令失败,请检查您的 AWS CLI 配置。
[postgres@all pgpool instances]$ TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
[postgres@all pgpool instances]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id
i-0a632a8349b701357配置 Pgpool-II
本节介绍如何安装和配置 Pgpool-II 参数以管理 AWS 上的虚拟 IP。本教程仅介绍虚拟 IP 相关的配置参数。其他配置请参考文档。
要分配和管理虚拟 IP,您需要配置以下配置参数。
1. 设置虚拟IP地址为delegate_IP。在这篇文章中,我们使用20.0.0.50.
delegate_IP = '20.0.0.50'2. 因为arping_cmd在 AWS 上不需要,所以设置arping_cmd = 'true'为始终返回成功退出状态。
arping_cmd = 'true'3.配置用于重写虚拟IP的路由条目if_up_cmd。if_down_cmd
if_up_cmd = '<path to script> up $_IP_$ <interface> <route table ID> <path to awscli>'
if_down_cmd = '<path to script> down $_IP_$ <interface> <route table ID> <path to awscli>'<path to script>:指定用于重写虚拟 IP 路由条目的脚本的路径。<interface>:指定网络接口。<route table ID>:指定与公共子网(应用程序实例)关联的路由表 ID。<path to awscli>:指定 AWS CLI 命令的路径。
以下示例显示了示例设置。用您自己的设置替换它们。
if_up_cmd = '/etc/pgpool-II/if_cmd.sh up $_IP_$ eth0 rtb-08ba4c1b34 /usr/local/bin/aws'
if_down_cmd = '/etc/pgpool-II/if_cmd.sh down $_IP_$ eth0 rtb-08ba4c1b34 /usr/local/bin/aws'if_cmd.sh在所有 Pgpool-II 实例上创建脚本。
[ec2-user@all pgpool instances]$ sudo su - postgres
[postgres@all pgpool instances]$ cat /etc/pgpool-II/if_cmd.sh #!/bin/bash CMD=$1 VIP=$2 LOCAL_INTERFACE=$3 ROUTE_TABLE_ID=$4 AWSCLI=$5 TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id) if [ "_${CMD}" == "_up" ]; then echo "running if_up_cmd" echo "create route entry for ${VIP}/32 if it doesn't exist" ${AWSCLI} ec2 create-route --route-table-id ${ROUTE_TABLE_ID} \ --destination-cidr-block ${VIP}/32 --instance-id ${INSTANCE_ID} if [ $? -ne 0 ]; then echo "replace route entry for ${VIP}/32"${AWSCLI}ec2 replace-route --route-table-id ${ROUTE_TABLE_ID} \ --destination-cidr-block ${VIP}/32 --instance-id ${INSTANCE_ID} --output text fi if [ $? -ne 0 ]; then echo "ERROR: failed to replace route entry for ${VIP}/32" exit 1 fi echo "assign virtual IP ${VIP}/32 to local network interface ${LOCAL_INTERFACE}" /usr/bin/sudo /sbin/ip addr add ${VIP}/32 dev ${LOCAL_INTERFACE} label ${LOCAL_INTERFACE}:1 if [ $? -ne 0 ]; then echo "ERROR: failed to assign virtual IP ${VIP}/32" exit 1 fi elif [ "_${CMD}" == "_down" ]; then echo "running if_down_cmd" echo "remove virtual IP ${VIP}/32 from local network interface ${LOCAL_INTERFACE}" /usr/bin/sudo /sbin/ip addr del ${VIP}/32 dev ${LOCAL_INTERFACE} if [ $? -ne 0 ]; then echo "ERROR: failed to remove virtual IP ${VIP}/32" fi echo "remove route entry for ${VIP}/32"${AWSCLI}已成功带入ec2 delete-route --route-table-id ${ROUTE_TABLE_ID} --destination-cidr-block ${VIP}/32 if [ $? -ne 0 ]; then echo "ERROR: failed to remove virtual IP ${VIP}/32" fi echo "remove remaining route entry if any" ip route show to exact ${VIP}/32 dev ${LOCAL_INTERFACE} | xargs -r ip route delete ip route show table local to exact ${VIP}/32 dev ${LOCAL_INTERFACE} | xargs -r ip route delete fi echo "virtual IP ${VIP}${CMD}" exit 0
使/etc/pgpool-II/if_cmd.sh可执行。
[postgres@all pgpool instances]$ chmod +x /etc/pgpool-II/if_cmd.sh禁用源/目标检查
EC2 实例默认检查任何接收到的流量的来源或目的地。
您必须在每个 Pgpool-II 实例上禁用源/目标检查,才能将虚拟 IP 的流量路由到目标实例。
要禁用源/目标检查,请在所有 Pgpool-II 实例上运行以下命令。
本教程假设本地的网络接口是 eth0。
[ec2-user@all pgpool instances]$ sudo su - postgres
[postgres@all pgpool instances]$ LOCAL_INTERFACE=eth0
[postgres@all pgpool instances]$ MAC_ADDR=$(ip -br link show dev ${LOCAL_INTERFACE} | tr -s ' ' | cut -d ' ' -f3)
[postgres@all pgpool instances]$ EC2_NETWORK_INTERFACE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDR}/interface-id)
[postgres@all pgpool instances]$ aws ec2 modify-network-interface-attribute --network-interface-id ${EC2_NETWORK_INTERFACE_ID} --no-source-dest-check启动 Pgpool-II
配置 Pgpool-II 后,使用以下命令启动 Pgpool-II。
[ec2-user@all pgpool instances]$ sudo systemctl start pgpool验证虚拟 IP
现在,让我们验证应用程序实例和虚拟 IP 之间的连接。
首先,使用 SSH 移动到应用程序实例。
然后ping虚拟IP,测试应用实例能否与虚拟IP 20.0.0.50通信。
您应该会看到类似于以下内容的输出:
[ec2-user@ip-10-0-1-10 ~]$ ping 20.0.0.50 -c 3
PING 20.0.0.50 (20.0.0.50) 56(84) bytes of data.
64 bytes from 20.0.0.50: icmp_seq=1 ttl=64 time=0.486 ms
64 bytes from 20.0.0.50: icmp_seq=2 ttl=64 time=0.532 ms
64 bytes from 20.0.0.50: icmp_seq=3 ttl=64 time=0.580 ms
--- 20.0.0.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2040ms
rtt min/avg/max/mdev = 0.486/0.532/0.580/0.046 ms接下来,停止领导者 Pgpool-II 以手动触发切换。在这个例子中,Pgpool-II #1是领导节点。
[ec2-user@ip-10-0-11-10 ec2-user]# sudo systemctl stop pgpool
然后,再次 ping 虚拟 IP。
[ec2-user@ip-10-0-1-10 ~]$ ping 20.0.0.50 -c 3
PING 20.0.0.50 (20.0.0.50) 56(84) bytes of data.
64 bytes from 20.0.0.50: icmp_seq=1 ttl=64 time=0.431 ms
64 bytes from 20.0.0.50: icmp_seq=2 ttl=64 time=0.535 ms
64 bytes from 20.0.0.50: icmp_seq=3 ttl=64 time=0.511 ms
--- 20.0.0.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2080ms
rtt min/avg/max/mdev = 0.431/0.492/0.535/0.048 ms上面的输出表明,即使将虚拟 IP 重新分配给另一个实例,应用程序实例也可以成功与虚拟 IP 20.0.0.50 通信。
原文标题:How to make Pgpool-II Leader Switchover Seamless on AWS - Updating Route Table
原文作者:Bo Peng
原文链接:https://b-peng.blogspot.com/2022/09/configuring-vip-route-table.html





