Vagrant 是一个通用的工具,可以塑造成你认为合适的环境。
在 Vagrant1.6+
这个版本之后,提供了一个新的内置 provider:Docker
,这使得允许在 Vagrant
工具上面管理在容器中运行的开发环境,而不是在虚拟机中。同时,在其他操作系统上面不需要附加任何额外的工具和扩展。
1. 容器开发环境
使用 Vagrant 创建 Docker 环境的优点!
在 Vagrant
中使用了 provider:Docker
之后,使得工作流程变得非常容易和简单,同时还有了 Vagrant
特性的加持,比如跨平台、同步文件夹、预配置程序、目录共享等等优点。在本机本身不是 Linux
的操作系统上面,Vagrant
会自动打开并共享一个代理虚拟机来运行 Docker
环境,这个这个代理虚拟机是完全可定制化的,我们可以在里面根据自己的实际需求进行设置。
由于 Vagrant
的灵活性,你可以保留相同的工作流来管理不使用 Docker
的系统。这可能是另一个基于 Linux
的系统,也可能是完全不同的系统,比如基于 Windows
的开发环境。
2. 使用方式说明
简述一下,使用 Vagrant 创建 Docker 环境的步骤!
在 Vagrant
中创建 Docker
镜像和平常操作 Vagrant
几乎是一样。但需要注意的是,在创建 Docker
镜像的时候,我们不需要设置 config.vm.box
参数。
- [1] Docker Images
- 启动服务:
vagrant up --provider=docker
- 启动服务:
Vagrant
可以使用已经打包或者已经存在镜像,在启动的时候,如果本地不存在的话,会主动去拉去远程仓库上的对应镜像。
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.name = "db"
d.image = "foo/bar"
end
end
- [2] Dockerfiles
- 启动服务:
vagrant up --provider=docker
- 启动服务:
Vagrant
启动的时候,会在本地寻找对应的 Dockerfile
文件,自动进行构建和运行这个容器镜像。当然,也提供了 vagrant reload
来重新 build
该镜像。
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.build_dir = "."
end
end
- [3] Synced Folders and Networking
当使用 Docker
时,Vagrant
会自动将同步的文件夹和网络选项转换为 Docker
卷和转发端口,我们不必使用特定于 docker
的配置来做到这一点。与此同时,Docker Provider
不支持使用 Docker
容器同步的文件夹上的所有者或组的指定选项。
config.vm.synced_folder "/host/dir1", "/guest/dir1", docker_consistency: "cached"
config.vm.synced_folder "/host/dir2", "/guest/dir2", docker_consistency: "delegated"
- [4] Host VM
- 即我们可以指定虚拟机来运行容器服务
如果系统无法运行 Linux
容器,Vagrant
会自动启动一个虚拟机”来运行 Docker
的(启动主机 VM
的一个实例,并在这个 VM
上运行多个容器)。这允许我们基于 docker
的 Vagrant
环境保持可移植性,而不会因其所运行的平台而产生不一致。
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.vagrant_vagrantfile = "../path/to/Vagrantfile"
end
end
3. 相关操作命令
在 Vagrant 上面操作 Docker 容器的相关命令!
Docker Provider
公开了一些额外的 Vagrant
命令,用于与 Docker
容器进行交互。这有助于在 Vagrant
之上,可以完全访问上面的 Docker
容器。
- [1] docker-exec => 运行一次性命令
- 容器:
app
- 命令:
rake db:migrate
- 容器:
# 运行一次性命令
$ vagrant docker-exec app -- rake db:migrate
$ vagrant docker-exec -it -- /bin/sh
$ vagrant docker-exec default -it -- /bin/sh
# 区别镜像名称
Vagrant.configure do |config|
config.vm.define "web" do
config.vm.provider "docker" do |d|
d.image = "nginx"
end
end
config.vm.define "consul" do
config.vm.provider "docker" do |d|
d.image = "consul"
end
end
end
# 运行一次性命令
$ vagrant docker-exec -it web -- /bin/sh
$ vagrant docker-exec -it nginx -- /bin/sh
$ vagrant docker-exec -it consul -- /bin/sh
- [2] docker-logs
$ vagrant docker-logs app -- rake db:migrate
- [3] docker-run
$ vagrant docker-run app -- rake db:migrate
4. 相关参数配置
关于参数,可以参考 官方文档地址 进行查看!
- [1] 必选参数 - 三选一
image
- 启动的镜像或者镜像 ID 或名称build_dir
- 包含 Dockerfile 的目录的路径git_repo
- 用于构建镜像的 Git 存储库的 URL
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.build_dir = "."
d.image = "foo/bar"
d.git_repo = "https://github.com/xxx.git"
end
end
- [2] 可选参数
build_args
- 字符串数组 - 设置构建镜像参数cmd
- 字符串数组 - 自定义命令以在容器上运行compose
- 布尔值 - 使用 docker-compose 来管理容器的生命周期和配置compose_configuration
- 哈希值 - 用于填充 docker-compose.yml 文件的配置值dockerfile
- 字符串 - 构建目录中 Dockerfile 的名称env
- 哈希值 - 要公开到容器中的环境变量has_ssh
- 布尔值 - 将支持 ssh 容器ports
- 字符串数组 - 从容器公开给主机的端口volumes
- 字符串数组 - 要作为卷挂载到容器中的目录列表username
- 登录用户名 -docker login
password
- 登录密码 -docker login
5. 相关网络配置
关于参数,可以参考 官方文档地址 进行查看!
- Docker Network Options
docker.vm.network :private_network, type: "dhcp"
docker.vm.network :private_network, type: "dhcp", subnet: "172.20.128.0/24"
docker.vm.network :private_network, type: "dhcp", ip: "172.20.128.0", netmask: 24
docker.vm.network :private_network, ip: "172.20.128.2"
docker.vm.network :private_network, ip: "172.20.128.2", netmask: 16
- Public Networks
docker.vm.network :public_network, type: "dhcp"
docker.vm.network :public_network, type: "dhcp", bridge: "eth0"
docker.vm.network :public_network, type: "dhcp", bridge: ["eth0", "wlan0"]
docker.vm.network :public_network, type: "dhcp", bridge: "eth0", docker_network__ip_range: "192.168.1.252/30"
docker.vm.network :public_network, type: "dhcp", bridge: "eth0", docker_network__gateway: "192.168.1.2"
- [3] Docker Network Example
# 下面的Vagrantfile将为容器生成这些网络
Vagrant.configure("2") do |config|
config.vm.define "docker" do |docker|
docker.vm.network :private_network, type: "dhcp", docker_network__internal: true
docker.vm.network :private_network,
ip: "172.20.128.2", netmask: "16"
docker.vm.network :private_network, type: "dhcp", subnet: "2a02:6b8:b010:9020:1::/80"
docker.vm.provider "docker" do |d|
d.build_dir = "docker_build_dir"
end
end
end
# 可以将容器连接到在Vagrant外部创建的docker网络
$ docker network create my-custom-network --subnet=172.20.0.0/16
Vagrant.configure("2") do |config|
config.vm.define "docker" do |docker|
docker.vm.network :private_network, type: "dhcp", name: "my-custom-network"
docker.vm.provider "docker" do |d|
d.build_dir = "docker_build_dir"
end
end
end
6. 完整配置示例
下面是一份完整 Vagrant 的配置文件!
如果运行 vagrant up --provider=docker
报错的话,多是因为对应的虚拟机不知道该参数导致的报错,换一个支持 docker
的 box
即可。
Vagrant.configure(2) do |config|
config.vm.provider "docker" do |d|
d.name = "hello"
d.image = "hello-world"
d.has_ssh = true
end
config.vm.provision "shell", inline: "echo 'hello docker!'"
end
7. 参考链接地址
送人玫瑰,手有余香!