New Dyno Networking Model
Posted by Michael
Today we're announcing a change to how networking on Heroku works. Dynos now get a dedicated, virtual networking interface instead of sharing a network interface with other dynos. This makes dynos behave more like standard unix containers resulting in better compatibility with application frameworks and better parity between development and production environments.
Previously, network interfaces were shared between multiple dynos. This weakened the abstraction of a dyno as a standard Unix-style container with a network interface of its own and full disposal of the whole TCP port range.
The shared network interface also resulted in a low grade information leak where one dyno could obtain some information about connections made by other dynos. This information did not include any customer data or other customer identifying information. But it broke the core principle of tenant isolation. With the new networking model, dynos now have fully isolated network configurations. We’d like to thank John Leach for working with us to analyze this aspect of our old networking model and point out the weakness.
We want the Heroku dyno to resemble a standard OS environment as much as possible, except you don't have to manage anything yourself. A dyno should let you instantly run any application that you can run on another reasonable unix-style system.
The new dyno networking model brings us closer to that goal: The dyno no longer imposes any restrictions on what ports an application can listen on. This improves out-of-the box compatibility with application frameworks that listen on multiple ports (for whatever reason). You can still only connect from the outside world to the port specified in the
$PORT environment variable, but now you don't have to painfully reconfigure your web stack to stop it from listening on other ports. In other words, if it worked on your local environment, there is now one less reason it might break on Heroku.
You are not required to make any changes to your applications to make it work with the new configuration. We have gradually rolled out the networking update over the last month and at this point it is the default for all new and existing applications.
Along the way we ran into some interesting problems in the underlying stack. Some library code behaves in unexpected ways when running on an OS with a high number of virtual network interfaces.
For example, listing network interfaces in Java using OpenJDK fails if any one network interface's index is greater than 255. We identified this problem during the gradual rollout and updated the buildpacks with a custom patched OpenJDK build so your applications would not be affected.
One problem we're still working on resolving is that Raindrops is not functional with the new networking stack. This is due to a Linux kernel bug. The bug has been addressed in the upstream kernel sources, but we’re still waiting for it show up in the branch that Heroku runs.
Check the Dev Center article on dynos for additional details.