Introduction
In the post A Beginner’s Guide for Vagrant we showed how to get started with Vagrant. I believe it is worthwhile to write a dedicated post to explain networking in Vagrant for several reasons.
- I have found that some Vagrant beginner including me have got stuck on Vagrant networking such as failing to access the service in Vagrant VM.
- Networking is the first priority to figure out when it comes to multiple machines which is very common since applications are getting more and more complicated.
- Sometimes you want to simulate a complex network environment.
Concepts
Figure-1 depicts a typical home networking topology which is should be familiar to the readers. We’ll use this model to explain networking in Vagrant because it is much simpler than that in data center. But the concepts should be applied in any network where Vagrant runs. We assume that Vagrant is running in the laptop whose IP address is 192.168.1.10
.
It is worth mentioning that 192.168.1.10
is actually a private IPv4 address. Ideally, every Vagrant host should be assigned with at least one public IP address. However, it is unrealistic at the moment due to the lack of IPv4 address resource and slow transformation from IPv4 to IPv6. Nevertheless, what we are gonna discuss should apply no matter the address of the host is public or not.
Vagrant Networking
So far, Vagrant has provide 3 networking options. The underlying implementation is provider-dependent hence it is possible that the option is unavailable with some specific provider—for example, the UDP port forwarding in libvirt provider has not been implemented yet. If what is discussed in this post does not work as expected in your environment, please check the provider docs to see if it is fully supported.
Public Networking
Public network gives the VM the same network visibility as the Vagrant host. Wherever the Vagrant host is accessable, the VM could be reached directly as another standalone machine because it has a dedicated IP address in the same network subnet with the Vagrant host. Figure-2 shows the network topology.
Even the VM is running inside the host, it is able to be accessed directly by the desktop whose IP is 192.168.1.11
. Of course, this capability is implemented by the underlying providers instead of the Vagrant itself. Typically, it is achieved by a software bridge device. You can see that the IP address of the host has been shifted to the bridge device.
The word public
does not mean that the IP addresses have to be public routable IP addresses. Hence it is kind of confusing. The doc also states that bridged networking
would be more accurate. In fact, public networking
is called bridged networking
in the early days—see the doc of old version. Just keep one simple rule in mind—if the VM’s assigned IP is in the same subnet of the host, then it is a public networking configuration.
It should be noted that public networking is not always available even though the providers support bridged networking. It depends on whether you have control over the subnet where the host lives. Typically, the IP addresses—both public and private—assignment will be managed by network administrators in organizations which means you are not able to acquire extra IP addresses at will. In that case, the bridged networking will not work.
Private Networking
Vagrant private networks allow you to access your guest machine by some address that is not publicly accessible from the global internet. In general, this means your machine gets an address in the private address space.
The definition is quoted from Vagrant docs. However, IMHO, it is vague. As an experienced Vagrant user, it is really uninformative. Figure-3 shows the sketch of the private networking in Vagrant.
Technically, in private networking, a virtualized subnet that is invisible from outside of Vagrant host will be created by the underling provider—Vagrant just provides the abstraction with no implementation. Virtual machines attached to the same virtualized subnet are ables to communicate with each other. Unlike public networking, there is no way for the desktop whose ip is 192.168.1.11
to connect to the virtual machines directly.
Since the addresses assigned to the virtual machines are private IPv4 ones, the IP address range chosen to the virtualized subnet shall not be conflict with any existing network. Especially when the host itself is running in a private subnet as shown in Figure-3. Per my experience, 172.16.0.0 – 172.31.255.255
is rarely used in organizations which makes it suitable in private networking.
As mentioned before, Vagrant itself just defines the high level abstract options which are implemented by underlying providers. Usually, Vagrant knows how to involve the underlying providers to create the necessary subnets automatically. Thus there is no need for users to configure subnets manually. However, if the IP address range chosen by the Vagrant needs to be changed, manual networking configuration in the provider is required. It varies from provider to provider and the docs of providers should be referenced if networking customization is required.
The private networking in Vagrant only specifies that the virtual machines within the same subnet are visible to each other—it does NOT tell whether the virtual machines are able to access the network outside the host. The behavior is provider-dependent. For example, private networking with VirtualBox is limited on the host while in Libvirt the virtual machines are able to reach the outside. The docs about providers’ networking should be turned to if you need to get the detail.
Finally, like the public networking
, the private
is kind of confusing, at least uninformative. host-only
which was used to name the same method in the early days would be better.
Forwarded Ports
Forwarded ports expose the accessibility of virtual machines to the world outside the Vagrant host. In Figure-4, assume that an Nginx HTTP server runs in the virtual machine which uses private networking. Thus it is impossible to access the service from outside of the host. But through a forwarded port, the service is able to be exposed as a service of the Vagrant host which makes it public.
If public networking is used, forwarded ports would be useless because the VMs are already public. However, as mentioned, public networking is not always available due to the fact that it needs some prerequisites that are not always met. Under the circumstances, the combination of private networking and forwarded ports would be the only choice.
Epilogue
Vagrant networking is not hard actually because it is an abstraction for the rich underlying providers. But it is not easy either so I hope this post would be a good complement to the official docs. Just keep the following rules in mind.
- Don’t misunderstand the public/private networking for the public/private IPv4 addresses. They don’t address the same issues.
- Public networking attaches virtual machines to the same subnet with the Vagrant host
- Private networking hides virtual machines from the outside of the Vagrant host
- Forwarded ports create tunnels from virtual machines to outside world
Besides the common options, provider-specific options are also allowed such as VirtualBox and Libvirt. If you use different providers, check the doc to see if any extra option is available.
The networking options provided by Vagrant are actually high level, abstraction ones. The implementation varies from provider to provider. Usually you don’t have to know the implementation detail but getting a deep view would helpful for troubleshooting. Learning the network models of each provider would be a good start.