Vagrant创建Docker开发环境


Vagrant 是一个通用的工具,可以塑造成你认为合适的环境。

Vagrant1.6+ 这个版本之后,提供了一个新的内置 provider:Docker,这使得允许在 Vagrant 工具上面管理在容器中运行的开发环境,而不是在虚拟机中。同时,在其他操作系统上面不需要附加任何额外的工具和扩展。

Vagrant打造Docker开发环境


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 上运行多个容器)。这允许我们基于 dockerVagrant 环境保持可移植性,而不会因其所运行的平台而产生不一致。

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 报错的话,多是因为对应的虚拟机不知道该参数导致的报错,换一个支持 dockerbox 即可。

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. 参考链接地址

送人玫瑰,手有余香!


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录