Vagrant の使い方まとめ

Vagrant は仮想マシンを実験できる素晴らしいツールです。
毎度毎度やりたいことを自分で掘り起こすのにつらみを感じてきたのでまとめました。
随時まとめていきます。
最近は Otto も出てきたのでそっちに移行したいですが。

ポートフォワーディングの設定

こんな感じでやると http://localhost:8888/ で 8080 でリッスンする仮想マシンにアクセスできます。

  config.vm.network "forwarded_port", guest: 8080, host: 8888

ブリッジしたい

DHCP

  config.vm.network "public_network"

IP 指定したい

サブネットごえするばあいは VM の中にデフォルトゲートウェイを指定してあげる必要があります。

  config.vm.network "public_network", ip: "192.168.0.17"

NIC を指定する

この場合上だけだと vagrant up するたびにブリッジする NIC を聞かれてうざいので、NIC を指定します。

  config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"

Vagrant box を指定する

僕はよく puppetlabs で提供されている
前までは chef で提供されているものを使ってたんですが、なくなりました。
ATLAS で探してみましょう。

puppetlabs | Atlas by HashiCorp

  config.vm.box = "puppetlabs/centos-7.2-64-nocm"

ATLAS ができる前は野良 Vagrant box を以下から拾ってきたり、セキュリティが気になる場合は Packer で自分で作る必要がありました。

A list of base boxes for Vagrant – Vagrantbox.es

スペックを指定したい(VirtualBox)

デフォルトだと 1 CPU の 2 GB の割当なので、コンピューティングリソースをもう少し増強したい場合は以下の様な指定をする。

  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2", "--ioapic", "on"]
  end

複数の VM を立ち上げる

何も 1 台構成だけが脳じゃありません。
こんな 3 台構成もできる。

  config.vm.define "web" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "ap" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.11"
  end

  config.vm.define "db" do |instance|
    instance.vm.box = "puppetlabs/centos-7.2-64-nocm"
    instance.vm.network :private_network, ip: "192.168.33.12"
  end

Windows ユーザーが喜ぶ vagrant ssh の代わりに Tera Term を手軽に使える vagrant-teraterm プラグイン

私も 1 行だけコミットした vagrant-teraterm プラグインというのがあります。
vagrant ssh でもできるが、コマンドプロンプト内で Linux に入るという行為自体がキモい。
これ知る前は毎回 SSH のフォワーディングポート調べて Tera Term 手動で立ち上げて SSH してたんですが、
これで毎回フィンガープリントを確認される不自由から開放されます。
でも、正直 Mac のほうが使いやすいですよ。

vagrant plugin install vagrant-teraterm
vagrant up
vagrant teraterm

シェルプロビジョニングをする

Ansible や Chef を使うほどではないが、毎回立ち上げるたびにコマンドコチコチ入力するのも面倒だというときに一番強力なのがシェルプロビジョニングです。

  config.vm.provision "shell", inline: <<-SHELL
    sudo yum -y install epel-release
    sudo yum -y install --eneblerepo=epel nginx
  SHELL

ある程度出来上がった Vagrant の実行イメージを出力する

これはけっこう強力で、例えばLAN内のローカルミラーを参照するように設定したり、
例えば毎回 vagrant up するたびに Nginx や MySQL をインストールするのは正直だるいって時には vagrant package サブコマンドを使う。
Packer でがんばってやらなくてもいいのでお手軽でおススメ。

ある程度まとまった開発環境ができあがったらそれを他の開発者に配布するという使い方もできる。

vagrant package
rename package.box centos-7.2-x86_64-mysql-5.6.box
vagrant box add centos-7.2-x86_64-mysql-5.6 centos-7.2-x86_64-mysql-5.6.box

add し終わったら Vagrantfile の box 名指定するところにそれを指定して vagrant up すれば特定の役割を持った仮想マシンがいろんなミドルウェアを入れるオーバーヘッドがなくなるので楽ちんなのだ。

プライベートな Vagrant box Registry がほしいなあ。。。

参考リンク

  1. Documentation - Vagrant by HashiCorp
  2. 「hbstudy#60 SerfとConsulでシステム運用を楽しくしよう!」に行ってきました&Serf試してみました - 戦場のプログラマー
  3. RedHat 系 Linux のホスト名を設定する - 戦場のプログラマー
  4. vagrant teraterm が便利すぎてしょうがない件 - 戦場のプログラマー
  5. vagrant-digitalocean provider の簡単な使い方 - 戦場のプログラマー
  6. vagrant-digitalocean で vagrant up すると NoMethodError となる件 - 戦場のプログラマー
  7. Macでvagrant-omnibusプラグインのインストール中にnokogiriのインストールでコケるというお話 - 戦場のプログラマー

otto dev コマンドを使ってみた

新年一発目。
HashiCorp の集大成とも言えるべき Otto をインストールしてみた。

Otto とは

若干ググラビリティが低いのが難点。
これはすごく乱暴に言ってしまえば Vagrant の後継となるソフトウェアである。
Vagrant やら Consul やら Vault やら AWS やら GCP といったいろいろなものをシームレスに連携して統一世界を作るためのものらしい。
Mitchell Hashimoto 氏がここまで予見して Consul や Vault といったプロダクトをリリースしていたとしたら脱帽せざるを得ない。

otto 全般について触ってみた結果を載せられたらいいんだけど、何分時間も頭も足りないので全部は解説できない。
なので otto dev サブコマンドで起動、停止するだけの簡単なものを記録として残す。

さて、 otto dev サブコマンドは結論からいうと今のところ Vagrant なしには動かない。
バックエンドで Vagrant を使っている。
今後は Vagrant 自身も必要なくなって otto だけで動くようになってくれるのかな。
そうすると Vagrant の遅さを考えなくて良くなるのだろうか。

プロジェクトの作成

otto のプロジェクトを立ち上げるためには既存のソースだけ使うか、それとも Appfile という JSON 形式のファイルでどのような言語を使うかを指定してやることになる。
私はものぐさなので前者。
おそらく Vagrantfile に記述していたような複数VMを構成したり、秘伝のタレめいたシェルプロビジョニングを使いたい場合は Appfile に記述したのだろう。

ソースの用意

私は次のようなソースを用意した。

<?php
phpinfo();

otto compile

そしてそのディレクトリで otto compile する。
Appfile が見つからなければソースの内容をみてどの言語のプロジェクトか判断してくれるようだ。
この場合、リリースするインフラストラクチャは AWS が選択された。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto compile
==> Loading Appfile...
==> No Appfile found! Detecting project information...
No Appfile was found. If there is no Appfile, Otto will do its best
to detect the type of application this is and set reasonable defaults.
This is a good way to get started with Otto, but over time we recommend
writing a real Appfile since this will allow more complex customizations,
the ability to reference dependencies, versioning, and more.
==> Fetching all Appfile dependencies...
==> Compiling...
Application:    otto-php (php)
Project:        otto-php
Infrastructure: aws (simple)
Compiling infra...
Compiling foundation: consul
==> Compiling main application...
==> Compilation success!
This means that Otto is now ready to start a development environment,
deploy this application, build the supporting infrastructure, and
more. See the help for more information.
Supporting files to enable Otto to manage your application from
development to deployment have been placed in the output directory.
These files can be manually inspected to determine what Otto will do.

ローカル開発環境の立ち上げ

otto dev

満を持して vagrant up に相当するコマンドを叩く。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev
Would you like Otto to install Vagrant?
Otto requires vagrant to be installed, but it couldn't be found on your
system. Otto can install the latest version of vagrant for you. vagrant
will be installed system-wide since it uses system-specific installers.
Would you like Otto to install vagrant for you? Alternatively, you may install
this on your own.
If you answer yes, Otto will install vagrant version 1.8.1.
Please enter 'yes' to continue. Any other value will exit.
Enter a value:
Error building dev environment: Installation cancelled

otto dev は vagrant がインストールされていないと動かないらしい、もしくは otto 全体でそうなんだろうか。
あなたがお望みなら自動でシステムワイドでインストールしてやるぜ?といっているが、ここは yes 以外の適当なキーを押して抜けて自力で Vagrant をインストールする。

また vagrant を Web サイトからいちいちダウンロードするのは果てしなくだるいので、 otto にまかせてしまってもいいのかもしれない。
Mac の場合は Homebrew Cask がインストールされていればコマンド一発でインストールできる。
まあ、 sudo 権限が必要なのでパスワードは要求されるが・・・。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ brew cask install vagrant
==> Downloading https://releases.hashicorp.com/vagrant/1.8.1/vagrant_1.8.1.dmg
######################################################################## 100.0%
==> Verifying checksum for Cask vagrant
==> Running installer for vagrant; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are i
Password:
==> installer: Package name is Vagrant
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  vagrant staged at '/opt/homebrew-cask/Caskroom/vagrant/1.8.1' (6 files, 85M)

仕切り直して改めて otto dev

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev
==> Creating local development environment with Vagrant if it doesn't exist...
Raw Vagrant output will begin streaming in below. Otto does
not create this output. It is mirrored directly from Vagrant
while the development environment is being created.
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://atlas.hashicorp.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'hashicorp/precise64' is up to date...
==> default: Setting the name of the VM: dev_default_1451618455051_6865
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 4.2.0
default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
default: /vagrant => /Users/wnoguchi/Documents/pjt/otto/otto-php
default: /otto/foundation-1 => /Users/wnoguchi/Documents/pjt/otto/otto-php/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Installing Consul...
==> default: [otto] Installing dnsmasq for Consul...
==> default: [otto] Configuring consul service: otto-php
==> default: Running provisioner: shell...
default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Adding apt repositories and updating...
==> default: [otto] Installing PHP and supporting packages...
==> default: [otto] Installing Composer...
==> default: #!/usr/bin/env php
==> default: All settings correct for using Composer
==> default: Downloading...
==> default:
==> default: Composer successfully installed to: /tmp/composer.phar
==> default:
==> default: Use it: php composer.phar
==> Caching SSH credentials from Vagrant...
==> Development environment successfully created!
IP address: 100.79.109.82
A development environment has been created for writing a PHP app.
Edit files locally on your machine, the file changes will be synced
to the development environment automatically.
To run and view your application, run 'otto dev ssh' to enter the
development environment. You'll be placed directly into the working
directory where you can run "composer", "php", etc.
You can access the environment from this machine using the IP address above.
For example, if you start your app with 'php -S 0.0.0.0:5000', then you can
access it using the above IP at port 5000.

このログメッセージを見ればわかるが、 Consul もインストールされ、PHP ではもはや必須となった Composer までよろしくインストールしてくれている。
composer.json まで入れたらいい感じにインストールしてくれるんだろうか。
仮想マシンUbuntu の precise64 が選択されている。
ここも詳細に指定したいな。

開発環境として 100.79.109.82 という IP が与えられたので、さっそくホスト OS からブラウザでアクセスしてみる。
「データを受信していません」となった。どうも環境の AP サーバは自力で開発環境に入り、立ち上げてやる必要があるらしい。

いつものくせで vagrant ssh としてしまったら

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ vagrant ssh
A Vagrant environment or target machine is required to run this
command. Run `vagrant init` to create a new Vagrant environment. Or,
get an ID of a target machine from `vagrant global-status` to run
this command on. A final option is to change to a directory with a
Vagrantfile and to try again.

vagrant init せえよアホンダラア!!って怒られてしまった。
およそ otto dev ssh とでもするんだろう。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev ssh
==> Executing SSH. This may take a few seconds...
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
* Documentation:  https://help.ubuntu.com/
New release '14.04.3 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:23:18 2012 from 10.0.2.2
vagrant@precise64:/vagrant$ cd /vagrant/
vagrant@precise64:/vagrant$ ls
phpinfo.php

入れた。

vagrant@precise64:/vagrant$ php -S 0.0.0.0:5000
PHP 5.6.16-2+deb.sury.org~precise+1 Development Server started at Fri Jan  1 03:27:21 2016
Listening on http://0.0.0.0:5000
Document root is /vagrant
Press Ctrl-C to quit.
[Fri Jan  1 03:27:40 2016] 100.79.109.1:51305 [200]: /phpinfo.php
[Fri Jan  1 03:27:41 2016] 100.79.109.1:51306 [404]: /favicon.ico - No such file or directory

そしてブラウザから 5000 番ポートを叩く。

f:id:wnoguchi0727:20160101132031p:plain

見れた。

さらにアクセス元のリモートIPアドレスを取得するサンプルも書いてみた。
開発環境にはすぐに同期される。

<?php
echo $_SERVER['REMOTE_ADDR'];

そしてブラウザで見る。

f:id:wnoguchi0727:20160101133202p:plain

見れた。

じゃあシャットダウン。これもサブコマンドで otto dev halt だろうと予想がつく。

noguchiwataru-no-MacBook-Air:otto-php wnoguchi$ otto dev halt
==> Halting the the local development environment...
==> default: Attempting graceful shutdown of VM...
==> Development environment halted!

シャットダウンできた。

知らない IP アドレスだ…

ipduh によるとこの IP アドレスは

http://ipduh.com/ip/?100.79.109.82

100.79.109.82 is in the 100.64.0.0/10 block which is reserved to be used as Shared Address Space to accomodate the need of Carrier-Grade NAT (CGN) devices. It is anticipated that Service Providers will use this Shared Address Space to number the interfaces that connect CGN devices to Customer Premises Equipment (CPE). [ RFC 6598 ]

Integer: 1682926930

のように Carrier-Grade NAT デバイスが Customer Premises Equipment(CPE) に接続するための共有アドレス空間として 100.64.0.0/10 は予約されているらしい。
グローバル IP アドレス空間をむやみに汚染しているわけではないらしい。

これを見る限り CGN はグローバル IPv4 アドレス枯渇問題をとりあえず回避するために ISP が共有NATアドレス空間を定義したことがことの始まりであり、この RFC 定義空間をよろしく使っているのが otto dev になるようだ。

References

  1. Hashicorp Ottoを読む | SOTA
  2. HashiCorpの新プロダクトNomadとOttoを触ってみた | Developers.IO
  3. Hashicorp社の新しい仮想開発環境”Otto”でAppfileを記述してみた – FPGA開発日記

vagrant teraterm が便利すぎてしょうがない件

Windows 使っていると vagrant up したあとに仮想マシンにアクセスするのにコマンドプロンプトのログに流れた SSH のフォワーディングポートを読んで、 vagrant が自動生成した秘密鍵を指定して Tera Term で接続して・・・っていう流れをやっていたんだけど、さすがに馬鹿らしくなってしまった。
Mac じゃないからコマンドプロンプトvagrant ssh するのも微妙だし・・・。

Vagrant 仮想マシンに接続する TeraTerm マクロを吐き出すプラグイン(Gem) を書いたわけです。
vagrant ssh-configTeraTermvagrant-ssh-config-ttl 初の Gem 製作。

しかしながらそれでも複数VM取り扱ったりするとやっぱり大変。
と思っていたら vagrant-teraterm という素晴らしいプラグインが開発されていました。

  1. tiibun/vagrant-teraterm
  2. Windows – VagrantにTeratermマクロで接続する – Qiita
  3. Vagrant Teraterm pluginを作ってみた – Qiita

インストール

いたって簡単、

vagrant plugin install vagrant-teraterm

設定

デフォルトのインストールパスに Tera Term がインストールされていればとくに設定はいりません。
vagrantteraterm プラグインがよしなにやってくれます。

使い方

vagrant up したら以下のようにすると自動的に TeraTerm が対象の VM に繋いでくれます。

vagrant teraterm

複数VM を立ち上げている場合

以下のように VM 名を指定してあげればいいです。

vagrant teraterm vm1

ちなみに、最初は vagrant teraterm する際にフィンガープリントの検証で引っかかっていたので、 StrictHostKeyChecking no に相当する /nosecuritywarning を孵化するPR 投げて取り込んでもらいました。嬉しい。

蛇足

最近 HashiCorp から Otto という Vagrant の後継となるソフトウェアがリリースされました。
以前は Chef をよく使っていたのですが、 Vagrantfile のシェルプロビジョニングがお手軽すぎてダメ人間になってしまっています。
そしてこれも秘伝のタレ化すると。
その秘伝のタレ化する Vagrantfile をなんとかしてくれるのが Otto らしいです。
これも早めにいじってみたいなあ。

  1. Otto by HashiCorp
  2. Otto – HashiCorp
  3. Hashicorp Ottoを読む | SOTA

vagrant-digitalocean provider の簡単な使い方

次のような Vagrantfile を用意します。

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure('2') do |config|
config.vm.provider :digital_ocean do |provider, override|
override.ssh.private_key_path = '~/.ssh/digitalocean-vagrant'
override.vm.box = 'digital_ocean'
override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
provider.token = ''
provider.image = 'CentOS 6.5 x64'
# San Francisco 1
provider.region = 'sfo1'
provider.size = '512mb'
end
end

前提条件としては

  • Apps & API メニューで Personal Access Tokens を生成すること。Read, Write アクセス付与。
  • Vagrant という名前の秘密鍵が登録されていること。
  • ~/.ssh/digitalocean-vagrant と対になる公開鍵 ~/.ssh/digitalocean-vagrant.pub が存在すること。
  • 選択されているリージョンは San Francisco 1 (slug名になっている)。

ちなみに現在のリージョンとslug名の対応は以下のようになっている。

slug Region Name
nyc1 New York 1
ams1 Amsterdam 1
sfo1 San Francisco 1
nyc2 New York 2
ams2 Amsterdam 2
sgp1 Singapore 1
lon1 London 1
nyc3 New York 3

調べ方はさっきのパーソナルトークンを指定して以下の様な curl コマンドを発行すればいいです。
jq でフィルタリングしてます。

curl -X GET "https://api.digitalocean.com/v2/regions" \
-H "Authorization: Bearer $DIGITAL_OCEAN_TOKEN" \
2>/dev/null | jq '.regions [] | .slug,.name'

EC2 と違って Droplet が存在しているだけで課金対象になるので用が済んだらすぐに

vagrant destroy -f

References

  1. VagrantとSSDなVPS(Digital Ocean)で1時間1円の使い捨て高速サーバ環境を構築する – Glide Note – グライドノート
  2. jq コマンドが強力すぎてヤバい件 | CUBE SUGAR STORAGE
  3. DigitalOcean API

vagrant-digitalocean で vagrant up すると NoMethodError となる件

以下の様なエラーとなります。

% vagrant up --provider=digital_ocean
Bringing machine 'default' up with 'digital_ocean' provider...
==> default: Using existing SSH key: Vagrant
==> default: Creating a new droplet...
/Users/wnoguchi/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/create.rb:37:in `call': undefined method `first' for nil:NilClass (NoMethodError)
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Users/wnoguchi/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/setup_key.rb:33:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builder.rb:116:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `block in run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/util/busy.rb:19:in `busy'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builtin/call.rb:53:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builtin/config_validate.rb:25:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/warden.rb:34:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/builder.rb:116:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `block in run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/util/busy.rb:19:in `busy'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/action/runner.rb:66:in `run'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:196:in `action_raw'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:173:in `block in action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/environment.rb:434:in `lock'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:161:in `call'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/machine.rb:161:in `action'
from /Applications/Vagrant/embedded/gems/gems/vagrant-1.6.3/lib/vagrant/batch_action.rb:82:in `block (2 levels) in run'

DigitalOcean API V2 は Public Beta なので仕様が変わったためのようです。

Public Beta
Due to the large number of changes to API v2 we have decided to release it as a beta to collect user feedback. Please note that >during this period based on user feedback we may make some large changes which may break compatibility.

DigitalOcean API

このあたりは以下の Issue とプルリクで修正方法が確立されているので早く本家にマージされてほしいです。

とりあえずなんとかしたい方は対処療法的には

~/.vagrant.d/gems/gems/vagrant-digitalocean-0.6.2/lib/vagrant-digitalocean/actions/create.rb

の 37 行目を

          @client.wait_for_event(env, result['droplet']['action_ids'].first)
# ↓
@client.wait_for_event(env, result['links']['actions'].first['id'])

とすればいいです。

Vagrant AWS Provider を使ってみた

まずはダミーの box イメージをインポートする。

vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

そして次のような Vagrantfile を書く。
前提条件は以下。

  • IAMで予めEC2にアクセスを制限したユーザのクレデンシャルを払いだしておくこと
  • 使用するキーペアの名前は vagrant
  • 起動するインスタンスタイプは t2.micro (デフォルトだと m3.medium で起動してしまう)
  • Vagrant 用のセキュリティグループを定義してそれを使用
  • 東京リージョンを指定(ap-northeast-1)
  • 起動する AMI は Amazon Linux AMI 2014.03.2 (HVM) (ami-29dc9228)
  • SSH ユーザ名は ec2-user
  • 対応する秘密鍵の場所を指定する。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "dummy"
config.vm.provider :aws do |aws, override|
aws.access_key_id = ""
aws.secret_access_key = ""
aws.keypair_name = "vagrant"
aws.instance_type = "t2.micro"
aws.security_groups = [ "vagrant" ]
aws.region = "ap-northeast-1"
# Amazon Linux AMI 2014.03.2 (HVM)
aws.ami = "ami-29dc9228"
override.ssh.username = "ec2-user"
override.ssh.private_key_path = "~/.ssh/aws-ec2-vagrant.pem"
end
end

そして

vagrant up --provider=aws

以下の様なエラーが出るが、ここでは気にしない。

==> default: Rsyncing folder: /Users/wnoguchi/Documents/tmp/vagrant-ec2/ => /vagrant
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
mkdir -p '/vagrant'
Stdout from the command:
Stderr from the command:
sudo: sorry, you must have a tty to run sudo

IPアドレス知らなくてもSSHできる。

vagrant ssh

グローバルIPが知りたければインスタンスメタデータcurl で取得する。

[ec2-user@ip-172-31-25-90 ~]$ curl -w "\n" http://169.254.169.254/latest/meta-data/public-hostname
ec2-54-64-60-151.ap-northeast-1.compute.amazonaws.com
[ec2-user@ip-172-31-25-90 ~]$ curl -w "\n" http://169.254.169.254/latest/meta-data/public-ipv4
54.64.60.151

あとは nginx 入れるなりなんなりして実験して、用が済んだら

vagrant halt

か潔く

vagrant destroy -f

References

  1. mitchellh/vagrant-aws
  2. インスタンスメタデータとユーザーデータ – Amazon Elastic Compute Cloud

Macでvagrant-omnibusプラグインのインストール中にnokogiriのインストールでコケるというお話

Mac OS X Mavericks(10.9.4)です。他のMacでは vagrant-omnibus プラグインをインストールできるのですが、
メインで使ってるマシンでだけインストールできないという現象に遭遇。

どうやら nokogiri のインストールで失敗している模様。

% vagrant plugin install vagrant-omnibus
Installing the 'vagrant-omnibus' plugin. This can take a few minutes...
Building nokogiri using packaged libraries.
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:
An error occurred while installing nokogiri (1.6.3.1), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.6.3.1'` succeeds before bundling.

ためしに nokogiri 単体で入るか Gemfile に書いてインストールしてみたらこんなエラーが・・・

Building nokogiri using packaged libraries.
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
/Users/wnoguchi/.rbenv/versions/2.0.0-p481/bin/ruby extconf.rb
Building nokogiri using packaged libraries.

CentOS6.5にDockerインストールしてみた

Dockerすごく流行ってるらしいから今更ながら手を付けてみた。
Vagrantでバシッときれいな環境用意できるのがほんと手軽でいいね。

今回もこれで簡単に仮想マシン用意できました。

vagrant init chef/centos-6.5
vagrant up

インストール

  • CentOS6.5 x86_64

EPEL有効にする

EPEL – FedoraProject

sudo rpm -ivh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/i386/epel-release-6-8.noarch.rpm

Dockerインストール

  • Docker(1.0.0-6.el6)

  • インストール

sudo yum install docker-io
  • Dockerのサービススタート。
sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:                                       [  OK  ]
sudo chkconfig docker on
  • Dockerがちゃんと動いていることを確認するために最新版のCentOSイメージを取得する。
[vagrant@localhost ~]$ sudo docker pull centos:latest
Pulling repository centos
1a7dc42f78ba: Download complete
511136ea3c5a: Download complete
34e94e67e63a: Download complete
  • 取得が完了したらCentOSのイメージの一覧が以下のコマンドでリストに表示されることを確認する。
[vagrant@localhost ~]$ sudo docker images centos
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              1a7dc42f78ba        7 days ago          236.4 MB
  • イメージのテストをするためにbashを立ち上げてみよう。
sudo docker run -i -t centos /bin/bash

ちなみに -i はアタッチされていなくても標準入力を開いたままにしておくオプション。
-t は擬似端末(pseudo-tty)を割り当てることを意味する。
あいかわらずもやもやしている。

  -i, --interactive=false    Keep stdin open even if not attached
-t, --tty=false            Allocate a pseudo-tty

で、結果が以下。

[vagrant@localhost ~]$ sudo docker run -i -t centos /bin/bash
bash-4.2#

うん、プロンプト表示された。

実験

このままじゃ面白く無いからMySQL(クライアント)入れてみる。

bash-4.2# yum -y install mysql

当然ながらホストには全く影響がない。

[vagrant@localhost ~]$ mysql
-bash: mysql: コマンドが見つかりません
[vagrant@localhost ~]$ sudo -i
[root@localhost ~]# mysql
-bash: mysql: コマンドが見つかりません

本当はMySQLサーバ入れてみたかったんだけど、コンテナの中で

yum -y install mysql-server

すると「そんなのねぇ!」って怒られる。

mysql-server がどのリポジトリに入っているのか調べると updates リポジトリに入っていることが分かる。

[root@localhost ~]# yum info mysql-server
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.mirror.secureax.com
* epel: ftp.jaist.ac.jp
* extras: centos.mirror.secureax.com
* updates: centosv4.centos.org
Available Packages
Name        : mysql-server
Arch        : x86_64
Version     : 5.1.73
Release     : 3.el6_5
Size        : 8.6 M
Repo        : updates
Summary     : The MySQL server and related files
URL         : http://www.mysql.com
License     : GPLv2 with exceptions
Description : MySQL is a multi-user, multi-threaded SQL database server. MySQL is a
: client/server implementation consisting of a server daemon (mysqld)
: and many different client programs and libraries. This package contains
: the MySQL server and some accompanying files and directories.

ホスト側をupdatesでgrepするとヒットする。

[root@localhost ~]# cat /etc/yum.repos.d/CentOS-Base.repo | grep updates
# geographically close to the client.  You should use this for CentOS updates
#released updates
[updates]
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/

コンテナ内でgrepしてもヒットする。

bash-4.2# cat /etc/yum.repos.d/CentOS-Base.repo | grep updates
# geographically close to the client.  You should use this for CentOS updates
#released updates
[updates]
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/

うーん。なんで?

決定的違いを発見。

  • ホスト
[root@localhost ~]# cat /etc/redhat-release
CentOS release 6.5 (Final)
  • コンテナ
bash-4.2# cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)

なんじゃこりゃ。

コンテナではmariadbとか出てたし、CentOS7になってなんか変わったのだろうか。
追って色々調べよう。

とりあえず開発パッケージとか入れたりしてホストとコンテナの間で影響が無いことを確認して終了。

  • docker ps コマンドを発行してみる。

-a オプションは終了したコンテナ環境も一覧表示してくれる。

[vagrant@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           33 minutes ago      Exited (0) 3 minutes ago                       clever_nobel

さっきのあるね。アタッチしてみよう。

[vagrant@localhost ~]$ sudo docker attach 59d7660a51a8
2014/07/16 14:30:54 You cannot attach to a stopped container, start it first

停止したコンテナはアタッチできないって言われた。では開始しよう。

[vagrant@localhost ~]$ sudo docker start 59d7660a51a8
59d7660a51a8

docker ps してみる。

[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           42 minutes ago      Up 25 seconds                           clever_nobel

おお動いてる。アタッチする。

[vagrant@localhost ~]$ sudo docker attach 59d7660a51a8
bash-4.2# which gcc
/usr/bin/gcc
bash-4.2#

ちゃんと環境復元できてる!そして exit したら

[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

でもコンテナは削除してないから

[vagrant@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
59d7660a51a8        centos:latest       /bin/bash           43 minutes ago      Exited (0) 4 seconds ago                       clever_nobel

残ってる。
やばいおもしろい。

References

  1. CentOS 6.5 で Docker を使ってみる | CUBE SUGAR STORAGE
  2. CentOS – Docker Documentation

Vagrantを1.3.5から1.6.3に上げたよ(Vagrant Cloudを使うようになった)

やっと余裕が出てきたので、最近戯れてなかったVagrantをバージョンアップしてみようという気になった。

インストール前

[noguchiwataru@Macintosh] ~
% vagrant --version
Vagrant 1.3.5

インストール後

[noguchiwataru@Macintosh] ~
% vagrant --version
Vagrant 1.6.3

いつの間にかメジャーバージョンが3も上がってた。

vagrant init してみる

% vagrant init
Vagrant experienced a version conflict with some installed plugins!
This usually happens if you recently upgraded Vagrant. As part of the
upgrade process, some existing plugins are no longer compatible with
this version of Vagrant. The recommended way to fix this is to remove
your existing plugins and reinstall them one-by-one. To remove all
plugins:
rm -r ~/.vagrant.d/plugins.json ~/.vagrant.d/gems
The error message is shown below:
Bundler could not find compatible versions for gem "celluloid":
In Gemfile:
vagrant (= 1.6.3) ruby depends on
listen (~> 2.7.1) ruby depends on
celluloid (>= 0.15.2) ruby
vagrant-berkshelf (>= 0) ruby depends on
berkshelf (~> 2.0.7) ruby depends on
ridley (~> 1.5.0) ruby depends on
celluloid (0.14.1)

バージョンが衝突したからとりあえずプラグイン全部消して1つずつ入れなおしてくれって書いてある。
しばらくつかってなかったからもうプラグインも全部いらないかなって思って漢らしく

[noguchiwataru@Macintosh] ~/vagrant/centos
% rm -rf ~/.vagrant.d/plugins.json ~/.vagrant.d/gems

デフォルトでインストールされているプラグインはこれ。

[noguchiwataru@Macintosh] ~
% vagrant plugin list
vagrant-login (1.0.1, system)
vagrant-share (1.1.0, system)

改めて vagrant init してみる。

なんだかVagrantの内部状態をアップグレードしてるから殺してくれるなと言ってるっぽい。
いくらかディスク容量使うよとも言っている。
とくに問題ないので待つ。

% vagrant init
Vagrant is upgrading some internal state for the latest version.
Please do not quit Vagrant at this time. While upgrading, Vagrant
will need to copy all your boxes, so it will use a considerable
amount of disk space. After it is done upgrading, the temporary disk
space will be freed.
Press ctrl-c now to exit if you want to remove some boxes or free
up some disk space.
Press any other key to continue.
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.

Press any other key to continue. と表示されたところでそのままエンターする。

これでおしまい。

Vagrant boxイメージをインポートする

いつもならHashiCorpあたりで提供されているCentOSのboxイメージを使うか、
Packer等で自作するか、より手軽にイメージが欲しければ

A list of base boxes for Vagrant – Vagrantbox.es

を使うんだけど、 Vagrantbox.es はプルリクがあったら特に確認しないでバカスカリンクを突っ込んでるからあんまり推奨されてなかった。
前ダウンロードしたUbuntu Serverのboxイメージのaptがやたら遅いと思ったらブラジル向いてたよ。

Getting Startedを真面目に読むと

Getting Started – Vagrant Documentation

vagrant init hashicorp/precise32

すればVagrantfileが生成される。
vagrant up すれば勝手にUbuntuのboxがダウンロードされてくるようだ。
確かに動いたけど、なんでURLも指定しないでダウンロードできたのが意味がわからないし、
僕はCentOSのboxイメージが欲しかったのでもう少し調べてみた。

Boxes – Vagrant Documentation

によると

The easiest way to use a box is to add a box from the publicly available catalog of Vagrant boxes. You can also add and share your own customized boxes on this website.

もっとも簡単にboxを追加する方法は公開されたVagrant boxのカタログから取ってくるのが簡単だよって言ってる。

Vagrant Cloud

なんだか今のバージョンではVagrant Cloudにアカウントが無くてもダウンロードできるっぽい。

今登録されているのは以下。

[noguchiwataru@Macintosh] ~
% vagrant box list
Berkshelf-CentOS-6.3-x86_64-minimal (virtualbox, 0)
base                                (virtualbox, 0)
chef/centos-6.5                     (virtualbox, 1.0.0)
dummy                               (aws, 0)
hashicorp/precise32                 (virtualbox, 1.0.0)

とかメジャーな組織がメンテナンスしているboxが取ってくることができるので Vagrantbox.es からとってくるよりよっぽど安心できますね。

参考文献

  1. Getting Started – Vagrant Documentation
  2. Boxes – Vagrant Documentation
  3. Vagrant Cloud
  4. chef
  5. vagrantのboxをvagrant cloudからもらってくる – わすれっぽいきみえ
  6. A list of base boxes for Vagrant – Vagrantbox.es