How to emulate Internet in multi machine environment with Vagrant - virtual-machine

I'm creating a vagrant multi machine configuration file. Here is a chunk:
Vagrant.configure(2) do |config|
config.vm.box = "chef/centos-7.0"
config.vm.define "radius" do |radius|
radius.vm.hostname = "radius-server"
end
config.vm.define "mysql" do |mysql|
mysql.vm.hostname = "mysql-server"
end
end
how can I emulate the situation in which the above two virtual machines are in different networks separated by Internet?
I could create two different private networks having two different private ip addresses like 192.168.1.3 for the first virtual machine and 192.168.2.3 for the second virtual machine. in this case the machines would be in different networks. But could they talk to each other?

Yes, they can talk.
You need a router (the 3rd node) connected to both of these networks.
The router acts as the (mini) Internet:
A=[192.168.1.3] <=> [*.*.1.1]=router=[*.*.2.1] <=> [192.168.2.3]=B
Details
The easiest way is to assign the router role to the physical host because it has IP addresses on both of these networks (I guess they are 192.168.1.1 and 192.168.2.1 in your example). Otherwise, they are just numbers and, if Vagrant does not complain, network will function with IP addresses from public ranges as well (just be careful to disconnect physical network for clean testing).
Just enable routing (forwarding) in the OS on the physical host - googled example for Linux.
And make sure routes are configured on both of the virtual machines to each other via this router:
A's shell> ip route add default via 192.168.1.1
B's shell> ip route add default via 192.168.2.1
NOTE: Technically, because the networks use private IP addresses, they are not routable on the Internet (AFAIK, real Internet routers drop packets with these private IP addresses, while home routers NAT them).
Working Vagrant file
Tested example using libvirt provider.
Note that VMs are connected to two different networks.
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.provider "libvirt"
config.vm.define "rhel7_minion" do |rhel7_minion|
rhel7_minion.vm.box = "uvsmtid/centos-7.1-1503-gnome"
rhel7_minion.vm.synced_folder '.', '/vagrant', disabled: true
rhel7_minion.vm.network 'private_network',
:libvirt__network_name => 'primary_vagrant_private_net',
ip: '192.168.1.2',
:libvirt__netmask => '255.255.255.0',
:libvirt__forward_mode => 'route',
:libvirt__dhcp_enabled => true
end
config.vm.define "rhel5_minion" do |rhel5_minion|
rhel5_minion.vm.box = "uvsmtid/centos-5.5-minimal"
rhel5_minion.vm.synced_folder '.', '/vagrant', disabled: true
rhel5_minion.vm.network 'private_network',
:libvirt__network_name => 'secondary_vagrant_private_net',
ip: '192.168.2.3',
:libvirt__netmask => '255.255.255.0',
:libvirt__forward_mode => 'route',
:libvirt__dhcp_enabled => true
end
end

Related

Access vagrant VM with puphpet from local network?

I used vagrant and puphpet for two weeks and it works great. In my case I'll just use http://myserver.dev that I added to my host file as puphpet suggest
192.168.56.101 myserver.dev
Now I want to get access to my VM:s apache www folder from another computer in my local network.
This post suggest to uncomment some lines in vagrant file, but as I use puphpet my autogenerated vagrant file looks like this:
# -*- mode: ruby -*-
dir = File.dirname(File.expand_path(__FILE__))
require 'yaml'
require "#{dir}/puphpet/ruby/deep_merge.rb"
require "#{dir}/puphpet/ruby/to_bool.rb"
require "#{dir}/puphpet/ruby/puppet.rb"
configValues = YAML.load_file("#{dir}/puphpet/config.yaml")
provider = ENV['VAGRANT_DEFAULT_PROVIDER'] ? ENV['VAGRANT_DEFAULT_PROVIDER'] : 'local'
if File.file?("#{dir}/puphpet/config-#{provider}.yaml")
custom = YAML.load_file("#{dir}/puphpet/config-#{provider}.yaml")
configValues.deep_merge!(custom)
end
if File.file?("#{dir}/puphpet/config-custom.yaml")
custom = YAML.load_file("#{dir}/puphpet/config-custom.yaml")
configValues.deep_merge!(custom)
end
data = configValues['vagrantfile']
Vagrant.require_version '>= 1.8.1'
Vagrant.configure('2') do |config|
eval File.read("#{dir}/puphpet/vagrant/Vagrantfile-#{data['target']}")
end
But there are no uncomment lines.
I thought maybe I need to do something in puphpet's config.yaml?
Here's what I've found about ip and port:
machines:
vflm_azud9vpjzelv:
id: machine1
hostname: myserver.puphpet
network:
private_network: 192.168.56.101
forwarded_port:
vflmnfp_rkr38vlo4vcb:
host: '6597'
guest: '22'
memory: '512'
cpus: '1'
You have two simple choices:
Vagrant comes with the vagrant share command that opens up a publicly-accessible, random URL to your VM
Create a forwarded port from your host to your VM. For example, forward port 1080 on your host to port 80 in the VM, so when you go to http://localhost:1080 traffic will be forwarded to your VM. For this you need to set * as your Apache vhost's alias so it catches all traffic to the port you choose (in this case, 80).

Vagrant remote box with libvirt issue

I am trying to make vagrant work with the following setup
Two machines - One controller and one host
Installed vagrant + vagrant-nodemaster plugin in controller (1.5.4 vagrant)
Installed vagrant + vagrant-node + vagrant-libvirt in host machine
After installation I started nodeserver in host machine in an unused port.
With the following configuration pushed from controller to host (using vagrant remote config upload )
config.vm.define :vm3 do |vm3|
vm3.vm.network :private_network,
:ip => "192.168.170.57",
:libvirt__network_name => "vagrantnw",
:libvirt__dhcp_enabled => false
end
config.vm.provider :libvirt do |libvirt|
libvirt.driver = "qemu"
# leave out host to connect directly with qemu:///system
#libvirt.host = "localhost"
libvirt.connect_via_ssh = false # aeso needed
libvirt.username = "root"
libvirt.storage_pool_name = "default"
end
config.ssh.username = 'vagrant'
config.ssh.password = 'vagrant'
config.ssh.insert_key = 'true'
config.ssh.private_key_path = '/home/kk/ssh_privkey'
I am expecting that with the above configuration libvirt will create a vm with ip address as 192.168.170.57 with a valid nfs which can be mapped to host. Now, following are the issues I am facing
VM is always created in 192.168.121.xx network with a dynamic ip address assigned in the same subnet. I am not able to create vm in the specific network which I want.
I would like to remotely ssh into the vm using command 'vagrant remote ssh '. Or from a different host I would like to connect to the VM created above.
I would like to ftp a file to the guest once remote ssh is working fine. I believe we can do this using ansible . But wanted to check if a quick and dirty way to do it through vagrant .
Thanks
You can change the management network by adding the following lines in the provider definition:
config.vm.provider :libvirt do |libvirt|
...
libvirt.management_network_name = "vagrant-libvirt"
libvirt.management_network_address = "10.75.250.0/25"
end

Multicasting with `socat` in Vagrant & VirtualBox Env

The problem: Each machine in the same network should be able to broadcast to all the members, including itself.
This is an attempt to get working multicast with socat with VMs created in Vagrant & VirtualBox Envrionment. It seems things are working differently here, so I first tried to see how multicast working on physical machines.
I've 3 physical machines with ubuntu 12.04 server installed on them and named as pc0, pc1 and pc2.
On each machine I run:
socat STDIO UDP-DATAGRAM:224.0.0.1:2200,bind=:2200
...and when I typed hi from pc0 from pc0, it has broadcasted to itself and other 2 machines and this is what I wanted (and I hope this is how multicast supposed to work):
ubuntu#pc0:~$ socat STDIO UDP-DATAGRAM:224.0.0.1:2200,bind=:2200
hi from pc0
hi from pc0
ubuntu#pc1:~$ socat STDIO UDP-DATAGRAM:224.0.0.1:2200,bind=:2200
hi from pc0
ubuntu#pc2:~$ socat STDIO UDP-DATAGRAM:224.0.0.1:2200,bind=:2200
hi from pc0
I'm using the IP 224.0.0.1 as this is used by default for multicast on every machine.
Next, I have tried to implement same stuff with 3 VMs, vb0, vb1 and vb2. Github repo is here.
Now I tried to broadcast from vb0:
vagrant#vb0:~$ socat STDIO UDP-DATAGRAM:224.0.0.1:2200,bind=:2200
hello from vb0
hello from vb0
...and it doesn't broadcast to the other members (as in case of the physical machines above) except itself.
It seems, there are additional settings should be done prior to have this working...
Vagrantfile:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu-12.04-x64"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider "virtualbox" do |vb|
vb.cpus = "2"
vb.memory = "4096"
end
config.vm.provision "chef_apply" do |chef|
chef.recipe = File.read("recipe.rb")
end
config.vm.define "vb0" do |vb0|
vb0.vm.hostname = "vb0"
vb0.vm.network "private_network", ip: "10.20.30.100"
end
config.vm.define "vb1" do |vb1|
vb1.vm.hostname = "vb1"
vb1.vm.network "private_network", ip: "10.20.30.101"
end
config.vm.define "vb2" do |vb2|
vb2.vm.hostname = "vb2"
vb2.vm.network "private_network", ip: "10.20.30.102"
end
end
Running on each device (i.e. vb01, vb1 and vb2):
sudo ip route add 224.0.0.0/4 dev eth1
solved the issue.
On physical environment it's working without doing this.
No idea why we have to run this in Virtual Environment like this one.
vagrant#vb0:~$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.0.2.2 0.0.0.0 UG 100 0 0 eth0
10.0.2.0 * 255.255.255.0 U 0 0 0 eth0
10.20.30.0 * 255.255.255.0 U 0 0 0 eth1
224.0.0.0 * 240.0.0.0 U 0 0 0 eth1
Helpful reference http://troglobit.github.io/multicast-howto.html

Vagrant: can not ping guest machine from the host

I have Mac OS with installed vagrant. On guest machine I have Ubuntu 12. So, what I would like to do is ping guest machine from host.
Guest machine attached to NAT (according to VirtualBox settings)
I found only one interface on guest machine (except lo):
eth0 Link encap:Ethernet HWaddr 08:00:27:88:0c:a6
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe88:ca6/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:581 errors:0 dropped:0 overruns:0 frame:0
TX packets:410 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:61376 (61.3 KB) TX bytes:51599 (51.5 KB)
The thing is that there is not ip address in 10.0.2.* network on the host. Host machine has several vboxnet interfaces, but they all don't have any ip addresses:
vboxnet0: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:00
vboxnet1: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:01
vboxnet2: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:02
vboxnet3: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:03
Have you got any idea why ip address is not assigned to host machine by VirtualBox? What can I do to be able to ping gust machine?
Here is my vagrant file (I removed some commented lines which I do not use):
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "hashicorp/precise64"
# The url from where the 'config.vm.box' box will be fetched if it
# doesn't already exist on the user's system.
# config.vm.box_url = "http://domain.com/path/to/above.box"
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 3306, host: 8086
config.vm.network "forwarded_port", guest: 27017, host: 27017
config.vm.synced_folder "/Users/KoulSlou/Documents/Cloudware12.10", "/vagrant", owner: "www-data", group: "www-data"
config.vm.synced_folder "/Users/KoulSlou/Documents/Cloudware/public","/cloudware", owner: "www-data", group: "www-data"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
#config.vm.network "private_network", ip: "192.168.1.2"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# If true, then any SSH connections made will enable agent forwarding.
# Default value: false
# config.ssh.forward_agent = true
...
end
By default (i.e. when not touching any network configurations), Vagrant configures VMs in VirtualBox to attach their first interface (eth0) to "NAT" (don't confuse it with "NAT Network" which is different option in VirtualBox).
When your VM interface is attached to NAT, the guest will get 10.0.2.15 IP. On the host side you will only see vboxnet# interface without IP. You can think about this interface as a private router for that guest.
VMs that are connected to NAT are not routable from the outside world. This is by design and that's one of the reasons why vboxnet# interface has no IP. VMs are able to access the "outside world" such as the internet and host machine but cannot be accessed from the outside world without port forwarding.
If default behaviour is not what you looking for, Vagrant provides high level abstraction of networking config:
Private network - This will create new subnet that shouldn't collide with host's subnet (or any other subnets the host might have route to). In VirtualBox this will be configured by attaching additional interface to "Host-Only".
Public network - Your VMs will get IP from the same subnet as your host. Basically this is like creating new machine on the same network as your host. In VirtualBox this will be configured by attaching additional interface to "Bridged Adapter".
More advanced networking configurations are possible by configuring networking via provider specific configuration.
Each config has it's own pros and cons and it's really depends on what you plan to achieve.
For additional info check VirtualBox's docs about networking.
I was exactly in the same case, here is a solution that worked for me.
If your vm was up, stop it with:
vagrant halt
Then go to your vagrant box, and open the VagrantFile.
Uncomment (or manually add) the following line inside of it
config.vm.network "public_network"
This will make sure that the next time you "vagrant up" your vm, it will make sure that your vm will get IP from the same subnet as your host (see #m1keil's answer for more details).
Then make your vm up again:
vagrant up
In my case it asked me which interface I should use for the network bridge, here is an excerpt of what I had:
==> default: Available bridged network interfaces:
1) en0: Ethernet
2) en1: Wi-Fi (AirPort)
==> default: When choosing an interface, it is usually the one that is
==> default: being used to connect to the internet.
default: Which interface should the network bridge to? 1
==> default: Preparing network interfaces based on configuration...
Notice that it tells you what your available interfaces are.
Type the number corresponding to the interface that you want, in my case I typed 1 (for en0: Ethernet).
And lastly, connect to your vagrant box.
In my case:
vagrant ssh
Then from the host, if you type ifconfig, you still won't be able to see the ip address of your vm, BUT, if you type ifconfig from your vm, it will give you an ip address that you can ping/access from your host.
Note: If you want to ping/access your host from your guest, be sure that your firewall is off (System>Preferences>Security). The firewall doesn't affect pings from the host to the vm though.
I'm not sure why you are seeing an IP address on the guest but you are not configuring any virtualbox networking at all given that vagrant file. You will want to uncomment the config.vm.network "private network" line and then configure the IP address.
The default setup for virtualbox is to put the host at 10.0.0.2 and expose the whole 10.0.0.0/8 range as a local address so I think anything in the 10.x.x.x range will work for the client vm.

Can't `ssh` onto Private Network

Given the following Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "centos_64"
config.vm.host_name = 'web'
config.vm.network "private_network", ip: "192.168.50.4"
end
Why can't I ssh onto the guest from the host?
$ ssh vagrant#web -p 22
ssh: connect to host web port 22: Connection timed out
But using vagrant ssh works:
$ vagrant ssh
Last login: Tue Mar 4 21:29:24 2014 from 10.0.2.2
[vagrant#web ~]$
As expected, I can ping the IP Address from the guest. But I can't ping from the host.
I'm confused as to why it's happening since my setup does not look different from this configuration.
First, vagrant ssh uses the forwarded port and not the private network address. You can get the configuration with vagrant ssh-config.
Is the name "web" really resolving to the specified IP? Can you ping/connect using the IP instead of the name? If not, verify that you don't have other VMs or external networks with the same address. Also some VPN products mess up the routing.
I managed to change the ssh address with
config.ssh.host = '192.168.0.13'
config.ssh.port = '22'`
as mentioned in https://superuser.com/questions/920536/how-to-change-the-ssh-host-in-vagrantfile/921728#921728
Just because the guest host has a defined hostname does not mean that the host machine will resolve its ip.
You should be able to ssh into the machine by doing:
ssh vagrant#192.168.50.4 <==== vagrant is the default password,
but you can avoid typing it alway by doing:
ssh-copy-id vagrant#192.168.50.4
here is my configuration and it's working for me
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.88.88"
config.ssh.host = "192.168.88.88"