読者です 読者をやめる 読者になる 読者になる

Tech Beans

Web企業で働くエンジニアのBlog


Docker on vagrant on Windows10

Docker on vagrant

Dockerをvagrant上に構築してみる。 ネット上の情報を参考にしてみてもうまくいかなかったので、だいぶ試行錯誤した

目指す構成は以下のとおり

Docker Container (CentOS6)
on
Vagrant (CentOS6)
on
Windows 10

※今回はHadoopクラスタ構築を目標にしているので、Hadoopという文字列がちらほら出てきますが、そこは任意です

Why docker on vagrant

ネット上の記事を見ると、vagrantで仮想環境を立てて、その上にさらにDockerによるコンテナを構築する例が多いけど、 docker(仮想) on vagrant (仮想)と、2重に仮想環境を構築する意味が最初わからなかった。

自分で調べてみたところでは、

  • DockerはLXCを利用しており、Linux上でしか動作しない
  • そのため、OSXWindows上では、VagrantでまずLinux環境を構築してから、Dockerを入れる。
    • その際のLinux環境は最小限のもので構わないので、boot2dockerなどの軽量Linuxを用いる
  • 逆にホストOSが最初からLinuxであれば、Dockerコンテナを直に立てればいい。

利点として、どのOSで作業をしようが、どこでもDockerコンテナを立てることができるので、 別OSに環境を移植する際もDockerコンテナを持っていけばよいということかな。

Vagrantごと持って行くと、Linux上ではLinux - Vagrant - Dockerとなり、 コンテナ型仮想化であるDockerを直接利用するよりオーバーヘッドが大きい)

Docker provision vs Docker provider

VagrantでDockerを扱うには、provisionとproviderが2つあって、どちらを使えばいいのかよくわからなかったので整理。

VagrantでDockerを立てる方法は主に2つある。

Provision:

  • Vagrantが立てるVM上に、Dockerを構築する。
    あくまでVMを立ててからDockerをインストールする形になるので、ホストOSがLinuxである場合にもLinux - VM - Dockerという構成になる。
    Vagrant v1.6まではこの構成?

Provider:

  • Vagrant ver1.6から追加された機能。
    VagrantVMを構築する際に、VirtualBox等によるVMでなく、Dockerによるコンテナを指定できるというもの。
    MacWindowsなど、直接Dockerが構築できないホストOS上では、Vagrantが自動で中間のLinux VMを立ててくれる。
    一方で、ホストOSがLinuxの場合は直接Dockerコンテナを立てるため、無駄がないのかな(未確認)。

どのOSでも使え、設定が簡単そうなProviderがよさそう。

Docker on Vagrant on Window10

Windows10にVagrant を立てて、その上にDockerコンテナを構築する

準備

以下をインスト-ル(詳細は割愛)

Vagrantfile

mkdir {任意のディレクトリ}/hadoop # 以下、D:/virtualbox_vms/hadoopとする
cd D:/virtualbox_vms/hadoop
mkdir host

hadoop/Vagrantfile にDockerコンテナ自体の構築手順を、   hadoop/host/Vagrantfile にDockerをインストールするVMのVagrantfileを置く。

ここらへんは、ドキュメントも豊富なのでそちらを参考に。。(そのうち追記するかも)

Vagrantfile

VAGRANTFILE_API_VERSION = "2"
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "hadoop-container" do |h|
    h.vm.provider "docker" do |docker|
      docker.vagrant_vagrantfile = "./host/Vagrantfile"
      docker.name = 'hadoop-container'
      docker.build_dir = '.'
    end
  end
end

Dockerfile

FROM centos:centos6

RUN yum update -y

### 以下、Dockerコンテナの構築コマンド(省略

host/Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.hostname = "docker-host"

  config.vm.box = "bento/centos-6.7"

  config.vm.box_check_update = false

  # provisoned by docker
  config.vm.provision "docker"
end

以上のファイルを準備したら、hadoopディレクトリ以下で、

vagrant up

と実行すれば、host/以下のVMも含めてdocker コンテナの立ち上げまでやってくれる。 はずだった。。

Permisson denied

DockerでのProvider実行時にPermisson Deniedになった。

D:\virtualbox_vms\hadoop>vagrant up
Bringing machine 'hadoop-container' up with 'docker' provider...
==> hadoop-container: Docker host is required. One will be created if necessary...
    hadoop-container: Docker host VM is already ready.
==> hadoop-container: Building the container from a Dockerfile...
    hadoop-container: stat /var/lib/docker/docker_build_7afac34b3a4f4be525c3d67a8eef89c3:
permission denied
A Docker command executed by Vagrant didn't complete successfully!
The command run along with the output from the command is shown
below.

Command: "docker" "build" "/var/lib/docker/docker_build_7afac34b3a4f4be525c3d67a8eef89c3"

Stderr: stat /var/lib/docker/docker_build_7afac34b3a4f4be525c3d67a8eef89c3: permission den
ied

Stdout:

同様の事例がissueに報告されている。 https://github.com/mitchellh/vagrant/issues/6822

これは、/var/lib/dockerがvagrant構築時にはroot権限になっているが、dockerコマンドを実行するのはvagrantユーザーであるから。

以下の行をhost/Vagrantfileに追記し、/var/lib/dockerディレクトリをvagrantユーザーのものにしておく。

# provisoned by docker
config.vm.provision "docker"
## 追記
config.vm.provision "shell", inline: <<-SHELL
  sudo chown vagrant:vagrant /var/lib/docker
SHELL

privisonは複数指定できるみたい。

これでとりあえずDockerコンテナが立ち上がるところまで確認できた。