本教程详细介绍如何使用Alibaba Cloud SDK for Java从已有ECS实例中分离出一个弹性网卡到新的ECS实例(VPC)。

前提条件

在使用本教程之前,请确保已完成以下操作:
  • 使用ECS管理控制台或通过API获取您需要的ECS实例ID,API接口请参见DescribeInstances
  • 使用Alibaba Cloud SDK for Java,您需要一个阿里云账号和访问密钥(AccessKey)。 请在阿里云控制台中的AccessKey管理页面上创建和查看您的AccessKey。
  • 确保您已经安装了Alibaba Cloud SDK for Java,准确的SDK版本号,请参见 阿里云开发工具包(SDK)
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.4.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-ecs-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-ecs</artifactId>
            <version>4.17.4</version>
        </dependency>
    </dependencies>

代码示例

说明 本示例有以下4点需要注意:
  • 弹性网卡必须处于可用(Available)状态。
  • 实例必须处于运行中(Running)或者已停止(Stopped)状态。
  • 弹性网卡只能附加到 VPC 类型实例,且必须与实例在同一 VPC 内。
  • 由于 VPC 虚拟交换机不能跨可用区,弹性网卡附加的实例与弹性网卡所在的交换机必须属于同一可用区。
本文操作示例主要以代码形式体现,具体代码如下:
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;

/**
 *  从实例中分离一个弹性网卡到新的实例(VPC类型)
 *
 *     AssignPrivateIpAddresses    为一块弹性网卡分配一个或多个辅助私有IP地址
 *     AttachNetworkInterface    附加弹性网卡(ENI)到专有网络(VPC)类型实例上
 *     DetachNetworkInterface    从一台实例上分离一个弹性网卡(ENI)
 *     DescribeNetworkInterfaces    查看弹性网卡(ENI)列表
 */
public class Demo {

    // 需要添加弹性网卡的实例ID(请您自行配置)
    private static String dBinstanceId = "";

    public static void main(String[] args) {
        // 初始化公共请求参数
        IAcsClient client = Initialization();
        // 查看弹性网卡(ENI)列表
        List<DescribeNetworkInterfacesResponse.NetworkInterfaceSet> networkInterfaceSets = DescribeNetworkInterfaces(client);
        // 请根据实际需求选择要分离的弹性网卡
        DescribeNetworkInterfacesResponse.NetworkInterfaceSet networkInterfaceSet = networkInterfaceSets.get(0);
        // 弹性网卡ID
        String networkInterfaceId = networkInterfaceSet.getNetworkInterfaceId();
        // 原弹性网卡所在实例ID
        String instanceId = networkInterfaceSet.getInstanceId();
        // 从一台实例上分离一个弹性网卡(ENI)
        int i = DetachNetworkInterface(client, instanceId, networkInterfaceId);
        if ( i == 1 ){
            // 附加弹性网卡(ENI)到专有网络(VPC)类型实例上
            AttachNetworkInterface(client, networkInterfaceId, dBinstanceId);
            // 为一块弹性网卡分配一个或多个辅助私有IP地址
            AssignPrivateIpAddresses(client, networkInterfaceId);
        }
    }

    /**
     * AssignPrivateIpAddresses    为一块弹性网卡分配一个或多个辅助私有IP地址
     */
    private static void AssignPrivateIpAddresses(IAcsClient client, String networkInterfaceId) {
        AssignPrivateIpAddressesRequest request = new AssignPrivateIpAddressesRequest();
        request.setNetworkInterfaceId(networkInterfaceId);
        List<String> privateIpAddressList = new ArrayList<String>();
        privateIpAddressList.add("172.30.**.***");
        privateIpAddressList.add("172.16.**.***");
        request.setPrivateIpAddresss(privateIpAddressList);
        try {
            AssignPrivateIpAddressesResponse response = client.getAcsResponse(request);
            System.out.println("--------------------为附加的弹性网卡分配IP地址--------------------");
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * AttachNetworkInterface    附加弹性网卡(ENI)到专有网络(VPC)类型实例上
     */
    private static void AttachNetworkInterface(IAcsClient client, String networkInterfaceId, String dBinstanceId) {
        AttachNetworkInterfaceRequest request = new AttachNetworkInterfaceRequest();
        // 实例ID。
        request.setInstanceId(dBinstanceId);
        // 弹性网卡ID
        request.setNetworkInterfaceId(networkInterfaceId);
        try {
            AttachNetworkInterfaceResponse response = client.getAcsResponse(request);
            System.out.println("--------------------附加弹性网卡到VPC类型的实例--------------------");
            System.out.println(new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
    }

    /**
     * DetachNetworkInterface    从一台实例上分离一个弹性网卡(ENI)
     */
    private static int DetachNetworkInterface(IAcsClient client, String instanceId, String networkInterfaceId) {
        DetachNetworkInterfaceRequest request = new DetachNetworkInterfaceRequest();
        // 实例ID
        request.setInstanceId(instanceId);
        // 弹性网卡ID
        request.setNetworkInterfaceId(networkInterfaceId);
        try {
            DetachNetworkInterfaceResponse response = client.getAcsResponse(request);
            System.out.println("--------------------从ECS实例上分离一个弹性网卡(ENI)--------------------");
            System.out.println(new Gson().toJson(response));
            return 1;
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
        return 0;
    }


    /**
     * DescribeNetworkInterfaces    查看弹性网卡(ENI)列表
     */
    private static List<DescribeNetworkInterfacesResponse.NetworkInterfaceSet> DescribeNetworkInterfaces(IAcsClient client) {

        DescribeNetworkInterfacesRequest request = new DescribeNetworkInterfacesRequest();
        // 弹性网卡类型。取值范围:Primary  Secondary
        request.setType("Secondary");
        try {
            DescribeNetworkInterfacesResponse response = client.getAcsResponse(request);
            System.out.println("--------------------查询弹性网卡(ENI)列表--------------------");
            System.out.println(new Gson().toJson(response));
            return response.getNetworkInterfaceSets();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
        return null;
    }

    /**
     * Initialization  初始化公共请求参数
     */
    private static IAcsClient Initialization() {
        // 初始化请求参数
        DefaultProfile profile = DefaultProfile.getProfile(
                "<your-region-id>", // 您的可用区ID
                "<your-access-key-id>", // 您的AccessKey ID
                "<your-access-key-secret>"); // 您的AccessKey Secret
        return new DefaultAcsClient(profile);
    }
}

执行结果

正确的返回结果类似如下:
--------------------查询弹性网卡(ENI)列表--------------------
{
    "requestId": "75550A74-C6F3-4452-9640-6D3B3DE0F4B5", 
    "totalCount": 5, 
    "pageNumber": 1, 
    "pageSize": 10, 
    "networkInterfaceSets": [
        {
            "networkInterfaceId": "eni-bp16v0fuhulfl5e1cna3", 
            "status": "Available", 
            "type": "Secondary", 
            "vpcId": "vpc-bp1m7v25emi1h5mtcyq80", 
            "vSwitchId": "vsw-bp11abbpsn47afia34nsr", 
            "zoneId": "cn-hangzhou-b", 
            "privateIpAddress": "192.168.100.3", 
            "macAddress": "00:16:3e:12:47:27", 
            "networkInterfaceName": "ghg", 
            "instanceId": "", 
            "creationTime": "2019-09-02T08:24:45Z", 
            "resourceGroupId": "", 
            "privateIpSets": [], 
            "tags": [ ], 
            "securityGroupIds": [], 
            "associatedPublicIp": { }
        }
    ]
}
--------------------从ECS实例上分离一个弹性网卡(ENI)--------------------
{
"RequestId":"04F0F334-1335-436C-A1D7-6C044FExxxxx"
}
--------------------附加弹性网卡到VPC类型的实例--------------------
{
"RequestId":"04F0F334-1335-436C-A1D7-6C044FExxxxx"
}
--------------------为附加的弹性网卡分配IP地址--------------------
{
"RequestId":"04F0F334-1335-436C-A1D7-6C044FE70008"
}