使用 Vagrant 管理虚拟环境

学习如何使用 Vagrant 创建和配置虚拟机,并运行部署后的配置。
226 位读者喜欢这篇文章。
7 great open source tools to power your marketing stack

Opensource.com

Vagrant 是一个工具,它提供了一个简单易用的命令行客户端,用于管理虚拟环境。我开始使用它是因为它让我更容易开发网站、测试解决方案和学习新东西。

根据 Vagrant 的网站,“Vagrant 缩短了开发环境设置时间,提高了生产奇偶校验,并使 ‘在我的机器上可以工作’ 成为过去的遗物。”

Vagrant 可以做很多事情,您可以在 Opensource.com 的 Vagrant 开源资源文章中了解更多背景信息。

在本入门指南中,我将演示如何使用 Vagrant 来:

  1. 创建和配置 VirtualBox 虚拟机 (VM)
  2. 运行部署后的配置 Shell 脚本和应用程序

听起来很简单,事实也的确如此。Vagrant 的强大之处在于它拥有一个一致的工作流程,用于部署和配置机器,而与平台或操作系统无关。

我们将首先使用 VirtualBox 作为 **提供者**,设置一个 Ubuntu 16.04 **镜像 (box)**,并将一些 Shell 命令作为 **配置器 (provisioner)** 应用。我将把物理机(例如,笔记本电脑或台式机)称为宿主机,并将 Vagrant VM 称为虚拟机。

在本教程中,我们将整理一个 Vagrantfile,并提供定期检查点以确保我们的文件看起来相同。我们将涵盖以下入门和高级主题:

入门主题

  • 安装 Vagrant
  • 选择 Vagrant 镜像
  • 理解 Vagrantfile
  • 运行虚拟机
  • 使用配置器

高级主题

  • 网络
  • 同步文件夹
  • 部署多台机器
  • 确保一切正常工作

看起来很多,但一旦我们完成,所有内容都将很好地组合在一起。

安装 Vagrant

首先,我们将导航到 VagrantVirtualBox 的下载页面,以安装每个应用程序的最新版本。

我们可以输入以下命令来确保应用程序的最新版本已安装并可以使用。

Vagrant

# vagrant --version
Vagrant 2.0.3

VirtualBox

# VBoxManage --version
5.2.8r121009

选择 Vagrant 镜像

选择 Vagrant 镜像类似于为服务器选择镜像。 在基本层面上,我们选择要使用的操作系统 (OS)。 有些镜像更进一步,并且已经安装了其他软件(例如 Puppet 或 Chef 客户端)。

镜像的首选在线存储库是 Vagrant Cloud; 它为多个提供者提供了大量的 Vagrant 镜像。 在本教程中,我们将使用 Ubuntu Xenial Xerus 16.04 LTS 每日构建版。

理解 Vagrantfile

将 Vagrantfile 视为环境的配置文件。 它描述了 Vagrant 环境在如何构建和配置 VirtualBox VM 方面的情况。

我们需要创建一个空的项目目录来工作,然后使用以下命令从该目录初始化 Vagrant 环境:

# vagrant init ubuntu/xenial64

这只会创建 Vagrantfile; 它不会启动 Vagrant 镜像。

Vagrantfile 具有完善的文档,其中包含大量关于如何使用它的指导。 我们可以使用 --minimal 标志生成最小化的 Vagrantfile。

# vagrant init --minimal ubuntu/xenial64

生成的文件将如下所示:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
end

稍后我们将更多地讨论 Vagrantfile,但现在,让我们启动并运行此镜像。

运行虚拟机

让我们从我们的项目目录发出以下命令:

# vagrant up

第一次执行 vagrant up 需要一段时间,因为它会将镜像下载到您的机器。 在随后的运行中,它会更快,因为它会重用同一个下载的镜像。

一旦虚拟机启动并运行,我们可以通过在我们的项目目录中发出以下命令来 ssh 进入我们的单台机器:

# vagrant ssh

就这样! 从这里,我们应该能够登录到我们的虚拟机并开始使用它。

使用配置器

在继续之前,让我们回顾一下。 到目前为止,我们已经选择了一个镜像并运行了服务器。 在大多数情况下,服务器未配置,并且没有我们可能想要的任何软件。

配置器提供了一种使用诸如 Ansible、Puppet、Chef 甚至 Shell 脚本之类的工具在部署后配置服务器的方法。

在默认 Vagrantfile 中可以找到使用 shell 配置器的示例。 在此示例中,我们将运行命令来更新 apt 并将 Apache2 安装到服务器。

   config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     apt-get install -y apache2
   SHELL

如果我们想使用 Ansible playbook,配置部分将如下所示:

config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
end

一个巧妙的事情是,我们可以通过发出 provision 子命令来仅运行 Vagrantfile 的配置部分。 这非常适合测试脚本或配置管理播放,而无需每次都重新构建虚拟机。

Vagrantfile 检查点

我们最小的 Vagrantfile 应该如下所示:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
   config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     apt-get install -y apache2
   SHELL
end

在添加配置部分之后,我们需要运行此配置子命令:

# vagrant provision

接下来,我们将继续构建我们的 Vagrantfile,涉及一些更高级的主题,为任何想要深入研究的人打下基础。

网络

在本节中,我们将在 VirtualBox 的 vboxnet0 网络上添加一个额外的 IP 地址。 这将允许我们通过 192.168.33.0/24 网络访问机器。

将以下行添加到 Vagrantfile 将配置机器在 192.168.33.0/24 网络上具有额外的 IP。 此行也用作默认 Vagrantfile 中的示例。

config.vm.network "private_network", ip: "192.168.33.10

Vagrantfile 检查点

对于那些正在关注的人来说,这是我们正在工作的 Vagrantfile 的状态:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
   config.vm.network "private_network", ip: "192.168.33.10"
   config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     apt-get install -y apache2
   SHELL
end

接下来,我们需要重新加载我们的配置,以使用这个新的接口和 IP 重新配置我们的机器。 此命令将关闭虚拟机,使用新的 IP 地址重新配置 Virtual Box VM,然后重新启动虚拟机。

# vagrant reload

当它重新启动时,我们的机器应该有两个 IP 地址。

同步文件夹

同步文件夹是我开始使用 Vagrant 的原因。 它们允许我在我的宿主机上使用我的工具进行工作,同时将文件提供给 Web 服务器或应用程序。 它使我的工作流程更加轻松。

默认情况下,宿主机上的项目目录作为 /home/vagrant 挂载到虚拟机。 这在开始时对我有用,但最终,我想自定义此目录的挂载位置。

在我们的示例中,我们定义了项目目录中的 HTML 目录应作为 /var/www/html 挂载,并且用户/组所有权为 root

config.vm.synced_folder "./html", "/var/www/html",
 owner: "root", group: "root"

需要注意的一点是:如果您正在使用同步文件夹作为 Web 服务器文档根目录,则需要禁用 sendfile,否则您可能会遇到文件看起来没有更新的问题。

更新您的 Web 服务器的配置超出了本文的范围,但是以下是您要更新的指令。

在 Apache 中

EnableSendFile Off

在 Nginx 中

sendfile off;

Vagrantfile 检查点

在添加我们的同步文件夹配置后,我们的 Vagrantfile 将如下所示:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
   config.vm.network "private_network", ip: "192.168.33.10"
   config.vm.synced_folder "./html, "/var/www/html",
      owner: "root", group: "root"
   config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     apt-get install -y apache2
   SHELL
end

我们需要重新加载我们的机器以使新配置生效。

# vagrant reload

部署多台机器

我们有时将项目目录称为“环境”,而一台机器算不上一个环境。 最后一个部分扩展了我们的 Vagrantfile 以部署两台机器。

要创建两台机器,我们需要将单台机器的定义封闭在一个 vm.define 块内。 其余配置完全相同。

这是一个 define 块中服务器定义的示例。

Vagrant.configure("2") do |config|

config.vm.define "web" do |web|
    web.vm.box = "web"
    web.vm.box = "ubuntu/xenial64"
     web.vm.network "private_network", ip: "192.168.33.10"
     web.vm.synced_folder "./html", "/var/www/html",
        owner: "root", group: "root"
     web.vm.provision "shell", inline: <<-SHELL
       apt-get update
       apt-get install -y apache2
     SHELL
  end

end

请注意,在 define 块中,我们的变量称为 "web",并且它会通过该块传递,以引用每个配置方法。 我们稍后将使用相同的名称来访问它。

在下一个示例中,我们将向我们的配置中添加第二台名为 "db" 的机器。 在我们之前在第二个块中使用 "web" 的地方,我们将使用 "db" 来引用第二台机器。 我们还将更新我们在 private_network 上的 IP 地址,以便我们可以在机器之间进行通信。

Vagrant.configure("2") do |config|

config.vm.define "web" do |web|
    web.vm.box = "web"
    web.vm.box = "ubuntu/xenial64"
     web.vm.network "private_network", ip: "192.168.33.10"
     web.vm.synced_folder "./html", "/var/www/html",
        owner: "root", group: "root"
     web.vm.provision "shell", inline: <<-SHELL
       apt-get update
       apt-get install -y apache2
     SHELL
  end

  config.vm.define "db" do |db|
      db.vm.box = "db"
      db.vm.box = "ubuntu/xenial64"
       db.vm.network "private_network", ip: "192.168.33.20"
       db.vm.synced_folder "./html", "/var/www/html",
          owner: "root", group: "root"
       db.vm.provision "shell", inline: <<-SHELL
         apt-get update
         apt-get install -y apache2
       SHELL
    end

end

已完成的 Vagrantfile 检查点

在我们的最终 Vagrantfile 中,我们将安装 MySQL 服务器,更新 IP 地址,并从第二台机器中删除同步文件夹的配置。

Vagrant.configure("2") do |config|

config.vm.define "web" do |web|
    web.vm.box = "web"
    web.vm.box = "ubuntu/xenial64"
     web.vm.network "private_network", ip: "192.168.33.10"
     web.vm.synced_folder "./html", "/var/www/html",
        owner: "root", group: "root"
     web.vm.provision "shell", inline: <<-SHELL
       apt-get update
       apt-get install -y apache2
     SHELL
  end

  config.vm.define "db" do |db|
      db.vm.box = "db"
      db.vm.box = "ubuntu/xenial64"
       db.vm.network "private_network", ip: "192.168.33.20"
       db.vm.provision "shell", inline: <<-SHELL
         export DEBIAN_FRONTEND="noninteractive"
         apt-get update
         apt-get install -y mysql-server
       SHELL
    end

end

确保一切正常工作

现在我们有了一个完整的 Vagrantfile。 让我们介绍一个额外的 Vagrant 命令来确保一切正常工作。

让我们销毁我们的机器并从头开始构建它。

以下命令将删除我们之前的 Vagrant 镜像,但保留我们之前下载的镜像。

# vagrant destroy --force

现在我们需要重新启动环境。

# vagrant up

我们可以使用 vagrant ssh 命令 SSH 进入机器:

# vagrant ssh web

或者

# vagrant ssh db

您应该有一个可以扩展的工作 Vagrantfile,并将其用作学习更多知识的基础。 Vagrant 是一个用于测试、开发和学习新事物的功能强大的工具。 我鼓励您继续添加并探索它提供的选项。

User profile image.
Alex Juarez 是 Rackspace 的首席工程师,在该公司工作了 11 年。 Alex 喜欢所有开源的东西,以及培训和指导他人,并且作为 RHCA/RHCI,他非常有资格这样做。 Alex 在许多区域性和全国性的开源会议上发表过演讲,分享知识并鼓励人们学习更多知识。

1 条评论

当您处理 Vagrant 时,使用 https://puphpet.com/ 项目会更容易:)

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.