虚拟IP(VIP)是一种网络模式,它允许管理员快速将IP地址从一台服务器移动到另一台服务器,而几乎不会停机,也称为浮动IP,如果手动切换服务器的速度超过DNS 的TTL时,最好配上keepalived。
在私有环境中部署keepalived本身并没有好说的,但是aws中存在诸多限制,其中三个需要明确指出的:
1. VRRP协议的组播被禁止,也就是说keepalived需要调整心跳的通知方式,修改/etc/keepalived/keepalived.conf配置文件中的通知为单播模式,一般配web 服务器上数量较少,所以也不会损失太多网络带宽。
2. 配置了VIP(floating ip)以后,AWS的VPC并不知道,尝试下arp也学习不到该vip的mac地址,所以必须要通过配置ENI(Elastic Network Interface弹性网络接口)使得该VIP可达。
3. 然而当你关了Master以后,ENI的网络配置并不会自动切换漂移IP,为了故障切换,我利用切换VIP的通知机制,通过调用添加和移除private-ip-addresses的方式达到漂移IP的效果。下面详细介绍。
1. 准备
IAM 账户
进入控制台/服务/IAM中去创建一个账号,然后创建一个系统管理员的组,把这个账号加入到组中,这个过程中会得到Access Key ID和Secret Access Key。在服务器上运行aws configure,填入Access Key ID和Secret Access Key(其中Access Key ID是用于集群查Secret Access Key的一个key,而Secret Access Key用作客户端数据的加密和服务端数据的解密)还有region就完成注册了。
region是指你服务器所在的区域,比如us-east-2。同时脚本还需要安装jq, aws cli。在部署keepalived的节点上安装下:
apt install jq
apt install aws cli
添加/移除IP的脚本
assign_private_ip.sh
#!/bin/bash
###### ###### ###### ###### ###### ###### ###### ######
# Description:
#
# attaches an IP of your choice to the primary NIC
# an instance you specify
#
# Setup:
#
# You need, at a minimum, the following permissions:
# {
# "Statement": [
# {
# "Action": [
# "ec2:AssignPrivateIpAddresses",
# "ec2:DescribeInstances"
# ],
# "Effect": "Allow",
# "Resource": "*"
# }
# ]
# }
#
# Usage:
#
# ./assign_private_ip.sh ip_address instance_id
#
# Example:
# ./assign_private_ip.sh '10.0.3.15' 'i-100ffabd'
#
###### ###### ###### ###### ###### ###### ###### ######
# http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -o errexit
set -o nounset
IP=$1
INSTANCE_ID=$2
ENI=$(\
aws ec2 describe-instances \
--instance-ids $INSTANCE_ID | \
jq -r \
'.Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' \
)
echo "Adding IP $IP to ENI $ENI"
aws ec2 assign-private-ip-addresses \
--network-interface-id $ENI \
--private-ip-addresses $IP \
--allow-reassignment
unassign_private_ip.sh
#!/bin/bash
###### ###### ###### ###### ###### ###### ###### ######
# Description:
#
# attaches an IP of your choice to the primary NIC
# an instance you specify
#
# Setup:
#
# You need, at a minimum, the following permissions:
# {
# "Statement": [
# {
# "Action": [
# "ec2:AssignPrivateIpAddresses",
# "ec2:DescribeInstances"
# ],
# "Effect": "Allow",
# "Resource": "*"
# }
# ]
# }
#
# Usage:
#
# ./unassign_private_ip.sh ip_address instance_id
#
# Example:
# ./unassign_private_ip.sh '10.0.3.15' 'i-100ffabd'
#
###### ###### ###### ###### ###### ###### ###### ######
# http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -o errexit
set -o nounset
IP=$1
INSTANCE_ID=$2
ENI=$(\
aws ec2 describe-instances \
--instance-ids $INSTANCE_ID | \
jq -r \
'.Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' \
)
echo "Removing IP $IP from ENI $ENI"
aws ec2 unassign-private-ip-addresses \
--network-interface-id $ENI \
--private-ip-addresses $IP
安装/配置keepalived
/etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_script check_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 3
weight -2
fall 10
rise 2
}
vrrp_instance VI_1 {
state MASTER
notify_master "/root/assign_private_ip.sh 172.31.40.156 i-04257c267fb6923f7"
notify_backup "/root/unassign_private_ip.sh 172.31.40.156 i-04257c267fb6923f7"
unicast_src_ip 172.31.40.155
unicast_peer {
172.31.38.87
}
interface eth0
virtual_router_id 51
priority 101
authentication {
auth_type PASS
auth_pass 4be37dc3b4c90194d1600c483e10ad1d
}
virtual_ipaddress {
172.31.40.156
}
track_script {
check_apiserver
}
}
其他节点类似。只是state,改为backup就好了,backup节点的优先级改为100,下面对掉下:
unicast_src_ip 172.31.40.155
unicast_peer {
172.31.38.87
}
现在验证下,systemctl stop keepalived.service。发现vip发生了漂移,并且集群内可达。