All Products
Search
Document Center

Elastic Compute Service:Detach an ENI from an ECS instance

Last Updated:Aug 11, 2023

This topic describes how to use Alibaba Cloud Elastic Compute Service (ECS) SDK for Java to detach an elastic network interface (ENI) from an ECS instance.

Scenarios

The operation used to detach an ENI from an instance is asynchronous. If you send a request to detach an ENI and obtain a response, the response indicates that the request is sent but does not indicate that the ENI is detached. Use the method that is described in one of the following examples based on your business scenario to check whether the ENI is detached from the instance:

  • Example 1: The method described in this example is suitable for scenarios that do not require low latency or a large amount of resources when you detach an ENI from an instance. You can poll for the state of an ENI and check whether the ENI is detached. If the operation is throttled, we recommend that you use the method described in Example 2.

  • Example 2: The method described in this example is suitable for scenarios that require low latency and a large amount of resources when you detach an ENI from an instance. You can use an event-driven architecture to check whether an ENI is detached. In this method, Message Service (MNS) is used to obtain messages and you are charged for using MNS.

Usage notes

  • Primary ENIs cannot be detached from ECS instances.

  • The ENI must be in the Detaching (Detaching) or InUse (InUse) state.

  • The ECS instance must be in the Running (Running) or Stopped (Stopped) state.

Example 1

The method described in this example is suitable for scenarios that do not require low latency or a large amount of resources when you detach an ENI from an instance. You can poll for the state of an ENI and check whether the ENI is detached.

  1. Run commands to detach the ENI.

  2. Poll the DescribeNetworkInterfaces operation to query the state of the ENI and check whether the ENI is detached.

Note
  • When you poll for the state of an ENI, we recommend that you use a backoff policy with intervals of 2 seconds, 1 second, 1 second, and 1 second.

  • You can poll for the state of an ENI up to 60 times per second.

  • In this example, Alibaba Cloud ECS SDK V2.0 is used.

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.DescribeNetworkInterfacesRequest;
import com.aliyun.ecs20140526.models.DescribeNetworkInterfacesResponse;
import com.aliyun.ecs20140526.models.DescribeNetworkInterfacesResponseBody.DescribeNetworkInterfacesResponseBodyNetworkInterfaceSetsNetworkInterfaceSet;
import com.aliyun.ecs20140526.models.DetachNetworkInterfaceRequest;
import com.aliyun.ecs20140526.models.DetachNetworkInterfaceResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;

/**
 * In this example, the DescribeNetworkInterfaces operation is polled to check whether the ENI is detached.
 */
public class DetachNetworkInterfaceWithEniDescribe {

    private static final String ENI_STATUS_INUSE = "InUse";
    private static final String ENI_STATUS_AVAILABLE = "Available";
    private static final String ENI_STATUS_DETACHING = "Detaching";
    private static final long DESC_INTERVAL_MS = 2000;

    /**
     * detach eni
     *
     * @param regionId
     * @param instanceId
     * @param eniId
     * @return
     */
    public static DetachNetworkInterfaceResponse detachNetworkInterface(Client ecsClient, String regionId,
        String instanceId, String eniId) {
        DetachNetworkInterfaceResponse response = null;
        try {
            DetachNetworkInterfaceRequest request = new DetachNetworkInterfaceRequest();
            request.setRegionId(regionId);
            request.setInstanceId(instanceId);
            request.setNetworkInterfaceId(eniId);
            // Specify a custom policy.
            RuntimeOptions runtime = new RuntimeOptions();
            response = ecsClient.detachNetworkInterfaceWithOptions(request, runtime);
            System.out.printf(
                "detach network interface %s from ecs instance %s send request success. Request id is %s.%n",
                eniId, instanceId, response.getBody().getRequestId());
        } catch (TeaException te) {
            System.out.println("ErrCode:" + te.getCode());
            System.out.println("ErrMsg:" + te.getMessage());
            System.out.println("RequestId:" + te.getData().get("RequestId"));
        } catch (Exception e) {
            System.out.println("ErrCode:" + e.getMessage());
        }
        return response;
    }

    /**
     * describe eni
     *
     * @param regionId
     * @param eniId
     * @return
     */
    public static DescribeNetworkInterfacesResponseBodyNetworkInterfaceSetsNetworkInterfaceSet describeNetworkInterface(
        Client ecsClient, String regionId, String eniId) {

        List<DescribeNetworkInterfacesResponseBodyNetworkInterfaceSetsNetworkInterfaceSet> networkInterfaceSetList;
        try {
            DescribeNetworkInterfacesRequest request = new DescribeNetworkInterfacesRequest();
            request.setRegionId(regionId);
            request.setNetworkInterfaceId(Collections.singletonList(eniId));
            // Specify a custom policy.
            RuntimeOptions runtime = new RuntimeOptions();
            DescribeNetworkInterfacesResponse response
                = ecsClient.describeNetworkInterfacesWithOptions(request, runtime);
            networkInterfaceSetList = response.getBody().getNetworkInterfaceSets().getNetworkInterfaceSet();
            if (networkInterfaceSetList != null && networkInterfaceSetList.size() > 0) {
                return networkInterfaceSetList.get(0);
            }
        } catch (TeaException te) {
            System.out.println("ErrCode:" + te.getCode());
            System.out.println("ErrMsg:" + te.getMessage());
            System.out.println("RequestId:" + te.getData().get("RequestId"));
        } catch (Exception e) {
            System.out.println("ErrCode:" + e.getMessage());
        }
        return null;
    }

    /**
     * Check whether eni successfully detached with max retry count
     *
     * @param ecsClient
     * @param regionId
     * @param eniId
     * @param maxDescTimes
     * @return
     */
    public static boolean isDetachNetworkInterfaceSuccess(Client ecsClient, String regionId, String eniId,
        int maxDescTimes) {
        boolean result = false;
        for (int i = 0; i < maxDescTimes; i++) {
            DescribeNetworkInterfacesResponseBodyNetworkInterfaceSetsNetworkInterfaceSet networkInterface
                = describeNetworkInterface(ecsClient, regionId, eniId);
            if (Objects.isNull(networkInterface)) {
                System.out.println("DescribeNetworkInterfaces return null, please check your input.");
                break;
            }
            if (ENI_STATUS_AVAILABLE.equals(networkInterface.getStatus())) {
                result = true;
                break;
            } else if (ENI_STATUS_INUSE.equals(networkInterface.getStatus())) {
                break;
            } else if (ENI_STATUS_DETACHING.equals(networkInterface.getStatus())) {
                System.out.printf("This is the %s times describe networkInterface, eni id %s is still detaching.%n",
                    i + 1, eniId);
            } else {
                System.out.printf(
                    "This is the %s times describe networkInterface, eni id %s status is %s, please check before "
                        + "detach.%n",
                    i + 1, eniId, networkInterface.getStatus());
                break;
            }
            interval(DESC_INTERVAL_MS);
        }
        return result;
    }

    public static void interval(long intervalMs) {
        try {
            Thread.sleep(intervalMs);
        } catch (InterruptedException ignored) {

        }
    }

    /**
     * Initialize the client by using your AccessKey ID and AccessKey secret. 
     *
     * In this example, the AccessKey pair that is used for authentication is retrieved from environment variables. Make modifications based on your production environment in actual scenarios. 
     * Do not store critical information, such as AccessKey IDs and AccessKey secrets, in plaintext in the code. 
     *
     * @return Client
     * @throws Exception
     */
    public static Client createClient() throws Exception {
        Config config = new Config()
            .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
            .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "<yourEcsEndPoint>";
        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        String regionId = "<regionId>";
        String eniId = "<yourEniId>";
        String ecsInstanceId = "<yourEcsInstanceId>";
        int maxRetryCnt = 3;

        Client ecsClient = createClient();

        detachNetworkInterface(ecsClient, regionId, ecsInstanceId, eniId);
        if (isDetachNetworkInterfaceSuccess(ecsClient, regionId, eniId, maxRetryCnt)) {
            System.out.printf(
                "Async detach network interface %s success.", eniId);
        } else {
            System.out.printf(
                "Async detach network interface %s fail. Please try again.", eniId);
        }
    }
}

Example 2

The method described in this example is suitable for scenarios that require low latency and a large amount of resources when you detach an ENI from an instance. You can use an event-driven architecture to check whether an ENI is detached. In this method, MNS is used to obtain messages and you are charged for using MNS. For information about the billing of MNS, see Pricing.

Preparations

  1. Create a queue. For more information, see Create a queue.

    In this example, a queue named eni-operate-completed-event is created, and the default settings of other parameters are used for the queue.

  2. Create a system event-triggered alert rule. For more information, see Create a system event-triggered alert rule.

    Configure the following parameters:

    • Alert Rule Name: Specify a name for the rule. In this example, enter eni-event-test-rule.

    • Product Type: Select Elastic Compute Service (ECS).

    • Event Type: Select Status Notification.

    • Event Level: Select INFO. Event Name: Select NetworkInterface:NetworkInterfaceOperateCompleted. Resource Range: Use the default setting. You can modify the setting based on your business requirements.

    • Notification Method: Select Message Service - Queue, set Queue to eni-operate-completed-event that you created, and then set Region.

Sample code

Run the sample code to listen to MNS messages and check whether an ENI is detached. To download the sample code, click NetworkInterfaceDemo.zip.

  1. Run commands to detach the ENI.

  2. Obtain MNS messages to check whether the ENI is detached.

References

DetachNetworkInterface