All Products
Search
Document Center

:Enable multiple applications to share bandwidth (sample code)

Last Updated:Sep 21, 2023

This topic describes how to enable multiple applications to share the bandwidth of an Internet Shared Bandwidth by calling an API operation through Alibaba Cloud SDK for Python. This reduces the data egress costs.

Scenario

A company creates two Elastic Compute Service (ECS) instances and deploys an application on each ECS instance. The ECS instances need to receive requests from the Internet. The service port is port 80. The amount of bandwidth required by the two ECS instances varies within a day:
  • The peak hours of ECS 1 range from 13:00:00 to 18:00:00. During this period of time, the bandwidth required is 1,000 Mbit/s. During the remaining hours of the day, the bandwidth required is 500 Mbit/s.
  • The peak hours of ECS 2 range from 19:00:00 to 23:00:00. During this period of time, the bandwidth required is 1,000 Mbit/s. During the remaining hours of the day, the bandwidth required is 500 Mbit/s.

If you want to purchase bandwidth for the ECS instances separately, you must purchase two bandwidth plans with a total bandwidth of 2,000 Mbit/s. However, the ECS instances cannot make full use of the bandwidth during off-peak hours. This causes bandwidth resource wastes.

To resolve this problem, you can configure Destination Network Address Translation (DNAT) for your NAT gateway and purchase EIP bandwidth plans.
  • DNAT maps elastic IP addresses (EIPs) to ECS instances in a virtual private cloud (VPC). Then, the ECS instances can receive requests from the Internet.
  • An EIP bandwidth plan can be shared among multiple applications to reduce the costs of Internet data transfer.
Scenario

Prerequisites

Before you start, make sure that the following requirements are met:

  • An Alibaba Cloud account is created. If you do not have an Alibaba Cloud account, create one.

  • An AccessKey pair is created. If you do not have an AccessKey pair, go to the Security Management page and create an AccessKey pair.

  • A Python development environment is prepared and Alibaba Cloud SDK for Python is installed. For more information, see Get started with Classic SDK for Python.

  • A virtual private cloud (VPC) and a vSwitch are created. For more information, see CreateVpc.

  • An Elastic Compute Service (ECS) instance is created in the vSwitch. Applications are deployed on the ECS instance. For more information, see CreateInstance.

  • Two elastic IP addresses (EIPs) are created for the NAT gateway. The EIPs must meet the following requirements:

    • The EIPs and the NAT gateway must belong to the same region.

    • The EIPs are billed on a pay-as-you-go basis.

    For more information, see AllocateEipAddress.

Procedure

Procedure

Step 1: Create a NAT gateway

NAT gateways are enterprise-class gateways that provide network address translation services. You must create a NAT gateway before you can create DNAT entries.

Note

When you create an enhanced NAT gateway, you must specify a vSwitch for the NAT gateway. Then, the system assigns an idle private IP address from the vSwitch to the NAT gateway.

  • If you want to create and attach an enhanced NAT gateway to an existing vSwitch, make sure that the zone to which the vSwitch belongs supports enhanced NAT gateways. In addition, the vSwitch must have idle IP addresses.

  • If you do not have a vSwitch, you must create a vSwitch in a zone that supports enhanced NAT gateways before you can create an enhanced NAT gateway. Then, you can specify the vSwitch for the enhanced NAT gateway.

You can call ListEnhanhcedNatGatewayAvailableZones to query the zones that support enhanced NAT gateways and call DescribeVSwitches to query idle IP addresses in a vSwitch.

  1. The following sample code shows how to create a NAT gateway:

    from alibabacloud_credentials.client import Client as CredClient
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException
    from aliyunsdkcore.acs_exception.exceptions import ServerException
    from aliyunsdkvpc.request.v20160428.CreateNatGatewayRequest import CreateNatGatewayRequest
    
    # Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
    # We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
    # In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
    cred = CredClient()
    access_key_id = cred.get_access_key_id()
    access_key_secret = cred.get_access_key_secret()
    
    # Create an AcsClient instance.
    client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')
    
    # Create a NAT gateway.
    request = CreateNatGatewayRequest()
    request.set_accept_format('json')
    
    # The ID of the VPC where the NAT gateway is deployed.
    request.set_VpcId("vpc-bp1fu6qir3kh9017q****")
    
    # The name of the NAT gateway.
    request.set_Name("test")
    
    # The description of the NAT gateway.
    request.set_Description("test")
    
    # The billing method of the NAT gateway.
    # Set the value to PostPaid. This is the default value.
    request.set_InstanceChargeType("PostPaid")
    
    # The ID of the vSwitch to which the NAT gateway is attached.
    # When you create an enhanced NAT gateway, you must specify a vSwitch. The system automatically assigns an idle private IP address from the vSwitch to the enhanced NAT gateway.
    request.set_VSwitchId("vsw-bp1nz9748zh312m37****")
    
    # The type of the NAT gateway.
    # Valid values: Normal and Enhanced. Normal: indicates a standard NAT gateway. Enhanced: indicates an enhanced NAT gateway.
    # Enhanced NAT gateways are an upgrade from standard NAT gateways and use a more advanced architecture. Compared with standard NAT gateways, enhanced NAT gateways offer higher elasticity and stability. This improves how you can manage data transfer.
    request.set_NatType("Enhanced")
    
    # The metering method of the NAT gateway.
    # Set the value to PayByLcu, which indicates the pay-by-LCU metering method.
    request.set_InternetChargeType("PayByLcu")
    
    # Make an API request and print the response.
    response = client.do_action_with_exception(request)
    
    # python2:  print(response)
    print(str(response, encoding='utf-8'))

    Command output:

    {
        "RequestId":"8859BB3B-47F5-*****************",
        "SnatTableIds":{
            "SnatTableId":[
                "stb-bp1d09opt**********"
            ]
        },
        "ForwardTableIds":{
            "ForwardTableId":[
                "ftb-bp1h*************"
            ]
        },
        "BandwidthPackageIds":{
            "BandwidthPackageId":[]
        },
        "NatGatewayId":""ngw-uf6htj15rgyp8ivix****""
    }
  2. The following sample code shows how to query the details of the NAT gateway:

    from alibabacloud_credentials.client import Client as CredClient
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException
    from aliyunsdkcore.acs_exception.exceptions import ServerException
    from aliyunsdkvpc.request.v20160428.DescribeNatGatewaysRequest import DescribeNatGatewaysRequest
    
    # Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
    # We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
    # In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
    cred = CredClient()
    access_key_id = cred.get_access_key_id()
    access_key_secret = cred.get_access_key_secret()
    
    # Create an AcsClient instance.
    client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')
    
    # Query the details of the NAT gateway.
    request = DescribeNatGatewaysRequest()
    request.set_accept_format('json')
    
    # The ID of the NAT gateway that you want to query.
    request.set_NatGatewayId("ngw-uf6htj15rgyp8ivix****")
    
    # Make an API request and print the response.
    response = client.do_action_with_exception(request)
    
    # python2:  print(response)
    print(str(response, encoding='utf-8'))

    Command output:

    {
        "TotalCount":1,
        "PageSize":10,
        "RequestId":"6928DB33-84E0-**************",
        "PageNumber":1,
        "NatGateways":{
            "NatGateway":[
                {
                    "Description":"test",
                    "ResourceGroupId":"rg-acfmyxp******",
                    "InstanceChargeType":"PostPaid",
                    "EipBindMode":"MULTI_BINDED",
                    "FullNatTableIds":{
                        "FullNatTableId":[]
                    },
                    "BandwidthPackageIds":{
                        "BandwidthPackageId":[]
                    },
                    "BusinessStatus":"Normal",
                    "Name":"test",
                    "NetworkType":"internet",
                    "ExpiredTime":"",
                    "Tags":{
                        "Tag":[]
                    },
                    "Status":"Available",
                    "ForwardTableIds":{
                        "ForwardTableId":[
                            "ftb-bp1h*************"
                        ]
                    },
                    "SecurityProtectionEnabled":false,
                    "IpLists":{
                        "IpList":[]
                    },
                    "AutoPay":false,
                    "DeletionProtection":false,
                    "NatType":"Enhanced",
                    "InternetChargeType":"PayByLcu",
                    "NatGatewayPrivateInfo":{
                        "MaxSessionEstablishRate":100000,
                        "IzNo":"cn-hangzhou-g",
                        "PrivateIpAddress":"10.4.0.57",
                        "MaxSessionQuota":2000000,
                        "MaxBandwidth":5120,
                        "EniInstanceId":"eni-bp19ray**********",
                        "EniType":"",
                        "VswitchId":"vsw-bp1nz97***********"
                    },
                    "EcsMetricEnabled":false,
                    "VpcId":"vpc-bp1fu6***********",
                    "SnatTableIds":{
                        "SnatTableId":[
                            "stb-bp1d09opt**********"
                        ]
                    },
                    "CreationTime":"2023-02-10T07:07:03Z",
                    "IcmpReplyEnabled":true,
                    "RegionId":"cn-hangzhou",
                    "Spec":"",
                    "NatGatewayId":""ngw-uf6htj15rgyp8ivix****""
                }
            ]
        }
                            

Step 2: Associate EIPs with the NAT gateway

A NAT gateway works as expected only after it is associated with an EIP.

The following sample code shows how to associate EIPs with the NAT gateway:

from alibabacloud_credentials.client import Client as CredClient
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkvpc.request.v20160428.AssociateEipAddressRequest import AssociateEipAddressRequest

# The IDs of the EIPs that you want to associate with the NAT gateway. In this example, the IDs of EIP 1 and EIP 2 are specified.
allocationIds = ["eip-uf6pvlaprugu1azc8****", "eip-uf69ls0f3qgv0alk6****"]

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
# We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
# In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
cred = CredClient()
access_key_id = cred.get_access_key_id()
access_key_secret = cred.get_access_key_secret()

# Create an AcsClient instance.
client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')

# Associate the EIPs with the NAT gateway.
for i in range(0, 2):
    request = AssociateEipAddressRequest()
    request.set_accept_format('json')

    # The ID of the NAT gateway with which you want to associate the EIPs.
    request.set_InstanceId("ngw-uf6htj15rgyp8ivix****")

    # The IDs of the EIPs that you want to associate with the NAT gateway.
    request.set_AllocationId(allocationIds[i])

    # The type of resource with which you want to associate the EIPs.
    request.set_InstanceType("NAT")
    
    # Make an API request and print the response.
    response = client.do_action_with_exception(request)

    # python2:  print(response)
    print(str(response, encoding='utf-8'))

Command output:

{
    "RequestId": "8292A46D-F720-4AEE-98FB-7D3352BA2B63"
}
{
    "RequestId": "E62EEBF8-D327-440E-95BC-8884832C1326"
}

Step 3: Create a DNAT entry

A DNAT entry maps an EIP of a NAT gateway to the private IP address of an ECS instance. Then, the ECS instance can provide Internet-facing services. Configure the DNAT entries that are described in the following table for ECS 1 and ECS 2.

Entry name

EIP

External port

Protocol Type

Private IP address

Internal port

DNAT1

EIP1

80

TCP

ECS1

80

DNAT2

EIP2

80

TCP

ECS2

80

  1. The following sample code shows how to create a DNAT entry for ECS 1:

    from alibabacloud_credentials.client import Client as CredClient
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException
    from aliyunsdkcore.acs_exception.exceptions import ServerException
    from aliyunsdkvpc.request.v20160428.CreateForwardEntryRequest import CreateForwardEntryRequest
    
    # Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
    # We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
    # In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
    cred = CredClient()
    access_key_id = cred.get_access_key_id()
    access_key_secret = cred.get_access_key_secret()
    
    # Create an AcsClient instance.
    client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')
    
    # Create a DNAT entry.
    request = CreateForwardEntryRequest()
    request.set_accept_format('json')
    
    # The ID of the DNAT table to which you want to add the DNAT entry.
    request.set_ForwardTableId("ftb-uf6hdobgppflyr2ng****")
    
    # Specify the EIP that is used to communicate with the Internet. In this example, the IP address of EIP 1 is specified.
    request.set_ExternalIp("101.xx.xx.137")
    
    # The external port that is used in port forwarding. Valid values: 1 to 65535. In this example, this parameter is set to 80.
    request.set_ExternalPort("80")
    
    # Specify the private IP address of the ECS instance that wants to receive requests from the Internet. In this example, this parameter is set to the private IP address of ECS 1.
    request.set_InternalIp("192.xx.xx.100")
    
    # The internal port that is used in port forwarding. Valid values: 1 to 65535. In this example, this parameter is set to 80.
    request.set_InternalPort("80")
    
    # The protocol that is used by the ports.
    # Valid values: TCP, UDP, and Any. TCP: Only TCP packets are forwarded. UDP: Only UDP packets are forwarded. Any: All packets are forwarded.
    request.set_IpProtocol("TCP")
    
    # The name of the DNAT entry. In this example, the name is set to DNAT1.
    request.set_ForwardEntryName("DNAT1")
    
    # Make an API request and print the response.
    response = client.do_action_with_exception(request)
    
    # python2:  print(response)
    print(str(response, encoding='utf-8'))

    Command output:

    {
        "RequestId": "93A6E13E-C168-4444-9DF1-F4B22B1E0A12",
        "ForwardEntryId": "fwd-uf69gp4nyj8b9aa2n****"
    }
  2. The following sample code shows how to create a DNAT entry for ECS 2:

    from alibabacloud_credentials.client import Client as CredClient
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException
    from aliyunsdkcore.acs_exception.exceptions import ServerException
    from aliyunsdkvpc.request.v20160428.CreateForwardEntryRequest import CreateForwardEntryRequest
    
    # Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
    # We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
    # In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
    cred = CredClient()
    access_key_id = cred.get_access_key_id()
    access_key_secret = cred.get_access_key_secret()
    
    # Create an AcsClient instance.
    client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')
    
    # Create a DNAT entry.
    request = CreateForwardEntryRequest()
    request.set_accept_format('json')
    
    # The ID of the DNAT table to which you want to add the DNAT entry.
    request.set_ForwardTableId("ftb-uf6hdobgppflyr2ng****")
    
    # Specify the EIP that is used to communicate with the Internet. In this example, the IP address of EIP 1 is specified.
    request.set_ExternalIp("106.xx.xx.94")
    
    # The external port that is used in port forwarding. Valid values: 1 to 65535. In this example, this parameter is set to 80.
    request.set_ExternalPort("80")
    
    # Specify the private IP address of the ECS instance that wants to receive requests from the Internet. In this example, this parameter is set to the private IP address of ECS 1.
    request.set_InternalIp("192.xx.xx.101")
    
    # The internal port that is used in port forwarding. Valid values: 1 to 65535. In this example, this parameter is set to 80.
    request.set_InternalPort("80")
    
    # The protocol that is used by the ports.
    # Valid values: TCP, UDP, and Any. TCP: Only TCP packets are forwarded. UDP: Only UDP packets are forwarded. Any: All packets are forwarded.
    request.set_IpProtocol("TCP")
    
    # The name of the DNAT entry. In this example, the name is set to DNAT2.
    request.set_ForwardEntryName("DNAT2")
    
    # Make an API request and print the response.
    response = client.do_action_with_exception(request)
    
    # python2:  print(response)
    print(str(response, encoding='utf-8'))

    Command output:

    {
        "RequestId": "EB455CB3-222E-4F62-AF20-FAF908615717",
        "ForwardEntryId": "fwd-uf6g8gu2ld36nohly****"
    }

Step 4: Create an Internet Shared Bandwidth

Internet Shared Bandwidth instances support bandwidth sharing and multiplexing on a regional scale. You can use Internet Shared Bandwidth instances to reduce bandwidth resource costs.

The following sample code shows how to create an Internet Shared Bandwidth:

from alibabacloud_credentials.client import Client as CredClient
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkvpc.request.v20160428.CreateCommonBandwidthPackageRequest import CreateCommonBandwidthPackageRequest

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
# We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
# In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
cred = CredClient()
access_key_id = cred.get_access_key_id()
access_key_secret = cred.get_access_key_secret()

# Create an AcsClient instance.
client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')

# Create an EIP bandwidth plan.
request = CreateCommonBandwidthPackageRequest()
request.set_accept_format('json')

# Specify the maximum bandwidth of the EIP bandwidth plan. Valid values: 1000 to 5000. Unit: Mbit/s. In this example, this parameter is set to 1500. You can set the parameter based on your business requirements.
request.set_Bandwidth(1500)

# The connection type.
# Valid values: BGP and BGP_PRO. BGP: BGP (Multi-ISP). BGP_PRO: BGP (Multi-ISP) Pro.
request.set_ISP("BGP")

# The name of the EIP bandwidth plan.
request.set_Name("test")

# The description of the EIP bandwidth plan.
request.set_Description("test")

# The metering method of the EIP bandwidth plan.
# Valid values: PayByBandwidth and PayBy95. PayByBandwidth: The EIP bandwidth plan is charged based on bandwidth usage. PayBy95: The EIP bandwidth plan is charged based on the enhanced 95th percentile bandwidth. Default value: PayByBandwidth.
request.set_InternetChargeType("PayByBandwidth")

# Make an API request and print the response.
response = client.do_action_with_exception(request)

# python2:  print(response)
print(str(response, encoding='utf-8'))

Command output:

{
    "RequestId": "592C8AB6-09AC-4751-9B17-231BF8FEEA44",
    "ResourceGroupId": "rg-acfmx2k5unk****",
    "BandwidthPackageId": "cbwp-uf6jvfp1wqps1vywa****"
}

Step 5: Associate EIPs with the Internet Shared Bandwidth

You can associate EIP 1 and EIP 2 with the Internet Shared Bandwidth. After the EIPs are associated with the Internet Shared Bandwidth:

  • Services attached to the NAT gateway with which the EIPs are associated share the bandwidth of the Internet Shared Bandwidth.

  • The previous maximum bandwidth of the EIPs is invalid. The sum of the maximum bandwidth of the EIPs equals the maximum bandwidth of the Internet Shared Bandwidth.

  • The previous billing methods of the EIPs become invalid. The EIPs function as public IP addresses. Data transfer and bandwidth usage are not charged for the EIPs.

The following sample code shows how to associate EIP 1 and EIP 2 with the Internet Shared Bandwidth:

from alibabacloud_credentials.client import Client as CredClient
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkvpc.request.v20160428.AddCommonBandwidthPackageIpRequest import AddCommonBandwidthPackageIpRequest

# Specify the EIPs that you want to associate with the EIP bandwidth plan. In this example, EIP 1 and EIP 2 are specified.
IpInstanceIds = ["eip-uf6pvlaprugu1azc8****","eip-uf69ls0f3qgv0alk6****"]

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
# We do not recommend that you save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of your resources may be compromised. 
# In this example, the AccessKey pair is obtained by using the Alibaba Cloud Credentials tool to authenticate API access. 
cred = CredClient()
access_key_id = cred.get_access_key_id()
access_key_secret = cred.get_access_key_secret()

# Create an AcsClient instance.
client = AcsClient(access_key_id, access_key_secret, '<your-region-id>')

for i in range(0, 2):
    # Associate the EIPs with the EIP bandwidth plan.
    request = AddCommonBandwidthPackageIpRequest()
    request.set_accept_format('json')
    
    # The ID of the EIP bandwidth plan.
    request.set_BandwidthPackageId("cbwp-uf6jvfp1wqps1vywa****")

    # The EIPs that you want to associate with the EIP bandwidth plan.
    request.set_IpInstanceId(IpInstanceIds[i])

    # Make an API request and print the response.
    response = client.do_action_with_exception(request)

    # python2:  print(response)
    print(str(response, encoding='utf-8'))
                

Command output:

{
    "RequestId": "658D8E3C-A85E-406C-AE49-EE6ECA2B9252"
}
{
    "RequestId": "166E9BF2-C12B-45B6-A712-633AD535B446"
}

Step 6: Check network connectivity

You can test the network connectivity by using a computer to access the applications on ECS 1 and ECS 2 over the Internet.

Note

Make sure that the security group rules of the ECS instance allow the ECS instance to receive requests from the Internet.

  1. Open a browser on a computer that can access the Internet.

  2. Enter one of the EIPs that are associated with the NAT gateway into the address bar of the browser and access the application that runs on an ECS instance.

    The result shows that the computer can access the applications on ECS 1 and ECS 2 over the Internet. In addition, the ECS instances share the bandwidth of the Internet Shared Bandwidth and can handle traffic spikes.

    Figure 1. Access the application on ECS 1Verify the network connectivity to ECS 1

    Figure 2. Access the application on ECS 2Verify the network connectivity to ECS 2