このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

1円クラウド・ホスティングDigitalOceanを、Vagrantから使ってみる

SSDなVPSを提供するDigitalOcean(https://www.digitalocean.com/)については、徳丸さんの記事に分かりやすく紹介されています。徳丸さん記事のタイトル「1時間1円から使える」から、「1円クラウド・ホスティング」と名づけてみたのですが、これはウソではありません。現状の僕の利用明細は次のとおりです。

0.01ドル単位で課金されて、合計で0.05ドルです。

このDigitalOceanを、去年くらいから話題となっている仮想環境マネージャVagrantから使ってみました。これ、便利ですよ。

内容:

DigitalOceanに申し込んでドロップレット(仮想マシン)を作る

トップページの[Sign UP]から申し込み(アカウント取得)ができます。メールアドレスとパスワードを入力して[Create an Account]するだけです。すると、Welcome to DigitalOcean! となります。とても簡単。僕は、徳丸さんのrefcode(アフィリエイト・リンク)から申し込みました。

アカウントを取得したら、課金のためのPayment Methodsを入力します。クレジットカード、PayPal、Promo Codeが使えます。それが終われば、ドロップレット(仮想マシン)が作れます。ドロップレットを作る手順は次の3ステップ。

  1. Update Billing
  2. Create Droplet
  3. Root Access

[Update Billing]は終わっているので、[Create Droplet]に進みます。Hostnameを入力し、Size(メモリ、CPU、SSD、転送量)、Region(データセンターの場所)、Image(システムのモトネタ)を選びます。リージョンは、日本からの使用だと、San Francisco 1 か Singapore 1 が良いようです(僕はデフォルトの New York 2 のままでしたが)*1。(Add optional SSH Keys と Settings は特に設定しなくていいでしょう。)

ドロップレットを作成した段階で、次のようなメールが送られて来ます。

Your new droplet has been created!

You can access it using the following credentials:
IP Address: xxx.xxx.xxx.xx
Username: root
Password: yyyyyyyyyyyy

[Root Access]に進むと、ブラウザ内に表示されるコンソールからrootログインできます。ブラウザではなくて、ssh root@xxx.xxx.xxx.xx というコマンドでも同じです。これで、指定したスペックのマシンとルートアクセスが手に入りました。

ドロップレットの管理画面に、利用できるドロップレットがリストされます。

一覧から特定のドロップレットを選ぶと、電源オフ(シャットダウン)、電源オン(ブート)、リブート、仮想マシンの削除などが行えます。使った分だけ課金されます。電源オフのときも課金はされるようです。不要なドロップレットは削除しましょう。

Vagrantを使った操作の準備:DigitalOcean側

ブラウザとSSHクライアントだけでもDigitalOceanのドロップレットを操作できますが、Vagrantを使うと非常にラクチンになります。Vagrantについては、Web上に豊富な情報がありますが、最近次の書籍が出ました。

実践 Vagrant

実践 Vagrant

Amazon

実は、この本を買ったので、DigitalOcean + Vagrant を試してみようと思ったわけです。Amazon EC2 + Vagrant については伊藤直也さんによる付録F「Vagrant と Amazon EC2」に記述があります。DigitalOceanもEC2と似たようなものです(たぶん、より簡単)。

Vagrantは、DigitalOceanのAPIを使ってドロップレットを制御するので、DigitalOceanの顧客IDとAPIキーを入手します。単に、コントロールパネルの[API](https://cloud.digitalocean.com/api_access)を選んで、[Generate New Key]ボタンを押すだけの話です。顧客IDもAPIキーも、32桁の16進数文字列です。

「SSHの認証キーはどうするんだろう?」と思ったのですが、これはVagrantが面倒をみてくれるので、DigitalOcean側では特に何もしなくても大丈夫です。

大事な注意:ブラウザのコントロールパネル画面から作ったドロップレットを、後からVagrantで操作しようとすると変なことになります。Vagrantで操作するドロップレットは最初からVagrantに作らせてください。

Vagrantを使った操作の準備:ローカルマシン側

Vagrantにvagrant-digitaloceanプラグインを導入する必要があります。

$ vagrant plugin install vagrant-digitalocean
Installing the 'vagrant-digitalocean' plugin. This can take a few minutes...
Installed the plugin 'vagrant-digitalocean (0.5.3)'!

$

これだけです。

VagrantでDigitalOceanドロップレットを操作するには、ローカルマシンにsshやrsyncが必要です。Windowsでは、CygwinやMinGW/MSYSによりPOSIX環境(のサブセット)を揃えておく必要があります。僕はMSYSを使っています。

SSHのキーペア(秘密鍵と公開鍵)を作ってないときは、これを作る必要があります。 ssh-keygen -t rsa -C someone@example.jp のようにすればいいでしょう。ここらへんは、SSHに関する情報を参照してください。既に自分のキーペアが作ってあればそれを使えます。秘密鍵のファイル名に、拡張子.pubを付けたファイルに公開鍵が入っていると仮定しているようなので、そのような名前(例えば、~/.ssh/id_rsa と ~/.ssh/id_rsa.pub)にしておきます。

rsyncが使えることも確認してください。

$ which rsync
/bin/rsync.exe

$

Windows上のMSYSの場合はちょっと問題があります。どうも、vagrant-digitaloceanプラグインがCygwinを仮定しているらしく、C:\Users\hiyama\ のようなWindowsパスを /cygdrive/c/Users/hiyama/ にマップするのです。MSYSでは /c/Users/hiyama/ です。シンボリックリンクで対処できないかと試みたのですがどうもうまくいきません。/etc/fstabに次のエントリーを付け加えました。

C:\    /cygdrive/c
||

これをすると他に影響があってうれしくないのですが、まーしょうがない。

<h4>Vagrantによるドロップレット操作</h4>

次のようなVagrantfileを作りました。

>|ruby|
# -*- coding: utf-8; mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.hostname = "do-centos64-x64"
  config.vm.box = "digital_ocean"
  config.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
  config.ssh.private_key_path = "~/.ssh/id_rsa"

  config.vm.provider :digital_ocean do |provider|
    provider.client_id = "... CLIENT ID ..."
    provider.api_key = "... API KEY ..."
    provider.image = "CentOS 6.4 x64"
    provider.region = "New York 2"
  end

end

config.ssh.private_key_path = "~/.ssh/id_rsa" は、SSHの秘密鍵のパスを指定します。この例だと、公開鍵は ~/.ssh/id_rsa.pub になります。

client_idとapi_keyは、先に入手しておいた実際の値を指定します。config.vm.provider :digital_ocean の部分は、ブラウザのDigitalOceanコントロールパネル画面からドロップレットを作るときと同じ項目を指定します。設定に関するより詳しい情報は:

さて、vagrant up してみましょう。

$ vagrant up --provider=digital_ocean
Bringing machine 'default' up with 'digital_ocean' provider...
[default] Creating new SSH key: Vagrant...
[default] Creating a new droplet...
[default] Assigned IP address: 107.170.54.137
DL is deprecated, please use Fiddle
[default] Modifying sudoers file to remove tty requirement...
[default] Rsyncing folder: /cygdrive/c/Users/hiyama/Work/digitalOcean/ => /vagrant...

$

DL is deprecated, please use Fiddle はいつも出る警告ですが、気にしなくてもいいようです。

初回起動では、Creating new SSH key: Vagrant... となります。VagrantがDigitalOcean側に公開鍵を登録してくれます。SSH公開鍵の登録は初回のみで、次からは登録済みのキーを使うことになります。

$ vagrant up --provider=digital_ocean
Bringing machine 'default' up with 'digital_ocean' provider...
[default] Using existing SSH key: Vagrant

… 後は同じ

$

sshでログインしてみます。

$ vagrant ssh
[root@do-centos64-x64 ~]# w
 02:46:17 up 7 min,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    flh1ael181.tky.m 02:46    0.00s  0.02s  0.00s w
[root@do-centos64-x64 vagrant]# su vagrant
su: user vagrant does not exist
[root@do-centos64-x64 ~]# cd /vagrant/
[root@do-centos64-x64 vagrant]# ls
Vagrantfile  Vagrantfile~
[root@do-centos64-x64 vagrant]# exit
logout
Connection to 107.170.54.137 closed.

$

VirtualBoxプロバイダーのときのSSHユーザーはvagrantですが、DigitalOceanだとrootでログインです。Vagrantfileがあるディレクトリが、仮想マシンの /vagrant/ としてアクセス可能となります。これは、VirtualBoxプロバイダーのときと同じです。ただし、常に同期しているわけではなくて、vagrant up のタイミングでrsyncコマンドでデータ転送されます。upしている状態でrsyncさせたいときは、vagrant provision が使えます。

$ echo hello > hello.txt

$ vagrant provision
[default] Rsyncing folder: /cygdrive/C/Users/hiyama/Work/digitalOcean/ => /vagrant...
DL is deprecated, please use Fiddle

$ vagrant ssh
Last login: Sat Mar  1 02:49:02 2014 from flh1ael181.tky.mesh.ad.jp
[root@do-centos64-x64 ~]# cat /vagrant/hello.txt
hello
[root@do-centos64-x64 ~]# exit
logout
Connection to 107.170.54.137 closed.

$

DigitalOceanのドロップレットの電源を落とすには次のようにします。

$ vagrant status
Current machine states:

default                   active (digital_ocean)

active

$ vagrant halt
[default] Powering off the droplet...

$

ブラウザのコントロールパネル画面からドロップレットの状態を確認すると、確かにパワーオフになっています。

ドロップレットを完全に削除するには:

$ vagrant status
Current machine states:

default                   off (digital_ocean)

off

$ vagrant destroy
Are you sure you want to destroy the 'default' VM? [y/N] y
[default] Destroying the droplet...

$

プロビジョニング

生成した仮想マシンを適切にセットアップすることがプロビジョニングです。Vagrantはプロビジョニングをサポートしています。ここでは、一番簡単なシェルスクリプトを使ったプロビジョニングを実行してみます。

Vagrantfileがあるディレクトリに、次のようなシェルスクリプトをprovision.shという名前で準備します。

#!/bin/sh
# -*- coding: utf-8-unix -*- 

yum install -y httpd
rm -rf /var/www/html
ln -fs /vagrant /var/www/html
chkconfig httpd on
service httpd start

Vagrantfileに、config.vm.provision という行を追加します。

# -*- coding: utf-8; mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.hostname = "do-centos64-x64"
  config.vm.box = "digital_ocean"
  config.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
  config.ssh.private_key_path = "~/.ssh/id_rsa"

  config.vm.provider :digital_ocean do |provider|
    provider.client_id = "... CLIENT ID ..."
    provider.api_key = "... API KEY ..."
    provider.image = "CentOS 6.4 x64"
    provider.region = "New York 2"
  end

  config.vm.provision "shell", path: "./provision.sh"

end

これによって、ドロップレット(仮想マシン)が生成された直後に指定のシェルスクリプトが実行されます。具体的には、Apache HTTPサーバーがインストールされて、/vagrant/ をDocumentRootとしてサービスを開始します。

DigitalOceanドロップレット(仮想マシン)の /vagrant/ は、ローカル作業ディレクトリと同期しているので、ローカルに次のようなファイルを準備しておけば、これがApacheによりWebに公開されます。

<h1>Hello, DigitalOcean</h1>

vagrant provision で強制的にプロビジョニングして、ブラウザでドロップレットのIPアドレスにアクセスしてみます。

確かにドロップレット上でWebサーバーが動いています。なお、ドロップレットのIPアドレスは次のように、vagrant ssh-config で知ることができます。

$ vagrant ssh-config
Host default
  HostName 107.170.54.137
  User root
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/Users/hiyama/Work/.ssh/id_rsa
  IdentitiesOnly yes
  LogLevel FATAL

$

その他こまごま

ドロップレットには、生成されるたびに新しいIPアドレスが割り当てられます。生のIPアドレスではなくてホスト名でアクセスできるとよいのですが、頻繁に生成・破棄を繰り返す場合は、「DNSに登録して」なんてことはできません。

この問題を解決するために、vagrant-hostmanager(https://github.com/smdahlen/vagrant-hostmanager)というプラグインがあるのですが、Windowsでは、vagrant up のタイミングではなくて、vagrant destroy のときにhostsにエントリーを追加する、というワケの分からない挙動をしていて使えませんでした。[追記]https://github.com/cogitatio/vagrant-hostsupdater というプラグインを見つけました。しかし、DigitalOceanプロバイダーには対応してないらしく、これもうまく動きませんでした。[/追記]

DigitalOceanの顧客IDとAPIキーをVagrantfileに入れたくないときは、環境変数経由で値を取り込みます。次のようになります。

# -*- coding: utf-8; mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.hostname = "do-centos64-x64"
  config.vm.box = "digital_ocean"
  config.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
  config.ssh.private_key_path = "~/.ssh/id_rsa"

  config.vm.provider :digital_ocean do |provider|
    provider.client_id = ENV['DO_CLIENT_ID']
    provider.api_key = ENV['DO_API_KEY']
    provider.image = "CentOS 6.4 x64"
    provider.region = "New York 2"
  end

  config.vm.provision "shell", path: "./provision.sh"

end

このVagrantfileを使う前に、環境変数をセットしておく必要があります。setup-env.shというファイルを作り、事前にsourceしましょう。なお、環境変数VAGRANT_DEFAULT_PROVIDERをセットしておくと、--providerオプションを省略できるので、これも設定しています。

# setup-env.sh -- Source this file to setup DigitalOcean environment variables

export VAGRANT_DEFAULT_PROVIDER=digital_ocean

export DO_CLIENT_ID=" ... "
export DO_API_KEY=" ... "

クラウド上の仮想マシンであるドロップレットが、VirtualBoxによるローカル仮想マシンとほとんど同じように扱えるのは、けっこう感慨深いものがあります。

*1:ネットワーク通信ではサンフランシスコやシンガポールのほうが有利でしょうが、ドロップレットの生成ではニューヨークのほうが速いような気がします。