一、介绍
阿里云不支持使用keepalived等服务器的vip使用,所以只能使用阿里云的ENI(弹性网卡)来实现
弹性网卡(Elastic Network Interface,简称ENI)是一种可以附加到专有网络VPC类型ECS实例上的虚拟网卡。通过弹性网卡,您可以在任何阿里云地域下实现高可用集群搭建、低成本故障转移和精细化的网络管理。
官方文档:https://help.aliyun.com/document_detail/58496.html?spm=a2c4g.11186623.6.824.771060e0Ke0wH1
二、创建弹性网卡


三、使用弹性网卡


绑定完几秒钟后内网就能通了
四、控制ENI的demo(python3)
1、python3 SDK 安装
pip3 install aliyun-python-sdk-core pip3 install aliyun-python-sdk-ecs
2、访问控制权限
管理阿里云ECS权限
3、控制ENI的demo
#!/usr/bin/env python3
#coding=utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526.AttachNetworkInterfaceRequest import AttachNetworkInterfaceRequest
from aliyunsdkecs.request.v20140526.DetachNetworkInterfaceRequest import DetachNetworkInterfaceRequest
import sys
from time import sleep
AccessKeyId = 'AccessKeyId'
AccessKeySecret = 'AccessKeySecret'
Endpoint = 'cn-qingdao'
remove_ecs_id = sys.argv[1] #传递移除网卡的ecs_id
ENI_ID = 'xxxx' #弹性辅助网卡ENI的id
ECS_ID_LIST = ['xxxx','xxxxx'] #ENI网卡绑定的ecs集群列表
try:
ECS_ID_LIST.remove(remove_ecs_id)
except Exception as e:
print(e)
exit(1)
add_ecs_id = ECS_ID_LIST[0] #选一个可以用的ecs的id,做为网卡绑定的服务器
def remove_vip(remove_ecs_id,ENI_ID):
'''解绑函数'''
client = AcsClient(AccessKeyId,AccessKeySecret,Endpoint) #建议不要使用变量,直接输入字符串
request = DetachNetworkInterfaceRequest()
request.set_accept_format('json')
request.set_InstanceId(remove_ecs_id)
request.set_NetworkInterfaceId(ENI_ID)
try:
response = client.do_action_with_exception(request)
except Exception as e:
print(e)
exit(2)
print(str(response, encoding='utf-8'))
return True
def add_vip(add_ecs_id,ENI_ID):
'''绑定函数'''
client = AcsClient(AccessKeyId,AccessKeySecret,Endpoint) #建议不要使用变量,直接输入字符串
request = AttachNetworkInterfaceRequest()
request.set_accept_format('json')
request.set_NetworkInterfaceId(ENI_ID)
request.set_InstanceId(add_ecs_id)
try:
response = client.do_action_with_exception(request)
except Exception as e:
print(e)
exit(3)
print(str(response, encoding='utf-8'))
if __name__ == '__main__':
ret = remove_vip(remove_ecs_id,ENI_ID)
if ret:
add_vip(add_ecs_id,ENI_ID)
五、结合keepalived的单播模式使用
1、keepalived试例配置文件
! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc #发送邮箱 } notification_email_from Alexandre.Cassen@firewall.loc #邮箱地址 smtp_server 127.0.0.1 #邮件服务器地址 smtp_connect_timeout 30 router_id LVS_DEVEL-01 #主机名,每个节点不同即可 } vrrp_instance VI_1 { state MASTER #节点主从,在另一个节点上为BACKUP interface eth0 #IP地址漂移到的网卡 virtual_router_id 51 #多个节点必须相同 priority 100 #优先级,备用节点的值必须低于主节点的值 advert_int 1 #通告间隔1秒 authentication { auth_type PASS #预共享密钥认证 auth_pass 1111 #密钥 } unicast_src_ip 172.31.0.204 #本机地址 unicast_peer { 172.31.0.205 #目标地址 } virtual_ipaddress { 192.168.1.100/24 dev eth0 #VIP地址 } }
! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_DEVEL-02 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } unicast_src_ip 172.31.0.205 unicast_peer { 172.31.0.204 } virtual_ipaddress { 192.168.1.100/24 dev eth0 } }
2、检查脚本(未测试过的脚本,可以根据思路自己修改或测试)
结合了rsync使用
#!/bin/bash
source /etc/init.d/functions
vip=192.168.1.100 #虚拟vip
local_ip=172.31.0.204 #本机ip
rsync_module_ip=172.31.0.205 #rsync目标的ip
ecs_id_file=/tmp/ecs_id.txt #保存弹性网卡所在的ecs的id名称(ecsID)
declare -A arr
arr["172.31.0.204"]="ecs的id" #内网ip作为key,ecs的id作为value
arr["172.31.0.205"]="ecs的id"
if [ `ip a s eth0|egrep -o ${vip}|wc -l` -eq 1 ];then #判断是否拥有vip
if [ `cat ${ecs_id_file}|wc -l` -eq 1 ];then #判断文件是否有内容
if `cat ${ecs_id_file}` != ${arr[${local_ip}]};then #判断ecs_id_file文件中记录的ecsID和本机的ecsID是否相同
python3 ENI.py ${arr[${rsync_module_ip}]} #执行脚本(python控制ENI的脚本)
echo ${arr[${local_ip}]} > ${ecs_id_file}
rsync -avz ${ecs_id_file} module_user@${rsync_module_ip}::aliyun_eni_module --password-file=/etc/rsync.password
else
rsync -avz ${ecs_id_file} module_user@${rsync_module_ip}::aliyun_eni_module --password-file=/etc/rsync.password
fi
else
# unset arr[${local_ip}] #删除arr中的本机的变量内容
python3 ENI.py ${arr[${rsync_module_ip}]} #执行脚本(python控制ENI的脚本)
if [ $? -eq 0 ];then #判断执行是否失败
#脚本执行成功,覆盖文件内容
echo ${arr[${local_ip}]} > ${ecs_id_file}
#rsync覆盖给另一台服务器的ecs_id_file文件(建议使用rsync的demon)
rsync -avz ${ecs_id_file} module_user@${rsync_module_ip}::aliyun_eni_module --password-file=/etc/rsync.password
else
#执行失败了操作
action "python3 scripts carried out Fail ${rsync_module_ip}" /bin/false
fi
fi
fi

