vagrant

发布时间 2023-03-29 16:22:50作者: 白色小旋风

vagrant

安装及简单使用

vagrant简介

vagrant可以封装一个 Linux 的开发环境,分发给团队成员。并且通过Vagrantfile配置文件迅速启动多个虚拟机完成开发环境的搭建。
vagrant本身并不具有创建虚拟机的能力,需要通过第三方支持完成虚拟机的创建。而vagrant本身则扮演着虚拟机管理者的角色。这个第三方支持者就是vagrant中的provider的概念。也就是说单独安装vagrant并不能创建虚拟机,需要安装一种provider供vagrant调用才能创建虚拟机。目前主流支持的provider有三种:VirtualBox、hyper-v、VMware。其中VMware需要收费,而hyper-v只有windows系统可以使用,所以我们选择VirtualBox作为provider。

baymax
vagrant和VirtualBox

vagrant中的box可以理解为模板,通过模板我们可以创建虚拟机,也可以将虚拟机重新打包成box形成新的模板。

vagrant和VirtualBox安装

访问vagrant官网'https://www.vagrantup.com/ ' 访问下载页面,找到对应于自己的操作系统的安装包下载后双击即可开始安装,按照默认选项完成完成安装即可。

baymax
vagrant下载界面

访问VirtualBox官网' https://www.virtualbox.org/ ' 下载安装包双击即可开始安装,按照默认选项完成完成安装即可。

baymax
VirtualBox下载界面
安装完成后打开命令行,输入命令
vagrant --version

能够打印vagrant版本即表示安装成功。

baymax
vagrant安装成功,打印版本

vagrant简单使用

  1. box导入
    vagrant支持启动虚拟机时先在本地查询需要使用的box是否存在,不存在则自动下载。但是国内访问外网不稳定,对应box又比较大有时候下载不了。所以我们提前使用国内的box源先导入box到vagrant中再使用对应box。我们使用centos/7作为示例box。

使用下面的命令添加box

vagrant box add --name=centos7 --provider=virtualbox "https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box" 

其中name参数指定下载后的box名称,启动虚拟机的时候通过该名称关联box。provider命令指定下载的box对应的provider。不同provider之间的box不能共用。上面的url为provider为virtualbox的centos/7的下载源。
可以访问 "https://app.vagrantup.com/boxes/search" 查询可以使用的box,可惜有时候下载不了或者下载很慢,国内没有统一的仓库源需要对应box需要自己找。

baymax
vagrant box查询
  1. Vagrantfile创建
    新建一个空文件夹,在命令行中进入新创建的文件夹。输入如下命令
vagrant init centos7

该命令会创建一个默认的Vagrantfile文件,文件除了注释有效代码只有三行。

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
end

Vagrantfile文件为ruby语言编写,不过简单使用不必需要知道ruby的语法,照猫画虎即可。第一次使用我们不更改Vagrantfile。

  1. 虚拟机启动
    输入如下命令
vagrant up

vagrant会根据Vagrantfile启动虚拟机。启动完成后我们可以使用status命令查看虚拟机状态

vagrant status
baymax
vagrant status查看虚拟机状态

可以看到,名字叫defaul的虚拟机已经处于run。虚拟机的名称可以通过Vagrantfile指定,后面我们会说明Vagrantfile的使用。至此一个centos7的虚拟机就创建完成了

  1. vagrant ssh链接虚拟机
    虚拟机创建完成后我们可以通过命令进入虚拟机当中。
vagrant ssh

可以看到我们已经进入虚拟机了。后面我们会介绍其他的进入虚拟机的方式。输入exit可以退出虚拟机。

baymax
vagrant进入虚拟机

vagrant ssh链接

key链接虚拟机

可以使用下面的命令查询vagrant创建的虚拟机的ssh链接配置

vagrant ssh-config

结果如下

baymax
vagrant ssh-config输出
其中 ``` HostName 127.0.0.1 User vagrant Port 2222 IdentityFile E:/vagrant/.vagrant/machines/default/virtualbox/private_key ``` HostName为虚拟机的链接地址,使用VirtualBox作为provider一般为"127.0.0.1"。User表示虚拟机用户名称。Port为ssh链接端口。 IdentityFile表示链接虚拟机的private_key的存放位置。 我们可以使用该key通过ssh命令直接链接虚拟机。命令如下,其中private_key地址需要替换成你自己的private_key的地址。
 ssh vagrant@127.0.0.1 -p 2222 -i  E:/vagrant/.vagrant/machines/default/virtualbox/private_key

如出现提示,选择yes即可进入虚拟机。

密码链接虚拟机

如果我们想要使用密码的方式链接虚拟机,默认是无法链接的。ssh-config的输出中有

 PasswordAuthentication no

表示,无法使用密码的认证方式。如果需要密码的方式链接虚拟机,需要进入虚拟机中修改配置文件。

sudo vi /etc/ssh/sshd_config

将PasswordAuthentication改为yes

PasswordAuthentication yes

然后重启虚拟机即可使用密码登录。

vagrant reload

默认用户名密码都是vagrant。如果已经使用ssh命令以key方式登录过一次虚拟机还需要先删除用户.ssh文件夹下的known_hosts。该文件在"C:\Users\xxx.ssh" 中,需要将xxx替换为你自己的用户名。

ssh vagrant@127.0.0.1 -p 2222

vagrant常用命令介绍

使用 list-commands命令可以查看vagrant的所有命令。

vagrant list-commands

比较常用的有:

  • box 管理box
  • destroy 销毁一个虚拟机
  • halt 停止一个虚拟机
  • init 初始化一个Vagrantfile
  • list-commands 查看所有命令
  • help 获取一个命令的说明
  • package 将虚拟机打包成box
  • plugin 插件管理命令
  • reload 重启一个虚拟机
  • resume恢复虚拟机
  • ssh 链接一个虚拟机
  • ssh-config 获取ssh配置
  • status 查看虚拟机状态
  • suspend 暂停一个虚拟机
  • up 启动一个虚拟机
baymax
vagrant list-commands查询结果

这里我们只介绍box以及虚拟机相关命令。其他命令如ssh和ssh-config已经在启动第一个虚拟机时介绍过了,而package等命令则在后面讲到对应功能时介绍。

box相关命令

box命令用来管理vagrant中的box。
除了使用help命令外,使用--help参数也能查询对应命令的说明。如查看box相关说明

vagrant box --help
baymax
vagrant box说明
* add命令用来添加一个box 可以继续使用help参数查看add的说明 ```powershell vagrant box add --help ```
baymax
vagrant add box说明

一般我们找到对应box直接使用add命令指定provider就能下载对应box。不过国内网速慢有时候下载不了或者需要很长时间,可以直接指定国内下载源下载。

vagrant box add --provider=virtualbox centos/7
vagrant box add --name=centos7 --provider=virtualbox "https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box" 
  • list 查看所有已添加box
vagrant box list
  • remove 删除一个box
vagrant box remove  --provider=virtualbox centos/7

虚拟机相关命令

  • halt停止一个虚拟机,相当于关机
vagrant halt default
  • reload 重启虚拟机
vagrant reload default
  • status 查询虚拟机状态
vagrant status default
  • suspend 暂停一个虚拟机
vagrant suspend default
  • up启动虚拟机
vagrant up
  • resume恢复虚拟机,将虚拟机从暂停状态恢复,用于恢复suspend暂停了的虚拟机。
vagrant resume default

.vagrant 以及 .vagrant.d 目录

vagrant使用过程中有两个比较重要的目录 .vagrant 和 .vagrant.d。

下载到本地的box就存储在 .vagrant.d。该目录存放在用户目录下。比如对于windows用户就是"C:\Users\xxxx"。其中xxxx为当前用户名称。

baymax
.vagrant.d目录下文件结构

其中boxes文件夹下存放了vagrant的box。centos7为box名称,0为box版本,virtualbox表明对应的provider。

insecure_private_key存放了默认的私有key,如果我们在Vagrantfile配置config.ssh.insert_key=false,则不会为新的虚拟机创建新的秘钥对而使用默认密钥对,此时使用该目录下的insecure_private_key即可链接虚拟机。该配置在管理多个虚拟机的时候可以方便管理key,但是不安全因为vagrant用户的insecure_private_key都是相同的。

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  config.ssh.insert_key=false
end

.vagrant与Vagrantfile放在一个目录下,在创建虚拟机时由vagrant创建。.vagrant则存放了对应的虚拟机相关的文件。

baymax
.vagrant目录下文件结构

其中machines文件夹中的default文件夹下的virtualbox文件夹下的private_key文件存放了名字叫default的虚拟机的私钥。之所以使用"vagrant ssh"命令时不用指定私钥地址,就是因为该命令默认查询了这个位置的私钥。

Vagrantfile介绍

使用init生成默认Vagrantfile有三行,第一行中的2表示配置方式的版本,一般不用更改。do和end组成一个配置对,中间写配置信息。

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
end

当我们想配置多个虚拟机时,可以使用define配置。

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  
  config.vm.define :demo1 do |demo1|
    demo1.vm.hostname = "demohost1"
    demo1.ssh.insert_key=false
  end
 
  config.vm.define :demo2 do |demo2|
    demo2.vm.hostname = "demohost2"
    demo2.ssh.insert_key=false
  end
end

第二行中的配置在define的do和end对之外,表示全局配置对所有虚拟机都有效,而define中的配置对对应的虚拟机有效。上面的Vagrantfile定义了两个虚拟机demo1和demo2。其中从全局配置中配置了两个虚拟机使用的box都是centos7。而在define中配置了虚拟机的hostname,并且两个虚拟机都不创建新的密钥对,使用默认不安全的密钥对。

baymax
启动两个虚拟机,并为每个虚拟机配置hostname
我们使用up命令启动后,可以看到两个虚拟机都已经启动了。并且进入虚拟后可以看到hostname配置已经生效了。

config.vm中可以配置虚拟机相关的很多配置,可以查看官网的帮助文档查看Vagrantfile相关的配置。'"https://developer.hashicorp.com/vagrant/docs"

baymax
vm配置官网说明
除了可以配置需要使用的box,版本,以及provider之外,还可以配置hostname、磁盘挂载和网络。磁盘挂载和网络后面会说明。

同理可以在帮助文档中查看ssh相关配置信息。

文件映射

使用virtualbox作为provider的时候直接使用synced_folder配置文件映射,会报错。需要给virtualbox工具安装插件。我们直接给vagrant安装插件,使用vagrant自动为virtualbox安装需要的插件这样操作更方便。
先为vagrant安装vagrant-vbguest插件,0.31版本有bug,启动虚拟机的时候会报"No Virtualbox Guest Additionsinstallation found"。所以使用0.21版本,安装过程从外网下载插件比较慢需要等一段时间。

 vagrant plugin install vagrant-vbguest --plugin-version 0.21

编辑Vagrantfile,添加文件映射配置

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  config.vm.define :demo1 do |demo1|
    demo1.vm.hostname = "demohost1"
	demo1.vm.synced_folder "./data/", "/data/"
  end
end

如果使用相对路径,相对路径的基地址为Vagrantfile所在文件夹。synced_folder将本地路径"./data/"映射到虚拟机中的"/data/"文件夹下。
synced_folder可以添加 type参数如

demo1.vm.synced_folder "./data/", "/data/", type: "rsync"

不指定type参数时系统自动选择合适的文件映射方式。一般不需要更改。rsync表示仅创建虚拟机时将宿主机目录同步到虚拟机中一次。
vagrant-vbguest插件在每次创建虚拟机时都会下载插件,导致虚拟机创建时间很长,如果不使用磁盘挂载功能可以不安装或者卸载这个插件。rsync类型的挂载不需要插件支持,如果rsync可以满足需求也不需要使用该插件。

vagrant网络配置

虚拟机链接网络有三种方式,端口映射,私有网络和公有网络。端口映射是将主机的端口映射到虚拟机的端口上,比如使用virtualbox作为provider的时候启动虚拟机默认将虚拟机22端口映射到宿主机2222端口。私有网络是只有主机可以访问虚拟机,如果多个虚拟机设定在同一个网段也可以互相访问。公有网络下的虚拟机享受实体机器一样的待遇,一样的网络配置。

端口映射

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  config.vm.define :demo1 do |demo1|
    demo1.vm.hostname = "demohost1"
	demo1.vm.network "forwarded_port", guest: 22, host: 12222
  end
  
  config.vm.define :demo2 do |demo2|
    demo2.vm.hostname = "demohost2"
	demo2.vm.network "forwarded_port", guest: 22, host: 12223
  end
end

如上面的Vagrantfile定义了两个虚拟机,并将虚拟机的22端口映射到本机的12222和12223两个端口上。
这种方式的好处是简单容易理解,但是如果管理的虚拟机比较多容易造成混乱。

私有网络

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  config.vm.define :demo1 do |demo1|
    demo1.vm.hostname = "demohost1"
	demo1.vm.network "private_network", ip: "192.168.1.2"
  end
  
  config.vm.define :demo2 do |demo2|
    demo2.vm.hostname = "demohost2"
	demo2.vm.network "private_network", ip: "192.168.1.3"
  end
end

上面的Vagrantfile定义了两个虚拟机,使用私有网络,可以通过ip参数指定ip地址。此时在本地可以直接通过配置的ip地址访问虚拟机。
私有网络虽然安全只有自己可以访问,但是也因此不方便合作。

公有网络

Vagrant.configure("2") do |config|
  config.vm.box = "centos7"
  config.vm.define :demo1 do |demo1|
    demo1.vm.hostname = "demohost1"
	demo1.vm.network "public_network"
  end
  
  config.vm.define :demo2 do |demo2|
    demo2.vm.hostname = "demohost2"
	demo2.vm.network "public_network", ip: "192.168.1.3"
  end
end

上面定义的两个虚拟机,使用公有网络的方式接入网络,如果不指定ip地址将由路由器动态分配ip地址。
我们可以进入虚拟机中查看ip地址,比如使用

ip addr show

如果指定的ip已经被使用则会出现ip绑定不成功的现象。
公有网络可以满足团队合作的需求,其他同事机器可以直接链接虚拟机,缺点是不安全,且需要占用ip地址。

box导入和导出

vagrant支持通过box创建一个虚拟机,然后进入虚拟机后进行需要的操作,再将虚拟机打包成新的box,以后按照该box作为模板创建新的虚拟机。比如使用centos7这个box创建一个虚拟机,进入虚拟机后安装mysql,再将安装好mysql的虚拟机打包成新的box。
使用本地打包的box创建虚拟机时vagrant需要先登录虚拟机才能创建密钥对,而又需要密钥对才能登录虚拟机,导致启动失败。打包前在虚拟机中打开用户名密码登录然后再打包box,以后需要使用该box创建虚拟机时在对应的Vagrantfile中配置用户名密码登录是比较方便的方式。

我们以centos7启动虚拟机后安装好mysql,开始打包该虚拟机。
如上所述我们先打开密码用户名登录方式。

sudo vi /etc/ssh/sshd_config

进入虚拟机修改上面的文件,将PasswordAuthentication从no更改为yes。然后我们停止虚拟机。

vagrant halt

需要使用virtualbox命令查看虚拟机名称,若该命令不存在则需要将virtualbox安装路径添加到环境变量中。

 vboxmanage list vms

使用查询到的虚拟机名称,打包一个box文件

vagrant package --base vagrant_mysql_1679555284956_18302 --output centos-mysql.box

其中需要将base参数的值替换成vboxmanage命令查询到的虚拟机名称。output参数指定输出的box文件名。完成后会在指定路径生成centos-mysql.box文件。不指定文件路径则在当前路径生成box文件。
再将生成的box文件导入到vagrant中

vagrant box add --name centos-mysql centos-mysql.box

再编辑新的Vagrantfile。将使用的box指定为我们新导入的box。

Vagrant.configure("2") do |config|
  config.vm.box = "centos-mysql"
  config.vm.define :mysql do |mysql|
    mysql.ssh.username = "vagrant"
    mysql.ssh.password = "vagrant"
	mysql.vm.synced_folder ".", "/vagrant", type: "rsync"
  end
end

上面第四第五行配置了虚拟机的用户名密码,vagrant在启动虚拟机时会使用该用户名密码登录虚拟机。第六行配置了一个rsync方式的目录挂载。默认会挂载当前目录到虚拟机的/vagrant目录下并且会自动选择挂载方式,如上所述其他挂载方式需要安装插件否则会启动失败,如果rsync方式可以满足需求的话可以增加该行配置不用安装插件。
启动虚拟机后,默认用户名密码都是vagrant,登录虚拟机。
可以看到已经存在mysql服务在正常运行中。

baymax
centos-mysql 成功启动