咱們經過配置Vagrantfile配置兩個虛擬機——web服務器和數據庫服務器。node
Vagrant::configure("2") do |config| config.vm.box = "precise64" config.vm.define "web" do |web| web.vm.network "forwarded_port", guest:80,host:8080 web.vm.provision :shell,path: "provision.sh" end config.vm.define "db" do |db| end end
Most commands, such as up, destroy, and reload now take an argument with the name of the machine to affect. As an example, if you wanted to reload just the web machine, you could do this:mysql
$vagrant reload web
By specifying no arguments, Vagrant assumes you want to take action on every machine. So vagrant reload alone would reload both the web and db machines.web
For some commands, this default behavior of taking action on every machine doesn’t make sense. vagrant ssh can’t SSH you into every machine in one terminal! So some commands require a target machine.sql
The output of vagrant status changes, too. It now lists multiple machines and the state of each of them:shell
$ vagrant status Current machine states: web running (virtualbox) db running (virtualbox) This environment represents multiple VMs. The VMs are all listed above with their current state. For more information about a specific VM, run `vagrant status NAME`. For detailed information on the state of a machine as well as helpful instructions on how to change the state of the machine, just call vagrant status with a target machine: $ vagrant status web Current machine states: web running (virtualbox) The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`. In cases where the environment has many machines, you can specify multiple targets in the same command: $ vagrant reload node1 node2 node3 Or, if you’re managing many nodes, you can even use a regular expression. Vagrant assumes if the node name starts and ends with / that it is a regular expression. For example: $ vagrant reload /node\d/ ...
Although the command interface changes slightly, the behavior of commands upon individual machines is unchanged. Everything continues working as you’d expect, only now Vagrant manages multiple machines!數據庫
If multimachine environments were made to model service-oriented architectures, there needs to be a way for the machines to communicate with each other. By default, by simply defining the machines, there is no way for them to communicate.express
By defining a private network on the machines that exists on the same subnet, the machines are able to communicate with each other. When specifying a static IP address with host-only networks on Vagrant, Vagrant by default uses a subnet mask of 255.255.255.0. This means that as long as the first three parts (octets) of the IP address are the same, the machines will be placed on the same network.ubuntu
Vagrant::configure("2") do |config| config.vm.box = "precise64" config.vm.define "web" do |web| web.vm.network "forwarded_port", guest:80,host:8080 web.vm.provision :shell,path: "provision.sh" web.vm.network "private_network",ip: "192.168.33.10" end config.vm.define "db" do |db| db.vm.network "private_network",ip:"192.168.33.11" end end
Now that the basics have been covered, we’ll provision the second machine with the shell provisioner to install MySQL on the second machine, and talk to that MySQL instance from the web machine using the MySQL client.服務器
First, create a new file db_provision.sh in your project root with the following contents:app
export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -y mysql-server sed -i -e 's/127.0.0.1/0.0.0.0/' /etc/mysql/my.cnf restart mysql mysql -uroot mysql <<< "GRANT ALL ON *.* TO 'root'@'%'; FLUSH PRIVILEGES;"
This is the shell script that will provision the db machine. Let’s quickly explain a few parts because it looks considerably different than the script used to set up Apache.
First, we export an environmental variable DEBIAN_FRONTEND with the value 「noninteractive.」 This makes it so that when installing MySQL server, it does not ask us questions for a root password and all that.
Next, we use sed to replace the bind address from loopback to 0.0.0.0, which means all interfaces. This is necessary so that remote machines can connect to the server.
Then, we restart MySQL so that our configuration changes can take effect.
And finally, we tell MySQL to allow root to connect from any host. This is generally very unsafe, but for the purpose of this example, it will work well.
Let’s wire it all up in the Vagrantfile with networking, and also by provisioning the web machine with the MySQL client. The Vagrantfile should look like this:
Vagrant::Configure("2") do |config| config.vm.box = "precise64" config.vm.define "web" do |web| web.vm.network "forwarded_port",guest: 80,host: 8080 web.vm.provision :shell, path: "provision.sh" web.vm.provision :shell, inline: "apt-get install mysql-client" web.vm.network "private_network", ip: "192.168.33.10" end config.vm.define "db" do |db| db.vm.provision :shell, path: "db_provision.sh" db.vm.network "private_network",ip: "192.168.33.11" end end
At this point, you should be able to fully understand the contents of the Vagrantfile. If there are any parts that are confusing or unclear, reread the previous sections until you fully understand them.
Run vagrant destroy to fully destroy both machines if they were running before. We want to start from a clean slate for this example.
After destroying the environment, run vagrant up to bring up both machines. This should take a few minutes, as both machines must fully provision.
Once the machines are running, log in to the web machine via SSH and use the MySQL client to access the db machine. The output should look similar to the following, but may be slightly different depending on versions and so on:
$ vagrant ssh web vagrant@precise64:~$ mysql -uroot -h192.168.33.10 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 48 Server version: 5.5.29-0ubuntu0.12.04.2 (Ubuntu) Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
Success! The web machine is able to connect to a remote MySQL server, except that the remote MySQL server is actually just another virtual machine on the local system. Given this example, it should be clear to see how these concepts can apply to larger or more complex architectures.