虚拟化工具Vagrant简明使用教程
简单介绍
如果你有一台物理服务器,现在需要租出去,你会怎么做呢?直接出租出去?当然是变成多台,然后分别出租出去呀,怎么做呢?答案是:虚拟化!
早年服务器的租用费用很高,而现在,一台云服务器,学生都可以以白菜价拥有了,当你拥有自己的VPS,可以在上面搭建网站,ftp服务器,或者是自建的云盘,如果是国外的vps,你还可以自建一个梯子,连接外面的世界。
一台物理服务器,通常配置比较高,一个16核32线程的服务器,可以开31台云服务器(如果是docker这种轻量级服务器,可以运行的更多),依靠的是虚拟化技术,这些云服务器,实际是运行在物理服务器上的虚拟机。但是这些虚拟机都要一个一个的安装吗?这样做效率很低,于是便有了容器编排工具,例如vagrant
Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境。它使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境 (来自百度百科)
vagrant 不仅用于服务器领域,也可以用在个人的学习,测试环境中,安装和启动比直接安装快得多。比如,你先搭建一个网站开发环境,可以去官网找到别人打包好的镜像,直接使用别人分享的成果,或者想做测试,又怕改变本机的环境,可以提供一个隔离的环境。下面做一个简单的介绍,详细教程可以查看官方文档:vagrant docs
1.安装
vagrant是全平台的,但它的使用需要结合虚拟机管理,最常用的是开源的virtualbox,因此需要安装vagrant和virtualbox
2.常用命令
vagrant命令都是以vagrant 开头的,在终端中输入vagrant -h 可以看到常用的一些命令,如果想查看具体的命令,可以在子命令下加-h参数,例如vagrant box -h 或 vagrant box add -h,可以找到与box镜像操作相关的使用帮助。
3.导入一个base box
vagrant 并不是虚拟机,它是一种与虚拟机结合起来用的编排工具,本身也不生产系统镜像,vagrant使用的镜像被称为base box,可以在vagrant官网上找到,也可以在github上找到。导入一个box的命令:1
2vagrant box add {name} {url}
vagrant init {name} #导入box并生成Vagrantfile文件
box镜像在亚马逊的服务器上,因此在国内,直接添加可能会非常慢,可以先下载离线镜像,然后在导入,离线下载方法:
url + versions/版本号/ + /providers/virtualbox.box
eg:
https://app.vagrantup.com/ubuntu/boxes/xenial64/versions/20180126.0.0/providers/virtualbox.box
导入离线镜像到仓库时,url为box文件的路径
vagrant box add /path/to/your/box
直接添加离线box时,会元数据,因此版本号会变成0,可以通过json文件添加box,如下:
eg:可以将ubuntu/trusty64.json文件与ubuntu/trusty64.box文件放在同一个文件夹
1 | { |
vagrant box add ubuntu/trusty64.json
查看已添加的box: vagrant box list
Windows上默认box仓库在C盘用户文件夹的”.vagrant.d”中,如果C盘不够,可以通过设置环境变量’ VAGRANT_HOME’,改变此文件夹的位置
4.启动并设置虚拟机
1 | vagrant init title #eg: vagrant init ubuntu/trusty64 |
vagrant init 会生成Vagrantfile文件,可以编辑Vagrantfile文件,对虚拟机进行一些自定义设置,Vagrantfile是ruby脚本,但没学过ruby也可以无压力看懂。
eg:
1 | # -*- mode: ruby -*- |
每一部分的含义
1 | # Installation script |
以上是provision的内容,定义了在第一次启动时,虚拟机执行的操作,可以进行一些自动化部署
config.vm.network
设定网络,有三种,private_network(对应虚拟机Host only),public_network(对应虚拟机桥接模式,需要指定桥接的网卡,ip地址和子网掩码),forwarded_port,把主机上x端口的请求,发送到虚拟机Y端口上处理
下图是ifconfig查看的网络情况,eth0 是NAT模式(vagrant设置的,必要的,用于连接网络),eth1是私有网络(host only)为手动设置的
hostname
虚拟机中的主机名称(终端上显示的名称),是区分多台虚拟机的重要方式
1 | config.ssh.username = "vagrant" |
ssh登录方式,可以使用 用户名和密码登录,也可以使用公钥对登录,默认使用公钥对登录,默认用户名和密码都是”vagrant”
config.vm.synced_folder
共享文件夹,用于快速在虚拟机和主机之间传送数据
1 | vb.memory = "1024" |
设定虚拟机的内存和核心数
如遇到虚拟机中的Virtualbox guest additions与Virtualbox中的不匹配会有如下提示:
The guest additions on this VM do not match the install version of VirtualBox! This may cause things such as forwarded ports, shared folders, and more to not work properly. If any of those things fail on this machine, please update the guest additions and repackage the box.
可以通过安装vbguest插件来解决,下次启动时会自动安装新的插件vagrant plugin install vagrant-vbguest
5.登录虚拟机
base box多数是没有图形界面的(程序员要啥图形界面 [滑稽脸]),virtualbox的界面太难用,因此选择用ssh连接,vagrant有自带的ssh工具,vagrant ssh
,会根据自动生成的密钥对直接登录进入系统,vagrant ssh-config
可以查看ssh的配置。
Windows上没有ssh客户端,可以选择git bash,或者openssh(windows上,对公钥对的权限有严格要求,有时会导致无法登录,优点是集成到cmd或powershell,但不推荐),也可以使用xshell,putty等工具1
2vagrant ssh
ssh username@{ip}
6. 查看状态,挂起,关机
1 | vagrant status #查看状态 |
7. 销毁和移除box
vagrant destroy
这个命令会删除virtualbox创建的虚拟机但不会移除仓库中的box 文件,移除box用 vagrant box remove box-name
8.导出镜像
当你在虚拟机中做了许多工作后,你可以导出镜像,分享给其他人使用,也可以留存自己使用,节省下次配置的时间。
private_network 需要清除一下网络状态:sudo rm -f /etc/udev/rule.d/70-persistent-net.rules
vagrant halt
先关机
在工程文件夹下(对应的Vagrantfile所在文件夹)1
2vagrant status #查看状态
vagrant package --output your-box-name.box
详细信息请查看 Creating a Base Box
9 同时启动多台虚拟机
附上大神老师写的一次启动多台机器(可用于集群管理)的脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 # -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu-xenial-docker"
config.vm.box_version = "1.0.0-1502068394"
config.vm.box_check_update = false
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 1
end
ssh_key_public = File.readlines("./insecure-key.pub").first.strip
config.vm.provision 'shell', inline: "echo #{ssh_key_public} >> /home/vagrant/.ssh/authorized_keys"
config.vm.provision "file", source: "./insecure-key", destination: "/home/vagrant/.ssh/id_rsa"
config.vm.provision 'shell', inline: "chmod 400 /home/vagrant/.ssh/id_rsa"
IP0 = 20
(1..3).each do |i|
config.vm.define "node#{i}" do |node|
node.vm.network "private_network", ip: "192.168.33.#{i + IP0}"
node.vm.hostname = "node#{i}"
node.vm.synced_folder "./data", "/vagrant_data", create: true, owner: "root", group: "root"
node.vm.provision "shell", inline: <<-SHELL
echo "This is node#{i}" > /etc/motd
SHELL
end
end
end
希望对你有所帮助!