Out of the box, Cycle offers a intuitive networking experience. For most users, advanced container and virtual machine networking isn't something they'll have to dive into. However, we generally expose advanced features through a building blocks type system.
For users that need to have granular control over their containers route tables or want to set a static egress IP for containers and virtual machines, this guide is for you.
The two features we will cover in this guide are:
Some Rules First
Routing tables exist in every container.
If you're not using specific routes or egress settings the route table is preconfigured to work by sending container to container traffic over eth-priv and traffic going out to the public internet over eth-pub.
Every container has both IPv4 and IPv6 route tables.
If there are connected SDN networks, there are additional entries for those interfaces that can be viewed on the IPv6 route tables.
When setting egress via gateway to true, the route table will be updated with a new default pointing at the gateway service.
Egress via gateway being a new "default" route is the reason why you can safely turn on both. Routes defined in the routes config will be more specific and not clash with egress via gateway.
Situation | You want | Because |
|---|---|---|
Traffic needs to all originate from the same IP. | Egress via Gateway | Traffic from downstream vendors is only accepted if the originating IP is on the allowlist or static. |
Certain traffic should not be handled by the default routes in the table. | Custom routes | Imagine trying to reach a company VPN or a service like Tailscale. |
Egress via Gateway
By default, all egress traffic originates from the server IP. In cloud environments, IP's can be dynamic as servers come and go and due to distributing container instances or vm's across multiple servers.
When Egress via Gateway is turned on, the downstream receiver of the traffic will see incoming requests as having originated from a static IP. This is accomplished by using the environments gateway service as the egress point. This leads to the origin IP being the same every time, regardless of which server the container or vm is on at the time of the request.
Enabling this Setting
In the portal, the setting can be enabled through the container or vm config page in the networking section. A more durable way to enforce this is through a stack, or even the API.
In the stack:
containers: worker: config: network: public: egress-only hostname: worker egress_via_gateway: truePublic, in the example, could be public, egress-only, or environment-limited.
Using the API:
{ "action": "reconfigure", "contents": { "network": { "public": "egress-only", "hostname": "worker", "egress_via_gateway": true, "routes": null }, ...: { /* the rest of the container config */ } }}Remember that when reconfiguring a container via the API the entire config needs to be set or default values will be assigned to the existing fields.
For users that plan to send a large volume of traffic egress over the gateway, there is an available performance setting on the gateway that can be toggled on. This setting will allow the gateway service to consume far more RAM and CPU from the server it is deployed to.
Container Routes
Container routes exposes a way for users to define additional entries into their containers routes table. For many users, this is an excellent way to route traffic over a VPN or some specialized network provided by a service like Tailscale.
10.* Networks
There are 2 internal ranges that Cycle uses and reserves that users should never use:
10.10.0.0/16 for NAT
10.255.0.0/16 for linux gateway
This rules out 10.0.0.0/8, as it contains both of the aforementioned ranges.
The Word Gateway
In this article, we talk about the gateway service - a Cycle specific "gateway". When configuring route tables, there is also the standard linux "gateway" which is basically "who do I send this traffic to". These two concepts are separate.
Configuring Container Routes
Field | In plain English |
|---|---|
| The destination address range in CIDR. |
| Where do I send the packet next? |
| The interface name. |
| The source address, or address from within the container that matching traffic will |
| If true platform will check if source exists before trying to use it. |
| If packets are IPv4 and need to travel over IPv6, IPv6 automatically wraps those packets in the correct headers. |
| Entries that give even more granular control over a list of gateways and their weights (or how often each gateway should be used). |
Nexthops
Field | What it does |
|---|---|
| Same as above, "where does the next packet go". In this case the gateway is accompanied by a weight. |
| The weight to apply to this gateway. The higher the weight the more often the given gateway is selected. |
Examples for Destinations
What actually goes in to the destination field? The ideal CIDR is as close to the range the private network uses as possible, not a bigger block that happens to have the private network range in it.
Example Service | Typical range |
|---|---|
Tailscale |
|
An office LAN over VPN |
|
Empty Destination
When the destination field is left empty the destination becomes either 0.0.0.0 or :: depending on the family, destination, or gateway (depending on which is set).
Defining in the Stack
Setting both of these in the stack is simple:
containers: worker: config: network: public: egress-only hostname: worker egress_via_gateway: true routes: - destination: 192.168.50.0/24 interface: eth-demo gateway: 192.168.50.1and the above results in the following:
Traffic headed to | Leaves via |
|---|---|
Other containers in the environment | Cycle's internal network |
| Your VPN sidecar at |
Everything else | The gateway, from your static IP |
Dive Deeper in Community
This guide is meant to be a primer for configuring advanced networking on Cycle using container routes and egress via gateway. If theres anything missing you'd like to dive deeper on, please open a new thread on the Cycle Community and a community member or a Cycle engineer will respond.
We love to hear more about what you're building, so don't hesitate to post.
You can also find us in our public Slack channel, if you're not already a member.