使用 Vagrant + VirtualBox 快速构建 CentOS 下的 Docker 环境

Vagrant - 基础概念:

Vagrant 是什么?

Vagrant是一款用于在单个工作流程中构建和管理虚拟机环境的工具。凭借易于使用的工作流程和专注于自动化,Vagrant降低了开发环境设置时间,提高了开发效率。

Vagrant 是构建在虚拟化技术之上的虚拟机运行环境管理工具:

  • 建立和删除虚拟机
  • 配置虚拟机运行参数
  • 管理虚拟机运行状态
  • 自动化配置和安装开发环境
  • 打包和分发虚拟机运行环境

Vagrant的适用范围

  • 开发
  • 测试

参考:https://www.vagrantup.com/intro/index.html

Vagrant - 下载安装:

Vagrant 下载:https://www.vagrantup.com/downloads.html

VirtualBox 下载:https://www.virtualbox.org/wiki/Downloads

Vagrant - 常用操作:

以下是 Vagrant 的常用操作命令:

命令 作用
vagrant box add 添加box的操作
vagrant init 初始化box的操作,会生成vagrant的配置文件Vagrantfile
vagrant up 启动本地环境
vagrant ssh 通过ssh登录本地环境所在虚拟机
vagrant halt 关闭本地环境
vagrant suspend 暂停本地环境
vagrant resume 恢复本地环境
vagrant reload 修改了Vagrantfile后,使之生效(相当于先 halt,再 up)
vagrant destroy 彻底移除本地环境
vagrant box list 显示当前已经添加的box列表
vagrant box remove 删除相应的box
vagrant package 打包命令,可以把当前的运行的虚拟机环境进行打包
vagrant plugin 用于安装卸载插件
vagrant status 获取当前虚拟机的状态
vagrant global-status 显示当前用户Vagrant的所有环境状态

Vagrant - Vgrantfile:

Vagrantfile的主要功能是对虚拟机器进行配置,

官方文档: https://www.vagrantup.com/docs/vagrantfile/

当执行过vagrant init之后 vagrant 会生成一个名为Vagrantfile的文件:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.

# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "base"

# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false

# 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.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"

# 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"

# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"

# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.

# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end

配置版本:

在命令终端执行完vagrant init之后,Vagrant 大致有以下几种形式:

1
2
3
4
5
6
7
Vagrant.configure("1") do |config|
# v1 configs...
end

Vagrant.configure("2") do |config|
# v2 configs...
end

目前,只有两个受支持的版本:“1”和“2”。 版本”1”代表Vagrant 1.0.x的配置。 版本“2”代表1.1以上到2.0.x的配置。

最低Vagrant版本:

可以在Vagrantfile中指定一组Vagrant版本要求,以强制人们使用Vagrant文件的特定版本的Vagrant。 这可以帮助解决使用带有Vagrantfile的过时或过时的Vagrant版本可能引起的兼容性问题。

应使用Vagrant.require_version帮助程序在Vagrant文件的顶部指定Vagrant版本要求:

1
Vagrant.require_version ">= 1.3.5"

在上面的情况下,只有加载它的版本是Vagrant 1.3.5或更高版本,Vagrantfile才会加载。

还可以指定多个需求:

1
Vagrant.require_version ">= 1.3.5", "< 1.4.0"

提示与技巧

Vagrantfile是一种非常灵活的配置格式。 它基于Ruby,你可以用它做很多事情。 然而,同样的道理,因为它是Ruby,所以有很多方法可以让你在脚下自我射击。 在本页使用一些提示和技巧时,请注意正确使用它们。

参考:https://www.vagrantup.com/docs/vagrantfile/tips.html

循环创建虚拟机

如果你想对许多多机器应用稍微不同的配置,你可以使用一个循环来做到这一点。 例如,如果你想创建三台机器:

1
2
3
4
5
6
(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end

在ssh会话中覆盖主机语言环境:

通常,主机语言环境变量传递给虚拟机。 如果虚拟机软件不支持主机语言环境,则可能会导致失败。 一种可能的解决方案是覆盖Vagrantfile中的语言环境:

1
2
3
4
5
ENV["LC_ALL"] = "en_US.UTF-8"

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

机器设置:

以下几组配置以config.开头的配置信息定义了虚拟机的配置信息。

config.vm

config.vm中设置了Vagrant管理的机器的配置。

配置 作用
config.vm.boot_timeout Vagrant等待机器启动并可访问的时间(秒 默认情况下,这是300秒。
config.vm.box 这将配置该机器要下载的box。可以去HashiCorp/Vagrant Cloud中查找已安装框的名称或框的简写名称。此选项需要Vagrant 1.5或更高版本。
config.vm.box_check_update 如果为true,Vagrant会在每次执行vagrant up时检查配置的config.vm.box的更新。 如果发现更新,Vagrant会告诉用户.
config.vm.box_download_checksum config.vm.box_url指定的box的校验。如果未指定,则不会执行校验和比较。如果指定,Vagrant会将下载的box校验与这个值和错误进行比较,如果指定了此选项,则还必须指定`config.vm.box_download_checksum_type。
config.vm.box_download_checksum_type 指定的校验和类型。支持的值目前是“md5”,“sha1”和“sha256”,如果执行则还必须指定config.vm.box_download_checksum
config.vm.box_download_client_cert 下载邮箱时使用的客户端证书的路径(如果有必要)。 默认情况下,不使用客户端证书来下载该框。
config.vm.box_download_ca_cert 直接下载盒子时使用的CA证书包的路径。 默认情况下,Vagrant将使用Mozilla CA证书包。
config.vm.box_download_ca_path 包含CA证书的目录的路径,用于直接下载box。 默认情况下,Vagrant将使用Mozilla CA证书包。
config.vm.box_download_insecure 如果为true,则来自服务器的SSL证书将不会被验证。 默认情况下,如果URL是HTTPS URL,则SSL证书将被验证。
config.vm.box_download_location_trusted 如果为true,则所有HTTP重定向将被视为可信。这意味着用于初始URL的凭证将用于所有后续重定向。默认情况下,重定向位置不受信任,因此凭据(如果指定)仅用于初始HTTP请求。
config.vm.box_url 可以找到配置的 box的URL。如果config.vm.box的是值是HashiCorp或者Vagrant Cloud中的一个box的简写,那么不需要指定该值。否则,它应该指向没有安装的盒子可以找到的适当位置。
config.vm.box_version 要使用box的版本
config.vm.communicator 用于连接到 guest box 的通信器类型。默认情况下是“ssh”,但对于 Windows 虚拟机应更改为“winrm”。
config.vm.graceful_halt_timeout 调用 vagrant halt 时 Vagrant 等待机器正常停止的时间。默认为 60 秒。
config.vm.guest 将在本机中运行的客户操作系统。默认为 linux,Vagrant 会自动检测正确的发行版。Vagrant 需要知道这些信息才能执行某些客户操作系统特定的事情,例如挂载目录和配置网络。
config.vm.hostname 机器应具有的主机名。默认为 nil。如果为 nil,Vagrant 将不管理主机名。如果设置为字符串,主机名将在引导时设置。
config.vm.network 参考下文网络配置
config.vm.post_up_message 执行 vagrant up 之后显示给用户的消息,可以用于指示如何访问开发环境的各个组件等。
config.vm.provider 配置 provider 特定的配置,该配置用于修改特定于某个 provider 的设置。如果您正在配置的 provider 不存在或未在运行 Vagrant 的系统上设置,则 Vagrant 将忽略此配置块。这允许共享一个适用于多个 provider 的 Vagrantfile,即使没有安装所有的 provider(至少要安装 Vagrantfile 要求的一个 provider)。
config.vm.provision 在机器上配置 provisioner,以便在创建机器时自动安装和配置软件。 参考:provisioner
config.vm.synced_folder 在机器上配置已同步的目录,以便主机上的目录可以与客户机同步。
config.vm.usable_port_range Vagrant 可以使用的用来处理端口冲突的一系列端口。默认为 2200..2250。

config.ssh

config.ssh涉及配置Vagrant如何通过SSH访问你的机器。大多数Vagrant的设置,默认值通常就够用了,但是我们还是可以根据自己的实际情况做出微调。

配置 作用
config.ssh.username 默认设置Vagrant将SSH作为用户名。如果自定义设置了用户名,则可以自由覆盖此内容。
config.ssh.password 设置Vagrant将用于验证SSH用户的密码。Vagrant建议在下面使用基于密钥的身份验证而不是密码。
config.ssh.host SSH进入的主机名或IP。默认情况下,这是空的,因为服务提供商通常会为您解决这个问题。
config.ssh.port 进入SSH的端口。默认情况下,这是端口22。
config.ssh.guest_port 运行SSH的guest虚拟机上的端口。这被一些提供商用来检测转发的SSH端口。例如,如果设置为22(默认值),并且Vagrant从主机上的端口4567检测到来宾端口22上的转发端口,则Vagrant将尝试使用端口4567与来宾进行对话(如果没有其他端口)选项。
config.ssh.private_key_path 用于SSH访问客机的私钥的路径。默认情况下,这是随Vagrant一起提供的不安全私钥,因为这是公共盒子使用的私钥。如果您使用自定义SSH密钥创建自己的自定义框,则应该指向该私钥。
config.ssh.keys_only 仅使用Vagrant提供的SSH私钥(不要使用存储在ssh-agent中的任何密钥)。默认值是true。
config.ssh.verify_host_key 执行严格的主机密钥验证。默认值是false。
config.ssh.forward_agent 如果为true,则启用通过SSH连接的代理转发。默认为false。
config.ssh.forward_x11 如果为true,则启用通过SSH连接进行的X11转发。默认为false。
config.ssh.forward_env 要转发给guest虚拟机的主机环境变量数组
config.ssh.insert_key 如果为true,Vagrant将自动插入一个用于SSH的密钥对,如果检测到,则替换机器内部的Vagrant默认不安全密钥。默认为 true
config.ssh.proxy_command 执行命令行命令,接收要在stdin上发送到SSH的数据。
config.ssh.pty 如果为true,pty将用于供应。默认为false。
config.ssh.keep_alive 如果为true,则此设置将默认每隔5秒发送一次保持活动数据包,以保持连接处于活动状态。
config.ssh.shell 执行来自Vagrant的SSH命令时使用的shell。默认情况下,这是bash -l。请注意,这对运行vagrant ssh时获得的shell没有影响。此配置选项仅影响在Vagrant内部执行命令时使用的shell。
config.ssh.export_command_template 用于在活动会话中生成导出的环境变量的模板。
config.ssh.sudo_command 使用sudo执行命令时使用的命令。
config.ssh.compression 如果设置为false,则此设置将不包括ssh进入机器时的压缩设置。 如果没有设置,它将默认为true,Compression = yes将使用ssh启用。
config.ssh.dsa_authentication 如果为false,则此设置在ssh登录到计算机时不包括DSAAuthentication。 如果未设置,则默认为true,DSAAuthentication = yes将与ssh一起使用。
config.ssh.extra_args 此设置值直接传递到ssh可执行文件中。 这使您可以传递任何命令来执行诸如反向隧道切入ssh程序之类的任务。

config.vagrant:

在设置中config.vagrant修改Vagrant本身的行为。

config.vagrant.host: 设置运行Vagrant主机的类型。默认情况下,这是:detect,这会导致Vagrant自动检测主机。Vagrant需要知道,以执行一些特定主机的东西,如准备NFS文件夹,如果他们启用了此信息。如果自动检测失败的话,您应该手动设置此配置。

config.vagrant.sensitive:(字符串,数组) 值不应该显示在Vagrant的输出值或列表。值将从Vagrant的正常UI输出以及记录器输出中去除。

1
config.vagrant.sensitive = ["MySecretPassword", ENV["MY_TOKEN"]]

config.winrm:https://www.vagrantup.com/docs/vagrantfile/winrm_settings.html

config.winssh: https://www.vagrantup.com/docs/vagrantfile/winssh_settings.html

Vagrant - 环境构建:

镜像下载:

由于网络的原因只能在:http://www.vagrantbox.es/下载。

下载完成之后是一个 .box文件。

环境构建:

创建一个文件夹,用来存放vagrantfile

1
➜  ~ cd Vagrant && mkdir centos && cd centos

添加一个 box 到当前的 目录中:

1
2
3
4
5
6
➜  centos vagrant box add --name centos ~/Public/Mirrors/centos-7.3.16.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos' (v0) for provider:
box: Unpacking necessary files from:
file:///Users/Yang/Public/Mirrors/centos-7.3.16.box
==> box: Successfully added box 'centos' (v0) for 'virtualbox'!

初始化一个Vagrant文件:

1
2
3
4
5
➜  centos vagrant init centos
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

编辑Vagrantfile文件:

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
30
31
32
33
34
35
➜  centos vim Vagrantfile

# 编辑 Vagrantfile 文件,添加以下内容

### start
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">=1.6.0"
boxes = [
{
:name => "docker-host",
:eth1 => "192.168.100.100",
:mem => "1024",
:cpu => "1"
}
]

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

boxes.each do |opts|
config.vm.define opts[:name] do |config|
config.vm.hostname = opts[:name]

config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", opts[:mem]]
v.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
end
config.vm.network :private_network,ip: opts[:eth1]
end
end
config.vm.synced_folder "~/Share", "/home/vagrant/labs"
config.vm.provision "shell", privileged: true, path: "./setup.sh"
end
### end

在当前目录下创建 setup.sh脚本文件,此举是为了安装 docker 环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
#/bin/sh

# install some tools
sudo yum install -y git vim gcc glibc-static telnet bridge-utils net-tools

# install docker
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh

# start docker service
sudo systemctl start docker

rm -rf get-docker.sh

配置完成后开始启动本地环境:

1
➜  centos vagrant up   # 过程省略 大概要等个两三分钟的样子

通过 SSH 进入到刚才启动成功的机器中:

1
2
3
4
5
➜  centos vagrant ssh
[vagrant@docker-host ~]$ cat /etc/centos-release # 查看 centos 的版本
CentOS Linux release 7.3.1611 (Core)
[vagrant@docker-host ~]$ docker -v # 查看 docker 的版本
Docker version 18.05.0-ce, build f150324

docker 相关配置,此举是为了能够让vagrant用户有权限对 docker 进行操作:

1
2
3
4
5
6
7
8
9
[vagrant@docker-host labs]$ sudo systemctl start docker  # 启动 docker
[vagrant@docker-host labs]$ sudo systemctl stop docker # 停止 docker
[vagrant@docker-host labs]$ sudo groupadd docker # 创建 docker 组
[vagrant@docker-host labs]$ sudo gpasswd -a vagrant docker # 将用户添加到docker组中

# 此时停止 docker 退出 shell 然后再重新登录

[vagrant@docker-host ~]$ systemctl start docker #此处需要认证一下 密码为: vagrant
[vagrant@docker-host ~]$ systemctl status docker # 查看 docker 的运行状态

docker hello-world:

1
2
[vagrant@docker-host ~]$ docker pull hello-world
[vagrant@docker-host ~]$ docker run hello-world

出现Hello from Docker!则说明 docker 环境没问题。

对了 root用户的密码也是vagrant

Vagrant - 安装插件:

快照插件:

使用Vagrant的快照功能可以很方便快速的创建当前虚拟机的一个临时备份状态,在进行重要操作时可以先创建一个快照以便在操作失误后快速恢复。

1、安装插件:

1
2
3
4
vagrant plugin install vagrant-vbox-snapshot
Installing the 'vagrant-vbox-snapshot' plugin. This can take a few minutes...
Fetching: vagrant-vbox-snapshot-0.0.10.gem (100%)
Installed the plugin 'vagrant-vbox-snapshot (0.0.10)'!

2、使用插件:

1
2
3
4
5
6
7
8
9
10
创建一个快照
vagrant snapshot take [vm-name] # 拍摄快照

vagrant snapshot list # 查看当前的快照列表

vagrant snapshot go [vm-name] <SNAPSHOT_NAME> # 转到指定快照

vagrant snapshot delete [vm-name] <SNAPSHOT_NAME> #删除快照(警告:一个非常慢的操作)

vagrant snapshot back [vm-name] # 返回到当前快照

Done.