メイン

2010年8月11日

仮想マシンとLVM2で簡単サーバ構築
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

はじめまして、7月に入社いたしましたsatoshiと申します。

会社でも自宅でもPCをMacにして、Linuxと同じ操作感で使用できて快適な今日この頃ですが、皆様いかがお過ごしでしょうか?

今回、KVM(Kernel-based Virtual Machine)とLVM(Logical Volume Manager)を使用して、サーバ構築すると便利なケースを紹介したいと思います。

新しくサーバを構築する場合、OSインストールイメージをDVDに焼いて、DVDをドライブに挿入して、手順の通り選択して...となると思います。 (中には、Cobblerを使用しているという先進的な方もいらっしゃるかもしれませんが)

仮想マシンでは新たにサーバ環境を構築する場合、既存の仮想ディスクをコピーして使い回せるのでインストールの手間を簡略化できます。 さらに、一歩進んでLVMで作成したスナップショットLVを使用すると消費するディスク領域を大幅に節約できます。

今すぐにデモ環境を用意したいとか、Webサーバは共通のものを使いたいが、アプリケーションがPHPとPythonって環境が異なるとか OSをアップグレードしたらどうなるかチェックしたいとか...等々いろいろ利用ケースを考えてみました。

前提環境

作成する仮想マシンは、ベース環境となる仮想マシンを必要としますのであらかじめ作成しておく必要があります。 さらに、スナップショットLVを利用した仮想マシン使用時は、元の仮想マシン(ベース環境)を停止しておきます。 また、インストール時のパラメータを変更すれば、XenやほかのLinuxディストリビューションでも流用可能だと思います。

物理マシン(ホスト環境)

物理マシン(サーバ機)にインストールした環境をホスト環境と呼ぶことにします。

KVMを仮想マシンに使用する場合は、ほぼ強制的にCPU仮想化支援機能が有効化されていることが必要です。

CPU仮想化支援機能
IntelVT-x OR AMD-V
OS
CentOS5.5
仮想マシンソフトウェア
KVM
仮想マシン管理ライブラリ
Libvirt
ボリューム管理
LVM2

仮想マシン(ベース環境,クローン環境)

複製元となる環境をベース環境と呼ぶことにします。

複製元からデータをコピーして作成した環境をクローン環境と呼ぶことにします。

OS
CentOS5.5
仮想ディスク
LVM2のLV(Logical Volume)

仮想マシン(オンデマンド環境)

ベース環境のLVから作成したスナップショットLVを利用した環境をオンデマンド環境を呼ぶことにします。

OS
CentOS5.5
仮想ディスク
LVM2のスナップショットLV

手順

事前準備

まずは、ベース環境の仮想マシンを作成します。 diskオプションに指定しているpoolは、VG(Volume Group)です。このように指定するとVGからLVが自動的に作成されます。 (LV名は、nameオプションで指定した名称+.img)

ベース環境作成:

# VGをlibvirtで管理
$ sudo virsh pool-create-as ServiceVG00 --type=lvm2 --target=/dev/ServiceVG00
# ベース環境の仮想マシンを作成
$ sudo virt-install \
--location http://ftp.riken.jp/Linux/centos/5/os/x86_64/ \
--accelerate \
--name basevm \
--ram 1024 \
--vcpus 2 \
--noacpi \
--os-variant rhel5.4 \
--network bridge:br0 \
--extra-args console=ttyS0,115200n8 \
--disk pool=ServiceVG00,bus=virtio,size=48,cache=writethrough \
--noreboot \
--keymap=ja

#インストーラが起動するので、OSのインストールを行います。
インストールを開始しています...
(...)
Guest installation complete... you can restart your domain
by running 'virsh start basevm'

インストールが完了したら、ホストOSにて仮想マシンの時刻設定を行います。

仮想マシンの時刻設定:

# 仮想マシンの時刻設定変更
$ sudo virsh edit basevm
<domain type='kvm'>
  <name>basevm</name>
  <uuid>bd55f202-cfd4-3d8b-ef23-d9e4d37c4711</uuid>

(...)
  </features>
  <clock offset='localtime'/>     # <= 'utc'を'localtime'に変更
  <on_poweroff>destroy</on_poweroff>
(...)
</domain>

後は、いつも通りOSの初期設定を行います。 (時刻設定、ネットワーク設定、パッケージインストール・更新等)

ベース環境初期設定:

# 仮想マシンの起動
$ sudo virsh start basevm
# ゲストOSにログインして初期設定
$ sudo virsh console basevm
connect to domain basevm
Escape character is ^]

(...)
CentOS release 5.5 (Final)
Kernel 2.6.18-194.8.1.el5 on an x86_64

basevm login:~root
Password:
Last login: Sun Aug  1 19:34:34 2010 from 192.168.100.8
[root@basevm ~]#

ケース1: 開発環境を複製する

個人ごとの開発環境を複製して、個別に環境をカスタマイズしたいという場合、ベース環境に必要なパッケージをインストールし、そのベース環境のLVを元にスナップショットLVを作成し、オンデマンド仮想マシンを作成すれば簡単に作成できます。 また、スナップショットLVに割り当てるディスク容量はデータが変更される分のみ見積もればよいので、ディスク容量を大幅に節約できます。

手順

  1. ベース環境のゲストOSで必要なパッケージをインストール

  2. 仮想マシン(ベース環境)をシャットダウン

  3. 必要な分だけ以下の操作を繰り返す

  4. ベース環境用LVのスナップショットLVを作成

    スナップショットLVの作成:

    # ベース環境LVのパスを確認
    $ sudo virsh dumpxml basevm | grep -A5 '<disk'
        <disk type='block' device='disk'>
    
          <driver name='qemu' cache='writethrough'/>
          <source dev='/dev/ServiceVG00/basevm.img'/> #<= LVのパス
          <target dev='vda' bus='virtio'/>
        </disk>
        <interface type='bridge'>
    # スナップショットLVの作成(ベース環境に対してディスク容量を1/48で設定)
    $ sudo lvcreate -s -L 1G -n snapvm.img /dev/ServiceVG00/basevm.img
    
    
  5. 作成したスナップショットLVを使用し、オンデマンド仮想マシンを作成

    OSのインストールはスキップできるので一瞬で仮想マシンの作成は完了します。 diskオプションに指定しているvolはスナップショットLVを指定しますが、指定方法は"Pool名/Volume名"となります。 (Libvirtで管理されているPoolからLVを作成すると自動的にLibvirtの管理下に入ります)

    オンデマンド仮想マシンの作成:

    $ sudo virt-install \
        --import \
        --accelerate \
        --name snapvm \
        --ram 1024 \
        --vcpus 2 \
        --noacpi \
        --os-variant rhel5.4 \
        --network bridge:br0 \
        --extra-args console=ttyS0,115200n8 \
        --disk vol=ServiceVG00/snapvm.img,bus=virtio,cache=writethrough \
        --noreboot \
        --keymap=ja
    
    インストールを開始しています...
    Guest installation complete... you can restart your domain
    by running 'virsh start snapvm'
    
  6. オンデマンド環境の仮想マシンに展開されたOSの各種調整(主にネットワーク設定)

    オンデマンド環境の仮想マシンで動作するOSは、元のベース環境とほぼ同じですが、MACアドレスの書換等ネットワーク周りの設定が自動的に変更されています。 環境依存の部分(ホスト名、ユーザパスワード)の変更を行えば、ベース環境のデータを共有しつつも、それぞれ別の開発環境として使用することが可能になります。

  7. 個別の環境作成

    後は、アプリケーションのデプロイをするだけで専用の開発環境が作成できます。

必要がなくなれば、仮想マシンを停止しスナップショットLVを削除するだけです。


Tip

スナップショットLVの拡張方法
スナップショットLVは通常のLVと同じく拡張が可能ですので、当初の見積もりよりデータの変更量が大きかった場合、下記のコマンドによりディスク容量の拡張できます。

LVのディスク容量の拡張:

# さらに+1G拡張する
$ sudo lvextend -L +1G /dev/ServiceVG00/snapvm.img

ケース2: オンデマンド環境の構成を実稼働環境として使用

オンデマンド環境のスナップショットLVをバックアップすると、ベース環境のデータとスナップショットに書き込まれたデータが取得できるので、それを新たに作成したLVに書き込みます。 これにより、ベース環境ともオンデマンド環境とも独立したサーバ環境を構築することができます。 オンデマンド環境の場合、大半のデータをベース環境と共存していましたが、この環境の場合は、すべてのデータをコピーしたクローン環境ですので、全く別の環境として構築することが可能です。

手順

  1. 仮想マシンを停止

  2. 新規仮想マシンを稼働させるLVを作成

    作成するLVのサイズはベース環境のLVと同等以上にします。

    LVの作成:

    $ sudo lvcreate -L 48G -n prod01.img ServiceVG00
    
  3. スナップショットLVを利用して仮想イメージを新規LVにコピー

    ベース環境のデータとスナップショットに書き込まれたデータを新たに作成したLVにコピーします。 (ディスク容量が大きければそれだけ時間がかかります。)

    仮想イメージをLVにコピー:

    
    $ sudo dd if=/dev/ServiceVG00/snapvm.img of=/dev/ServiceVG00/prod01.img bs=8192
    
  4. 仮想マシンを起動し、ゲストOSの設定を修正

    手順は、ケース1の4.以降と同様です。

ケース3: 仮想サーバのOSパッケージを実際にインストール・アップグレードした場合の影響が知りたい

yumコマンド等を使用すればいろいろそのパッケージの依存関係とか教えてくれますが、実際にアップグレードしてみないとわからないことも多々あります。 同じ環境の仮想サーバを複数台用意していたとして、そのスペアをアップグレードを試す環境として使うことが多いと思いますが、もし失敗した場合、スペアを破棄しなければならず再インストールということになってしまいます。 実際に試す環境として、スペアから作成したスナップショットLVを使用したオンデマンド仮想マシンを利用することもできます。 これなら失敗したとしてもスペアの環境には影響せず、かつ何度もアップグレードを試すことができます。

手順

  1. 仮想マシンの一時停止(virsh suspend)

    仮想マシンの一時停止:

    $ sudo virsh suspend basevm
    
  2. 仮想マシンLVのスナップショットLVを取得

  3. スナップショットLVを使用して、新規オンデマンド仮想マシンを作成

  4. オンデマンド環境のOSにログインし、実際にパッケージのアップグレード

  5. 問題なかったら、オンデマンド環境を停止し削除

  6. 一時停止状態の既存仮想マシンを再開し、パッケージのアップグレード

    仮想マシンの再開:

    $ sudo virsh resume basevm
    
    

インストール・アップグレードで失敗しても、2-5の手順を何度でもやり直すことができます。

最後に

今回使用したKVMは、Kernel-based...と名前の通りKernelに組み込まれ、標準のOSをそのままに動作させることが可能になっています。 KernelがバージョンアップするごとにKVMも機能強化されていくのでさらに使いやすくなっていくことでしょう。

コマンドラインが扱いづらいという方は、GUIデスクトップベース・Webベースのツールがリリースされていますのでそちらを使えばよいでしょう。

GUIデスクトップクライアント


Note

今回使用したコマンド virt-install も上記と同一プロジェクトの成果物です。


Webアプリケーション

大規模VM管理プラットフォーム

2010年6月11日

「ちわさん、奥さんが来ましたよ」
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

「え!?妻が会社に!?」と一瞬戸惑いましたが奥一穂さんでした。
別に妻が会社に来てもやましいことなど何もありませんが、こんちには、ちわです。こんにちわ。

以前の記事でもご紹介した通り弊社が提供しているまちつく!というサービスでは Q4M 0.9.0 を利用して地図の画像生成と Amazon S3 への転送を行っています。
その Q4M に障害が発生し弊社ではどうも解決できそうにないので Q4M の作者の奥一穂さんに相談させてもらいました。
その際は、デッドロックのバグを踏んでいる可能性があるので Q4M を 0.9.1 以上のものしてみてはどうかと返答を頂きました。
弊社では 64bit 環境であった為、0.9.2 は除外され、0.9.3 は新しすぎるので 0.9.1 を採用することにし、バージョンアップ後に障害もなく安定稼働を続けています。

そんな経緯もありまして、先日弊社に奥一穂さんが来社されることになり Q4M について10ページ程のスライドで Q4M の現状とこれからを紹介して頂いたり、弊社からいくつか質問をさせて頂く機会がありましたので今回は弊社からの質問とその回答をご紹介したいと思います。

queue_end() を呼ぶ頻度とデッドロックについて
ウ:(Q4M 0.9.0 の環境で)障害が起きたサービスと一度も障害が起きていないサービスがあります。障害の起きたサービスでは queue_wait() のループ内で毎回 queue_end() を呼んでいますが、他方では queue_wait() のループの外で queue_end() を呼んでいます。障害の起きたサービスでは頻繁に queue_end() を呼んでいることになりますが、queue_end() を頻繁に呼ぶことがデッドロックを誘発する原因になりうるのでしょうか?
奥(敬称略):まずデッドロックが発生するのは確率的な問題です。
queue_end() を頻繁に呼ぶことがデッドロックの発生率を高める主な要因にはならないと思います。

キューのリトライについて
ウ:キューのリトライの常套手段としてはどのようなものがありますか?
奥:例えば、優先度が高・中・低のテーブルを用意して高で失敗したキューをリトライ用として中のテーブルに入れます。
高が空になった時点でリトライ用の中に入っているキューを処理させる等でしょうか。

ウ:リトライを時間で制御したい場合はどのようにすればよいですか?例えば、キューの処理に失敗したらX秒後に処理するとか。
奥:リトライ用のキューに入れた時間とそのキューを取り出した時点での時刻を比較する。リトライ用のキューを取り出した時点でX秒経っていなかったら任意の時間 sleep する。
というのはどうでしょうか。

Conditional Subscription について
ウ:Conditional Subscription というのがありm
奥:あっ、Conditional Subscription 使ってますか?
ウ:使ってますね。使わないですか?
奥:私自身はあまり使っていないですね。
単純に queue_wait('table') するなら先頭からレコードを取り出せばよいですが、Conditional Subscription を使用すると条件に合致するレコードを走査する必要があるので溜まっているレコードが多ければそれだけコストがかかります。

アプリケーションとのアトミックな処理について
ウ:アプリケーションである処理の成功時に Q4M へ INSERT する、というロジックがあったとして、そのある処理は成功したけど Q4M への INSERT には失敗したという状況がありますが、このような場合はどうすればよいでしょうか?
奥:そうですね、Q4M ではなくて InnoDB でなんちゃってメッセージキューを実装するという解決方法はありますね。現状だとどうしようもないですね。Q4M でもトランザクションを扱えるようにしたいとは思っています。

処理したキューの統計情報について
ウ:例えば、一日に処理したキューの数を知りたいと思ったら SHOW ENGINE QUEUE STATUS; の数字を見ればよいのですか?
奥:そうですね。
ちょっとパースしづらいとは思いますが、その数字を見てください。

Parallel::Prefork について
ウ:Parallel::Prefork で fork している子プロセスが queue_wait() を呼んでタイムアウトになればその子プロセスは死にますが、現在のところ queue_wait() がタイムアウトする状況は把握していません。そうなると子プロセスはいつまでたっても死んでくれないという実装をしてしまったのですが Parallel::Prefork に Apache で言うところの MaxRequestsPerChild のようなものは実装される予定はありますか?
奥:ないですね。ImageMagick 等で画像を作っているのであればメモリリークも心配ですよね。必要であれば worker で実装してみてください。
ウ:はい、実装させて頂きます。

YAPC Asia 2010 について
ウ:YAPC Asia 2010 にスピーカーで参加する予定はありますか?
奥:今のところないです。

まとめ
「奥さんがウノウに来てくれるらしい」という話から実際に来社されるまでの時間が短く、奥さんへの質問の準備が足りなかったことが悔やまれますが以上が今回質問させて頂いた内容とその回答です。
どのような背景でどのように Q4M を使用するかは様々だとは思いますが、開発者の奥さんが Conditional Subscription をあまり使用していないというのは少々驚きました。まちつく!では Conditional Subscription は使用していませんが他プロジェクトでは使用しているようです。
同じ社内でも Q4M の使い方が違うので他社の方がどのように Q4M を使用しているかは気になるところです。

奥さんへ
お忙しい中来社して頂き、またウノウラボへの掲載を快諾していただきありがとうございました。

ウノウでは特に最近、積極的にエンジニアを採用しています。
採用ページをご覧になり興味のある方、ぜひご応募ください!!
Find Job!でも募集開始してます!

ウノウでは積極的にエンジニアを募集していますが、弊社にて勉強会を開いて頂けるエンジニアも募集したいと思っています。Twitter の弊社社長のリストのメンバーに向けて「勉強会がしたい」等つぶやいて頂ければ誰かしらが反応するとおもいます。日時の調整等がうまくいけば今回のように勉強会が実現するかもしれません。

2010年3月24日

秘伝のペケペケrcをつぎたす仕事
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは。murahashi です。
秘伝のペケペケrcの継ぎ足し方―あるいはbashrc, vimrc, screenrc それぞれについて別の場所のファイルを読み込む方法、再読み込みする方法―をまとめました。

dotfiles_sauce.jpg

どこかからコピペしてきたドットファイルを継ぎ足し継ぎ足しで自分に合わせた設定をつくり、それをいろんなところに持ちまわっている人は多いと思います。どうせならということで github や bitbucket や coderepos に公開している人もいるでしょう。

私も dotfiles という1ディレクトリにファイルをまとめて github にpush、使いたい場所でgit cloneして ~/dotfiles/.bashrc へのシンボリックリンクを ~/.bashrc に置いて「やったー」と喜んでいました。

ただ、この方法だとサーバの環境によって変えたい部分が出てきたときに困ってしまいます。私は困ってしまいました。
windowsでもgvimつかってるけど、いろいろかえたい
私の設定だと vimbackup なる決め打ちディレクトリがユーザ配下にないといけない..
コーディング規約 などなど

dotfiles_tangle.jpg

というわけでbashrc, vimrc, screenrcそれぞれについて別の場所のファイルを読み込む方法を検索してまとめしました。

# .bashrc
if [ -f $HOME/dotfiles/.bashrc ]; then
      source $HOME/dotfiles/.bashrc
fi
# .vimrc
if filereadable(expand('~/dotfiles/.vimrc'))
  source ~/dotfiles/.vimrc
endif
# .screenrc
source dotfiles/.screenrc

$HOME/dotfiles 以下にファイルがあるのは私の場合なので、適宜読み替えてください。
各環境のペケペケrcでは別の場所のファイルを読み込んでから、環境依存の項目を書くようにします。後から書いたほうが有効になります。

再読み込みについて
ペケペケrcが気軽に書けるようになると、書いてすぐ反映したくなるものです。
正確には再読み込みできるようにそれぞれのペケペケrcを書く必要があるのですが、そこまで手が回っていません。
単純な再読み込みを以下にあげます。

# .bashrc 再読み込み
$ source ~/.bashrc
# .vimrc 再読み込み
vimのコマンドモードで
:source $VIMRC
# .screenrc 再読み込み
screenのエスケープキーを入力して
:source $HOME/.screenrc

それでは楽しいプログラミングライフを!
dotfiles_enjoy.jpg

参照

Vim-users.jp - Hack #108: vimrc で外部ファイルを取り込む

卜部昌平のあまり reblogしないtumblr - 俺の .screenrc が火を吹くぜ
Vim-users.jp - Hack #74: 簡単にvimrcを編集する

環境

$ uname -a
Linux fri 2.6.32.9-70.fc12.i686 #1 SMP Wed Mar 3 05:14:32 UTC 2010 i686 i686 i386 GNU/Linux
$ bash --version
GNU bash, version 4.0.35(1)-release (i386-redhat-linux-gnu)
$ vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Dec 3 2009 08:50:41)
$ screen --version
Screen version 4.00.03 (FAU) 23-Oct-06

以上デース

ウノウでは特に最近、積極的にエンジニアを採用しています。

採用ページをご覧になり興味のある方、ぜひご応募ください。

Find Job!でも募集してます!

2010年3月12日

快適なsshクライアント生活
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

2010/03/13 一部記事修正。

はじめまして、HIROKIです。

大規模コンテンツの開発に携わっていると数多くのサーバにsshでログインすることになります。その手間を軽減するために $HOME/.ssh/config を設定してみます。

sshコマンドを簡略化

例えば dev01.labs.unoh.netというサーバにsshでログインするのであれば、
 $ ssh -i ~/.ssh/id_rsa.unoh hiroki@dev01.labs.unoh.net

という感じのコマンドでログインしているかと思います。

これを

 $ ssh dev01
でログインできるように設定してみましょう。
Host dev01
    User            hiroki
    HostName        dev01.labs.unoh.net
    IdentityFile    ~/.ssh/id_rsa.unoh

秘密鍵を複数使いわけている人はIdentityFileを指定すると便利です。

さらにホストを追加

さらにホストを追加してみます。
Host dev01
    User            hiroki
    HostName        dev01.labs.unoh.net
    IdentityFile    ~/.ssh/id_rsa.unoh

Host home
    User            hirocaster
    HostName 	    home.hiroki.jp
    IdentityFile    ~/.ssh/id_rsa.home
いままで
 $ ssh -i ~/.ssh/id_rsa.home hirocaster@home.hiroki.jp
でログインしていたのが
 $ ssh home
でログインできるようになりました。

各ホストの共通設定

すべてのホストの共通設定は以下のような感じ

Host *
     IdentityFile               ~/.ssh/id_rsa
     ForwardAgent               yes
     TCPKeepAlive               yes
     ServerAliveInterval        15
     ServerAliveCountMax        3

必ず設定ファイルの最後に追加するようにしてください。

踏み台を経由してログインする場合

応用編として、踏み台サーバ(op.labs.unoh.net)を経由して 開発サーバ(dev01.labs.unoh.net)にログインする場合

Host dev*
    User            hiroki
    IdentityFile    ~/.ssh/id_rsa.unoh
    ProxyCommand    ssh op.labs.unoh.net nc -w 6000 %h %p

踏み台サーバ(op.labs.unoh.net)の/etc/hostsにdev01,dev02などを追加しておくことがポイントです。

このようにしておけば、踏み台サーバを経由して開発サーバに入れます。

 $ ssh dev01
にもログインできますが、
 $ ssh dev02
にもログインできるようになります。

このようにワイルドカードを利用した設定もできます。

最終的な$HOME/.ssh/config

Host dev*
    User                        hiroki
    HostName                    dev.01.labs.unoh.net
    IdentityFile                ~/.ssh/id_rsa.unoh
    ProxyCommand                ssh op.labs.unoh.net nc -w 6000 %h %p

Host home
    User                        hirocaster
    HostName                    home.hiroki.jp
    IdentityFile                ~/.ssh/id_rsa.home

Host *
     IdentityFile               ~/.ssh/id_rsa
     ForwardAgent               yes
     TCPKeepAlive               yes
     ServerAliveInterval        15
     ServerAliveCountMax        3

以上でsshコマンドを利用してのログインが簡略化されました。

最後に

簡単にログインできるようになったからこそ、本番サーバとテストサーバを間違ってオペレーションしないようにログインした際にはサーバを確認する癖をつけてください。

$HOME/.ssh/configに関するその他の設定は

 $ man ssh_config

を参照ください。

ウノウでは特に最近、積極的にエンジニアを採用しています。
採用ページをご覧になり興味のある方、ぜひご応募ください。
Find Job!でも募集してます!

2009年6月26日

10テラバイトマシンのつくりかた
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加


「iPodの残り容量が200MBを切った」と社内で発言してから「iPhoneを買おう!」としきりに言われるようになったbokkoです。そんな私は先月、ホコリをかぶっていたデスクトップPCを筐体ごと買い換えました。今ではMacBookからSSHでログインしてターミナル上で快適な生活を送っています。

今月、2TBのHDDを6本使ったサーバを立てる機会がありまして、今日はその時のお話です。

続きを読む "10テラバイトマシンのつくりかた" »

  [PR] 転職


About Linux

ブログ「ウノウラボ Unoh Labs」のカテゴリ「Linux」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

前のカテゴリはlifehacksです。

次のカテゴリはLuaです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

ウノウサービス