1. 首页
  2. 运维开发
  3. Python

用Python实现阿里云ecs主机公网IP的切换功能

对于采集、注册或者代理来说,如果服务器公网IP可以自动切换,那么可能会少很多麻烦。最近博主就使用阿里云的api实现了这个小功能。实现的步骤比较简单,首先需要申请阿里云的api key。然后申请vpc专有网络,普通经典ecs主机无法挂载弹性IP,在刚刚申请的专有网络中开通一台ecs服务器。接着申请弹性公网IP。最后把这个公网IP挂载到专有网络下的ecs。完成后付费包括两部分,一个是ecs费用(包年或包月,预付费),另外是弹性公网eip的费用(按量、后付费)。

接下来开始用python来实现下。阿里云提供了python的sdk,这里博主就直接用sdk了。

第一步:创建vpc和ecs

这个直接在阿里云页面上创建就可以。

第二步:安装sdk

pip install aliyun-python-sdk-ecs

不清楚的可以参考阿里云:https://develop.aliyun.com/sdk/python

第三步:弹性公网IP方法

代码类似如下:

申请

def create_eip_address(regionid='cn-hongkong',chargetype='PayByBandwidth',bandwidth=1,fmt='json'):
    request=AllocateEipAddressRequest.AllocateEipAddressRequest()
    request.set_accept_format(fmt)
    request.set_Bandwidth(bandwidth)
    request.add_query_param('RegionId',regionid)
    request.add_query_param('InternetChargeType',chargetype)
    
    try:
        result=clt.do_action(request)
        r_dict=json.loads(result)
    except:
        print("Create EIP Address Failed.")
        sys.exit()
    
    if r_dict.has_key('EipAddress'):
        res={}
        res['ip']=r_dict['EipAddress']
        res['id']=r_dict['AllocationId']
        return res
    else:
        print(r_dict['Message'])
        sys.exit()

删除

def delete_eip_address(eipid,fmt='json'):
    request=ReleaseEipAddressRequest.ReleaseEipAddressRequest()
    request.set_accept_format(fmt)
    request.set_AllocationId(eipid)
    try:
        result=clt.do_action(request)
        r_dict=json.loads(result)
    except:
        print("Delete EIP Address Failed.")
        sys.exit()
    
    if r_dict.has_key('Code'):
        print(r_dict['Message'])
        sys.exit()
    else:
        return r_dict

绑定

def associate_eip_address(allocationid,instanceid,instancetype='EcsInstance',fmt='json'):
    request=AssociateEipAddressRequest.AssociateEipAddressRequest()
    request.set_accept_format(fmt)
    request.set_AllocationId(allocationid)
    request.add_query_param('InstanceType',instancetype)
    request.set_InstanceId(instanceid)
    try:
        result=clt.do_action(request)
        r_dict=json.loads(result)
    except:
        print("Associate EIP Address Failed.")
        sys.exit()
        
    if r_dict.has_key('Code'):
        print(r_dict['Message'])
        sys.exit()
    else:
        return r_dict

解绑

def unassociate_eip_address(allocationid,instanceid,instancetype='EcsInstance',fmt='json'):
    request=UnassociateEipAddressRequest.UnassociateEipAddressRequest()
    request.set_accept_format(fmt)
    request.set_AllocationId(allocationid)
    request.add_query_param('InstanceType',instancetype)
    request.set_InstanceId(instanceid)
    try:
        result=clt.do_action(request)
        r_dict=json.loads(result)
    except:
        print("Unassociate EIP Address Failed.")
        sys.exit()
        
    if r_dict.has_key('Code'):
        print(r_dict['Message'])
        sys.exit()
    else:
        return r_dict

以上就是一些弹性公网IP的4个方法,分别实现IP的申请、删除、绑定和解绑的功能。

第四步:更换IP

更换IP步骤:

获取ECS信息 --有EIP--> 解绑EIP -> 删除老EIP -->申请新EIP --> 绑定新EIP到ECS
    |                                              ^
    |                                              |
    -------------------无EIP------------------------

在删除老的公网IP前需要判断是否真的解绑,不然解绑请求提交给阿里云后马上删除老的EIP可能会因为eip还未解绑而报错。

代码类似如下:

def main():
    #获取当前vpc下ecs主机的eip
    instance=instance_info(ecs_vpc_id)
    eip_id=instance['EipAddress']['AllocationId']
    eip_ip=instance['EipAddress']['IpAddress']
    if not instance:
        print("Get instance info error.")
        sys.exit()
    else:
        if not eip_id:
            print("Instance %s has not associate eip address.") % ecs_vpc_id
        else:
            print("Instance: %s ,Eip id: %s .") % (ecs_vpc_id,eip_id)
    
            #解绑eip
            result_unassociate=unassociate_eip_address(eip_id, ecs_vpc_id)
            if not result_unassociate:
                print("Unassociate eip address from %s error.") % ecs_vpc_id
                sys.exit()
            
            #判断真正解绑后开始删除老的eip
            while True:
                eip_id_tmp=instance_info(ecs_vpc_id)['EipAddress']['AllocationId']
                if not eip_id_tmp:
                    #删除老的eip
                    result_release=delete_eip_address(eip_id)
                    if not result_release:
                        print("Release eip %s error.") % eip_id
                        sys.exit()
                    break
                else:
                    continue
                time.sleep(1)
    
    #申请新eip
    result_allocate=create_eip_address(bandwidth=eip_bandwidth)
    if not result_allocate:
        print("Allocate new eip address error.")
        sys.exit()
    
    #time.sleep(10)
    
    #绑定eip
    result_associate=associate_eip_address(result_allocate['id'], instanceid=ecs_vpc_id)
    if not result_associate:
        print("Associate eip %s to instance %s error.") % (result_allocate,ecs_vpc_id)
        sys.exit()
    else:
        print("Associate eip %s to instance %s successfully.") % (result_allocate['ip'],ecs_vpc_id)
        ip_dict={
            'oip':eip_ip,
            'nip':result_allocate['ip']
        }
        return ip_dict

 

以上代码我放在github上,地址:https://github.com/zhangnq/scripts/tree/master/python/aliyun,感兴趣的朋友也可以看下。

更换公网IP后,如果你需要修改dns解析记录,那么可以参考之前dnspod的api实现ddns这篇文章。

如果还有其他操作,那么也可以按照自己需求来实现。

参考网址:

使用dnspod和python动态域名解析ddns脚本实例

联系我们

0574-55011290

QQ:248687950

邮件:admin@nbhao.org

工作时间:周一至周五,9:00-18:00,节假日休息

QR code