talesleaves-dev

諸々の開発のメモ。画像は面倒

Windows10+Vagrant+VirtualBoxでCentOS7の仮想マシンを構築する

Vagrantfileの生成

この記事では以下の環境を目指したいと思います。

ホストOS
Windows10
仮想マシン
VirtualBox
ゲストOS
CentOS7
ゲストOSに展開するツール
Docker
Docker Compose
前の記事までにVagrantVirtualBoxのインストールは完了していますので、さっそくVagrantfileを記述していきます。

この記事について
私が作業した際の手順の再現となっているため、エラーが発生する箇所があります。
上記の環境で作業する環境をいち早く作りたい方は最終形のVagrantfileを参照してください。

プロジェクトの初期化

起動テストの時と同じ手順で、任意のプロジェクトフォルダにVagrantfileを作成します。

#プロジェクトのフォルダ内で
> vagrant init centos/7

この状態で生成されたVagrantfileの、コメントアウトされずに有効になっている部分のみを抜き出すと、以下のようになります。

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

BoxとしてCentOS7の最新版を指定しているだけの状態です。
ここに、デフォルトの設定では気持ちの悪いの部分の修正・設定を追加していきます。

共有フォルダの設定

共有フォルダはデフォルトではホスト側のプロジェクトフォルダ全体と、ゲスト側の"/Vagrant"が指定されています。
この状態ではゲスト側には必要のないVagrantfile自体も共有されてしまいますので、この設定を無効にします。

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
end

プロジェクトフォルダ内に共有用のフォルダを作成して、そのフォルダを指定しなおします。
ここではプロジェクトフォルダ内に”vsync”フォルダを作成しました。共有が働いているかの確認のために、そのフォルダの中に"test.txt"ファイルを作成しておきます。

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder "./vsync","/vsync"
end

これで一度、マシンを起動させてみます。

一度目のミス

Boxの取得、ポート転送、SSHの設定と進み、マシンが起動されて…エラーが表示されています。
これはVirtualBox仮想マシンとWindows10の間での共有フォルダーの作成に失敗したためです。
マシンの状況を確認してみます。

> vagrant status
Current machine states:

default                   running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

エラーは出ましたが動作はしているようです。
ここは一度、マシンを停止させ、廃棄してから再度挑戦してみます。

#マシンのあるプロジェクトフォルダ内で
#仮想マシンの停止
vagrant halt
#仮想マシンの破棄(強制)
vagrant destroy -f

回避策

調べてみると、VirtualBoxのゲストOSにVirtualBox Guest Additionsというツールをインストールしないと、共有フォルダが使用できないということでした。
これを回避する方法として一番手軽なのは、vagrant-vbguestプラグインVagrantへインストールすることです。
この手順を、Vagrantfileへ記述します。

Vagrant.configure("2") do |config|
  #なんとなく手順的にVagrantへの設定を先に書く
  config.vagrant.plugins = ["vagrant-vbguest"]
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder "./vsync","/vsync"
end

このファイルでupすると、localにプラグインをインストールするかを尋ねられます。*1
yを入力すると、vagrant-vbguestをインストールしてから、いつもの流れに向かいます。
yumのアップデートの後、自動でGuestAdditionのイメージをダウンロードしてインストールしてくれます。これで、共有フォルダも機能するはずです。
upが完了してプロンプトが返ってきたら、vagrant ssh仮想マシンに接続します。

> vagrant ssh
[vagrant@localhost ~]$ cd /vsync
[vagrant@localhost vsync]$ ls
test.txt

共有フォルダの設定が成功したことが確認できました。

ゲストOSへの設定とインストール

マシンの起動はこれで問題ありませんので、さらに気になる点だけ修正します。

仮想マシンの名前

現状だと、仮想マシンVagrant上では"defaut”と認識されます。さらに、VirtualBoxGUI上では長い名前が自動生成されているはずですので、これを特定の名前に指定します。
これには2つの設定ブロックを使用します。
Vagrant上でマシン名を付けるには、”config.vm.define”を使ってマシンの設定を切り分けます。
defineには文字列を指定してブロックに名前を付けますが、この文字列がVagrantが認識するマシン名となります。
VirtualBox上のマシン名は、vm.providerへの設定として行います。
この設定を追加すると、以下のようになります。

Vagrant.configure("2") do |config|
  #なんとなく手順的にVagrantへの設定を先に書く
  config.vagrant.plugins = ["vagrant-vbguest"]
    
  #仮想マシンの設定
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder "./vsync","/vsync", create: true

  #仮想マシン名の変更
  config.vm.define "local-test" do |local|
    local.vm.provider "virtualbox" do |vb|
      vb.name = "local-test"
    end
  end
end


config.vm.define
config.vm.defineは、本来は一つのVagrantfile内で複数のマシンを管理するときに使用するものです。
configの無名のブロックに共通させる設定を、defineで切り分けたブロックにはそれぞれのマシンへの設定を記述します。
今回で言えば、local-testマシンのproviderにVirtualBoxを指定して、VirtualBoxへマシン名として同じ名前を与えたことになります。
名前付きのブロックを複数作ってあげると、複数の仮想マシンを立ち上げることが出来ます。
複数マシンの設定についてはMulti-Machine - Vagrant by HashiCorpに記述があります。

OSのアップデートと設定テスト

OSのイメージは最新の状態とは限りません。
セキュリティや機能の修正が入っている可能性が高いので、アップデートを行う必要があります。
ここまでの設定でもvagrant sshでログインして手動でアップデートができますが、destroyしてupを繰り返すたびに同じ環境に手動で戻すのは骨が折れます。
そうした初回起動直後のアップデートや設定を、config.vm.provisionで設定できます。
provisionは様々な外部ツールも利用できますが、ここではシェルからコマンドでアップデートとサーバのタイムゾーンの設定を行ってみます。
シェルを使用する場合の記述方法は下記にまとめられています。
Shell Scripts - Provisioning - Vagrant by HashiCorp

ここでは、マシンの設定とマシン内での作業を切り離したいので、Vagrantfileの外部にシェルスクリプトを配置して、それを実行させます。
シェルスクリプト自体はシンプルで、以下のようになります。

#!/bin/bash
yum update -y
timedatectl set-timezone Asia/Tokyo

yumでアップデートを行って、タイムゾーンをAsia/Tokyoに変更しているだけです。
これをひとまず"os-config.sh"としてVagrantfileと同じ階層に保存して、Vagrantfileから指定します。

Vagrant.configure("2") do |config|
  #なんとなく手順的にVagrantへの設定を先に書く
  config.vagrant.plugins = ["vagrant-vbguest"]
    
  #仮想マシンの設定
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder "./vsync","/vsync", create: true

  #仮想マシン名の変更+VirtualBox特有の設定
  config.vm.define "local-test" do |local|
    local.vm.provider "virtualbox" do |vb|
      vb.name = "local-test"
    end
  end
 
  #仮想マシン内のOSへの初期設定
  config.vm.provision "shell", path: "os-config.sh"

end

path:で外部ファイルを指定する場合は、Vagrantfileからの相対パスにするのが無難です。
最後に、Docker Composeを使用したいので、これも自動でインストールしてもらいましょう。
これには、vagrant-docker-composeプラグインが必要となります。
プラグインの指定にvagrant-docker-composeを追加して、GithubのUsageどおりのprovision設定を追加してみます。

Vagrant.configure("2") do |config|
  #なんとなく手順的にVagrantへの設定を先に書く
  config.vagrant.plugins = ["vagrant-vbguest","vagrant-docker-compose"]
    
  #仮想マシンの設定
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.synced_folder "./vsync","/vsync", create: true

  #仮想マシン名の変更+VirtualBox特有の設定
  config.vm.define "local-test" do |local|
    local.vm.provider "virtualbox" do |vb|
      vb.name = "local-test"
    end
  end
 
  #仮想マシン内のOSへの初期設定
  config.vm.provision "shell", path: "os-config.sh"
  
  #DockerComposeを使いたい
  config.vm.provision :docker
  config.vm.provision :docker_compose
end

上記のVagrantfileでvagrant upを行うと、これまでよりもはるかに長い時間がかかりますが、マシンが起動するはずです。
vagrant sshでログインして

$ docker-compose -v

でバージョン表示が返ってくれば、設定が成功していること確認できます。
これでWindows10上に仮想マシンのCentOS7を立ち上げてDocker Comoseが利用できる環境が作成できました。*2

*1:pluginはVagrant全体に対するglobalなインストールとプロジェクトごとのlocalなインストールがあります

*2:ネットワークの設定などがまだ棚上げ