Guides

Setting up virtual networks

Create a private network, attach servers to it tagged or untagged, follow the change until the network has applied it, and configure the VLAN in the operating system.

Two deployed servers go onto a private network of their own, so each request that takes a {serviceId} runs once per server.

1. Choose a VLAN ID

Every network needs a localVlanId from 11 to 4094 that no other network in the organization uses. Get VLAN availability lists the tags taken as data.usedVlanIds and names the next free one as data.nextFreeVlanId, with the range in minVlanId and maxVlanId:

curl --request GET \
  --url https://api.serverside.com/v1/networking/virtual-networks/availability \
  --header 'Authorization: Bearer <api-key>'

2. Create the network

Create virtual network with the tag from step 1 as localVlanId:

curl --request POST \
  --url https://api.serverside.com/v1/networking/virtual-networks \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "backend",
  "type": "PRIVATE",
  "localVlanId": 100
}
'

The API does not choose a tag for you, so localVlanId goes in every create. The answer is 201 with the network, whose data.id is the {networkId} of the later steps. A private network gets no subnet and no gateway from us. The servers on it use a private range you choose; this guide uses 10.20.0.0/24. Frames you tag inside it with 802.1Q VLAN ids of your own reach the other servers with their tags intact.

3. Pick each server's segment

A server joins a network on a segment: one of its ports, or two bonded ports. Get network capabilities lists the physical ports under data.availableInterfaces, each with its id, name, macAddress and the segmentId it belongs to, with isConfigured set on a port that is already in a segment. data.availableBondingGroups lists the ports that can be bonded together.

curl --request GET \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/networking/capabilities \
  --header 'Authorization: Bearer <api-key>'

Two layouts work:

  • Tagged, on the existing segment. The segment that carries the server's internet access network untagged also carries the private network, tagged with its localVlanId. No second cable is used.
  • Native, on a second port. A free port becomes a segment of its own, and the private network arrives there untagged.

For the native layout, Create segment takes the interfaceIds to put in it: one free port, or two from one entry of availableBondingGroups to form an LACP bond, which the host names bond0, bond1 and so on. A bond takes exactly two ports, one on each switch of the pair, with the same port number on both.

curl --request POST \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/segments \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "interfaceIds": [
    "<interface-id>"
  ]
}
'

The answer is 201 with the new segment and its segmentId.

4. Attach the servers

Attach service once per server. For the tagged layout, segmentId is the one that carries the server's internet access network, which List service virtual networks shows on that network's row, and isNative is false. For the native layout, it is the new segment from step 3, with isNative true.

curl --request POST \
  --url https://api.serverside.com/v1/networking/virtual-networks/{networkId}/attachments \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Idempotency-Key: <idempotency-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "serviceId": "<service-id>",
  "segmentId": "<segment-id>",
  "isNative": false
}
'

A 202 means the change is on its way to the switches, and its body holds the change's status, APPLYING, and the time it was accepted as since. Sending the request again with the same Idempotency-Key answers 202 with the original change. Without a key, the same attachment sent once it is in place answers 204 and changes nothing.

5. Wait for the change

Two places report progress. Get service status carries networkChange, with a status of APPLYING or FAILED and the time it started as since. While it applies, a degraded object appears if a switch keeps failing to take the change: consecutiveFailures, the latest failureCategory, and nextAttemptAt for the next automatic attempt, or null once the change waits for our staff. A change that ends as FAILED has been rolled back on the switch, and its failureCategory names the cause.

List service virtual networks shows each attachment's own status: ATTACHING, then ATTACHED or ATTACH_FAILED.

curl --request GET \
  --url https://api.serverside.com/v1/baremetal/{serviceId}/virtual-networks \
  --header 'Authorization: Bearer <api-key>'

A server takes one network change at a time, so the next attach, detach or segment change for it waits until this one has finished.

6. Configure the operating system

A tagged network needs a VLAN interface on the server, on top of the interface that carries the segment. Get bare metal service names it: each entry in interfaces is one segment, and its name is the interface a deployment writes on the host, either the port's own name or bond0, bond1 and so on for a bond, whose bondMode reads LACP. After a change to the server's segments, interfaces shows the layout the next deployment will write, and the host keeps its old interfaces until it is reinstalled.

On Linux with iproute2, where the segment's name is eno1 and the shell variable VLAN holds the network's tag:

ip link add link eno1 name eno1.$VLAN type vlan id $VLAN
ip addr add 10.20.0.1/24 dev eno1.$VLAN
ip link set eno1.$VLAN up

Give the second server 10.20.0.2/24, and the two reach each other over the private network. These commands do not survive a reboot; put the same settings in the distribution's network configuration (netplan on Ubuntu, /etc/network/interfaces on Debian, NetworkManager on RHEL-family systems) to keep them.

Private networks carry jumbo frames at an MTU of 9000, and every server on the network needs the same value on its private interface:

ip link set eno1 mtu 9000
ip link set eno1.$VLAN mtu 9000

Linux will not set a VLAN interface's MTU above that of the port it sits on, which is why the parent port eno1 goes to 9000 first. In the tagged layout that port also carries the internet access network untagged, and the higher MTU applies to it as well; a private network on a port of its own keeps the two apart.

Servers in different datacenters

A network belongs to the organization, and neither the create request nor the network names a datacenter. Extending a private network between datacenters is coming soon. Until it ships, keep every server on a private network in the same datacenter.

Taking a server off the network

Detach service names the attachment in its path, by the server's id and the segment's:

curl --request DELETE \
  --url https://api.serverside.com/v1/networking/virtual-networks/{networkId}/attachments/{serviceId}/{segmentId} \
  --header 'Authorization: Bearer <api-key>' \
  --header 'Idempotency-Key: <idempotency-key>'

It answers 202 and reports progress the same way, through DETACHING until the row is gone, or to DETACH_FAILED. Use a new key for it: the key that attached the network on that segment answers with the attach again and detaches nothing. The addresses the server held on that network go back to their blocks as free, and their reverse DNS records are deleted. List attached services shows which servers are still attached, one row per server with each of its attachments.

Deleting the network

Delete virtual network answers 204 once no server is attached to the network and it holds no IP block:

curl --request DELETE \
  --url https://api.serverside.com/v1/networking/virtual-networks/{networkId} \
  --header 'Authorization: Bearer <api-key>'

Detach every server first, and return any IP block on the network as Managing IP addresses describes.

Removing a server's public network

A database or application server can drop its public network and stay reachable over the private network only. Its public network is its internet access network, the row with managedBy SYSTEM in List service virtual networks, and it detaches through the same Detach service call with that network's id and segmentId. Only the API can do this, since the cloud console removes private attachments and nothing else. Log in over the private address first, because SSH to the public address stops answering once it is detached.

The server's addresses go back to the network's IP blocks as free, and the blocks stay on the network, billed on the server's subscription. Without an address there the server cannot be reinstalled: a deployment needs a primary IPv4 address on a native network and is otherwise refused with 422 PRIMARY_IPV4_REQUIRED. To restore it, attach the network again as native and assign the server an IPv4 address from its block, since the first IPv4 address a server gets on a network becomes its primary one there. Once detached, the network is gone from the server's list; List virtual networks shows it again with includeManaged=true:

curl --request GET \
  --url 'https://api.serverside.com/v1/networking/virtual-networks?includeManaged=true' \
  --header 'Authorization: Bearer <api-key>'

The server also loses its own route to the internet, and we run no NAT gateway, so package updates and outbound calls have to pass through one of your servers that keeps a public address, set up as a NAT router or proxy on the private network.

Errors

StatuscodeCause
400VALIDATION_ERRORlocalVlanId is missing or outside 11 to 4094.
404ENTITY_NOT_FOUNDThe network or the server is not one of your organization's, or a detach names an attachment that does not exist.
409VLAN_ID_IN_USEAnother network in the organization has that localVlanId.
409INTERFACE_IN_USEA port in a new segment already belongs to another one.
409NATIVE_NETWORK_ALREADY_EXISTSThe segment already carries a native (untagged) network.
409NETWORK_ATTACHMENT_ALREADY_EXISTSTwo requests attached the same network to the same segment at the same moment.
409NETWORK_CHANGE_IN_PROGRESSA change for that server is still being applied. Retry after Retry-After (10 seconds).
409OPERATION_IN_PROGRESSA deployment, wipe or hardware test is running on the server; attachments and segments wait for it to end.
409IDEMPOTENCY_KEY_REUSEDThe Idempotency-Key was already used on that server for a different network or segment.
409NETWORK_HAS_ASSIGNED_SERVICEA delete while a server is still attached to the network.
409NETWORK_HAS_PREFIXESA delete while the network still holds an IP block.
422NETWORK_RENAME_BLOCKEDUpdate virtual network sent a name for an internet access network.
422VALIDATION_FAILEDA rule refused the request; the detail's code says which. SEGMENT_NOT_FOUND: the segmentId is not one of the server's segments. NETWORK_VLAN_UNSUPPORTED: a tagged attachment (isNative false) of a network that has no VLAN ID. On Create segment: INTERFACE_NOT_FOUND for a port that is not on this server, INTERFACE_UNAVAILABLE for one not connected to a switch, BOND_INVALID for ports that cannot form a bond.
422SERVICE_LOCKED, SERVICE_SUSPENDED, SERVICE_DELETINGAn attach, detach or segment change on a server that is locked or suspended, or being deleted.