JoyentのUbuntuVMでDockerを動かす

lxcとaufsで仮想マシンを色々と便利に使えるDockerを JoyentのUbuntuVMで使う方法。

基本的にEC2の案内と同じですけど、一部コツがあります。

OSの下ごしらえ

Ubuntu12.04のVMを使います。

‘/tmp’のアクセス権

VMのリリースバージョンにもよりますが、’/tmp’にstickey bitが立ってない(0755)ものがあります。
何をするにも普通に困るので変更しておきます。

chmod 01777 /tmp

マウント調整

JoyentのVMはルートデバイスが小さめで、’/data’にマウントする形でボリュームが追加されています。
容量をあまり気にしないで使うために、bind mountを使ってマウントポイントを調整します。

既存ディレクトリ移動とマウント

/var, /opt, /homeあたりを移動してしまえばよいでしょう。

mv /var /data/ ;mkdir /var; mount --bind /data/var /var
mv /home /data/ ;mkdir /home; mount --bind /data/home /home
mv /opt /data/ ;mkdir /opt; mount --bind /data/opt /opt 

fstabに追記

 cat << EOL >> /etc/fstab
/data/var /var none bind 0 0
/data/opt /opt none bind 0 0
/data/home /home none bind 0 0
EOL

一回再起動しておきましょう。

AUFS対応カーネルの導入

あとは公式のInstation:Ubuntu Linuxの12.04に従っていきます。

カーネル変更

デフォルトのカーネルはLinux 3.8.6-joyent-ubuntu-12-optと新しいのですが、aufsモジュールがありませんので変更します。

apt-get update && sudo apt-get install linux-image-generic-lts-raring

カーネルパッケージのインストールが終わったら、

/etc/default/grubGRUB_DEFAULT=2にして update-grubをかけます。

ちなみに0がLinux 3.8.6-joyentで、1はLinux 3.8.6-joyent(Recovery Mode)なので気をつけましょう。
update-grub後に再起動するまえには必ず/boot/grub/grub.cfgを確認しておくことをお奨めします。

Dockerのインストール

3.8.0-xx-genericのカーネルで起動したら、aufsモジュールをロードします。

modprobe aufs

あとはdotcloudのpptリポジトリを登録し、lxc-dockerパッケージをインストールするだけです。

apt-get install python-software-properties && sudo add-apt-repository ppa:dotcloud/lxc-docker
apt-get update
apt-get install lxc-docker

Docker Run!

GettingStartedの締めとして、Ubuntuコンテナを起動してみましょう。

docker run -i -t ubuntu /bin/bash

コンテナが起動して、ログイン状態になります。

他のシェルを立ち上げてからdocker psで確認します。

# docker ps
ID IMAGE COMMAND CREATED STATUS PORTS
0b51168a6cf3 ubuntu:12.04 /bin/bash 31 minutes ago Up 31 minutes

OKですね。

ChefServerの文書を書いています

ちょっと頼まれ事で、ChefServerについての文書を書いています。
目的はとあるサービスのプロモーションですが、ChefServer自体は特に何かのサービスに依存するというものでは無いのでそのつもりでまえがきを書いてみました。

まだまだドラフト版ですが、折角なので載せちゃおう。


ChefServerで考えなおそう構成管理と運用保守(Draft)

まえがき

この文書を手にとったあなたは、コンピュータシステムの構成管理と運用保守に少なからず関わっているものと思います。そして構成管理の省力化、運用保守の自動化に興味があるのでしょう。もちろん本文書の対象はそういった方々ですが、タイトルのChefServerを扱う前にすこしシステム管理についての考察にお付き合いください。

現在サーバの構成管理はどうしていますか? Excelにて作成した管理台帳をパソコンで保守し、共有フォルダで管理しているのでしょうか、Accessやひょっとすると自作のWebアプリケーションでしょうか。
それでは、管理台帳を更新する・参照する役割はどこにあるでしょう、たいていどちらも管理者=人間にありますね。

さて、あなたは管理台帳の元にあるシステムを更新します。いきなり管理台帳を更新するわけにはいきません、現状からどのような変更があるかと更新計画を立て、管理台帳を元に対象を絞込んで更新作業を実施して、管理台帳を更新するという手順を踏むことでしょう。
しかしこのワークフローには落とし穴がいくつも存在します、代表的なのが更新作業に手間取った挙句、管理台帳への反映が遅れたり、間違った情報で更新したり、あまつさえ反映そのものを忘れたりします。少なくとも私はそうですから、この文書を手にとった方にも何割かいることを期待します。

ここで考えてみます、管理台帳の更新を各サーバが現状に合わせて自動で行なってくれたら、また更新された管理台帳の情報を各サーバが直接参照でき、利用することができるなら? そしてもう一歩、管理台帳の情報にサーバの方から合わせてくれたなら。
管理台帳を編集することで管理対象のサーバはそれぞれが台帳に書かれている通りのふるまいに役割を更新し、サーバ同士で役割を確認し合うことで変更を追従し、結果=現状を管理台帳へリアルタイムに反映することができます。

もちろん商用のシステム管理ソリューションにはワークフローの問題を解決する優秀なソフトウェアがいくつか存在します、代表的なもので IBMのTivoli、 Microsoft(R) のActiveDirecotory(™) などが挙げられます。

そしてOpen Source Project にも強力な構成管理フレームワークが登場しています、その1つがこの文書で取り扱うChefです。Chefは今日も活発に開発が進められており、より沢山のプラットフォーム、概ねあらゆるシステムに対応すべく日々進歩しています。本文書ではその中でも構成管理の要であるChefServerを中心に解説していきます。


まえがきはここまでです、さて続きを書いていきましょうか

Joyent SmartOSでpkgin版rabbitmqのFile descriptor(FD)数を変更

JoyentがSmartOS用にパッケージ提供するrabbitmqをインストールして起動すると、デフォルトのFDが1024と心もとないので増やす。

RabbitMQ Management.jpg

変更対象ファイル

/opt/local/etc/rabbitmq/rabbitmq-env.conf

ulimit -n 10240

リスタートするとFDが増えている。

# svcadm restart rabbitmq
# plimit `pgrep beam`   
20741:  /opt/local/lib/erlang/erts-5.9.1/bin/beam.smp -W w -K true -A30 -P 104
   resource              current         maximum
  time(seconds)         unlimited       unlimited
  file(blocks)          unlimited       unlimited
  data(kbytes)          unlimited       unlimited
  stack(kbytes)         10240           unlimited
  coredump(blocks)      unlimited       unlimited
  nofiles(descriptors)  10240           10240
  vmemory(kbytes)       unlimited       unlimited

追った軌跡

smfのマニュフェストをいじろうかと思っていたが、まわりまわってコンフィグファイルで良かった。

  1. smfで確認、/opt/local/sbin/rabbitmq-serverが起動スクリプト。
  2. rabbitmq-server/opt/local/sbin/rabbitmq-envをドットコマンドで読んでいた。
  3. rabbitmq-envでは/opt/local/sbin/rabbitmq-defaultsをドットコマンドで読んでいた。
  4. rabbitmq-defaultsではユーザ環境ファイル /opt/local/etc/rabbitmq/rabbitmq-env.confを定義していた。
  5. rabbitmq-envに帰ったらユーザ環境ファイルをドットコマンドで読んでいた。
  6. 最後にrabbitmq-serversh -xオプションで実行して起動処理の中盤でulimitが実行されているのを確認した。

なかなか回りくどいが結果オーライ。

SmartOSの各種情報を取得する

JoyentのSmartOSで各種情報を取得するツールの案内。

smartos-blue

ちなみにここで紹介しているツールはbase64の1.8.xで確認、1.7以前のSmartOSには多分無いです。

sm-summaryを叩く

以前はイマイチ環境情報を取りにくかったSmartOSですが、sm-*コマンドの実装により相当扱いやすくなっています。

そのひとつがsm-summary

$ sm-summary 
* Gathering SmartMachine summary..
SM UUID             0ec33864-49ce-4674-bf01-976b8e771cdc
SM ID               246
Hostname            test01.example.com
SmartOS build       joyent_20120614T001014Z 
Image               base64 1.8.4
Pkgsrc              http://pkgsrc.joyent.com/sdc6/2012Q2/x86_64/All
Processes           31
Memory (RSS) Cap    1024M
Memory (RSS) Used   128M
Memory (RSS) Free   896M
Swap Cap            1024M
Swap Used           101M
/tmp Used           12K
Disk Quota          31G
% Disk Used         13%

準仮想のコンテナにありがちな、リソース上限と現状リソースの相関がつかみにくいといった悩みが結構解消します。

sm-summaryスクリプトの中身

sm-summaryコマンドはただのBashスクリプトなので中身を確認します、


#!/usr/bin/bash
#
# Provides SmartMachine summary of information.
# Joyent 2012.

PATH=”/opt/local/bin:/opt/local/gnu/bin:/opt/local/sbin:/usr/bin:/usr/sbin”;

echo “* Gathering SmartMachine summary..”;
SM_UUID=$(zonename);
SM_ID=$(zoneadm list -p | awk -F: ‘{ print $1 }’);
SM_HOSTNAME=$(hostname);
[[ -f /etc/product ]] && SM_IMAGE=$(cat /etc/product | grep Image | awk ‘{ print $2 ” ” $3 }’) || SM_IMAGE=”NA”;
[[ -f /etc/product ]] && SM_IMAGE=${SM_IMAGE:-$(cat /etc/product | grep Dataset | awk ‘{ print $2 ” ” $3 }’)} || SM_IMAGE=”NA”;
[[ -f /etc/product ]] && SM_IMAGE=${SM_IMAGE:-NA} || SM_IMAGE=”NA”;
[[ -f /opt/local/etc/pkg_install.conf ]] && SM_PKGSRC=$(cat /opt/local/etc/pkg_install.conf | awk -F= ‘{ print $2 }’) || SM_PKGSRC=”Not installed”;
SM_BUILD=$(uname -v);
SM_NPROCS=$(kstat -p -n nprocs_zone_${SM_ID} -s usage | awk ‘{ print $2 }’);
SM_MEMCAP=$(kstat -p -c zone_caps -n lockedmem_zone_${SM_ID} -s value | awk ‘{print $2/1024/1024 }’);
SM_MEMUSED=$(prstat -Z -s rss 1 1 | awk -v zone=${SM_UUID} ‘$8 ~ zone { printf(“%d”, $4 ) }’);
SM_MEMFREE=$(echo “${SM_MEMCAP}-${SM_MEMUSED}” | bc);
SM_SWAPCAP=$(kstat -p -c zone_caps -n swapresv_zone_${SM_ID} -s value | awk ‘{ print $2/1024/1024 }’);
SM_SWAPUSED=$(kstat -p -c zone_caps -n swapresv_zone_${SM_ID} -s usage | awk ‘{ printf(“%d”, $2/1024/1024) }’);
SM_TMPUSED=$(du -hs /tmp | awk ‘{ print $1 }’);
SM_DISKQUOTA=$(df -h / | tail -1 | awk ‘{ print $2 }’);
SM_DISKUSED=$(df -P -h / | tail -1 | awk ‘{ print $5 }’);

cat << EOF SM UUID ${SM_UUID} SM ID ${SM_ID} Hostname ${SM_HOSTNAME} SmartOS build ${SM_BUILD} Image ${SM_IMAGE} Pkgsrc ${SM_PKGSRC} Processes ${SM_NPROCS} Memory (RSS) Cap ${SM_MEMCAP}M Memory (RSS) Used ${SM_MEMUSED}M Memory (RSS) Free ${SM_MEMFREE}M Swap Cap ${SM_SWAPCAP}M Swap Used ${SM_SWAPUSED}M /tmp Used ${SM_TMPUSED} Disk Quota ${SM_DISKQUOTA} % Disk Used ${SM_DISKUSED} EOF [/bash]

結構泥臭い事をやっているという印象と共に、なるほどこうやって各種情報が取得できるのだなあと実感します。

マシンのUUIDなんかは、zoneadm list -p | awk -F: '{ print $1 }' とすればKVSのような感覚で取得できる。
知ってればできるけど、知らなきゃどうすりゃいいのか全然分からない事のリファレンスにもなって一石二鳥な感じ。

SmartOS

テスト用とはいえ、httpやamqp等いくらかのデーモンを上げていてもMemory (RSS) Used:128Mぽっち。
このリソース効率の良さは上手く活用するとサービスプロバイダ、ユーザともに案外魅力があるものです。

よく見受けられるOSに使われているような感覚の環境構築ではなく、なるべくスマートに使いこなしたいですね。

Concrete5のプリティーURLにNginxを対応させる

最近Concrete5の動向が気になるので、適当なSmartOSにインストールして設定してみた。

で、リクエストアドレスから/index.php/を除外するプリティーURLという設定とnginxのお話。

.htaccessの設定例が表示されるがNginxには無意味だった

管理画面でプリティーURLを有効にすると、.htaccess用の設定が表示され、ファイルのパーミッションが適切ならば自動で作成もしてくれる。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>

...だが今回Nginxとphp-fpmを使っていたので.htaccessは無意味なファイルとなってしまう。

代わりにNginx用にコンフィグの生成を行った。

Nginx用のRewriteRule

/usr/local/concrete5/wwwrootに一式展開したとして、下記のように設定した。

root /usr/local/concrete5/wwwroot;
index index.php index.html;
location / {
  if (!-e $request_filename) {
    rewrite ^ /index.php last;
  }
}

location ~ .php$ {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SERVER_NAME $host;
    fastcgi_param SCRIPT_FILENAME /usr/local/concrete5/wwwroot$fastcgi_script_name;
}

location ~ /.ht {
    deny all;
}

一応解説、NginxのLocationディレクィブはマッチ条件により優先順が違うので、上記はそのまま評価順ではありません。

  1. request_filenameにあたるファイルがなければindex.phpにリライト
  2. phpファイルへのリクエストはfastcgiとしてphp-fpmへ
  3. /.htを含むリクエストは403

の3つを指定しました、元のRewriteCondの2つめ3つめはindexディレクティブが吸収して、ファイル存在チェックの時点でindex.(php|html)が付与されて考慮されるため必要はありません。

fastcgi_paramやHeaderは利用用途に応じて追加しましょう。

ZcloudのAPIでマシン作成

米JoyentのSmartDataCenterが使えるZ CloudではJSONベースのAPIを使えるようになっている。

ドキュメントはまだ一般公開されていないが機能利用はOK、使ってみます。

APIトークンをGETしよう

サインアップ後にアカウント管理画面を見ると、右上にAPIキーのコーナーがある。

z-api-token-2.jpg

APIキーの取得はこれでOK

作成可能なマシンの一覧を取得しよう

今回APIとのやり取りはGoogleChromeのエクステンション、POSTMANで行いました、使いやすいRESTクライアントです。

ヘッダにX-API-KEYを追加、先ほど取得したトークンを入れてリクエスト。

作成可能なリストは/products.json

https://my.z-cloud.jp/products.jsonで作成可能なデータセットとパッケージの一覧が取得できます。

zcloudapi2.jpg

※図ではmachines.jsonなので適宜必要なAPIのパスに変更する。

レスポンスのBodyはこんな感じ。

[
    {
        "category": "SmartOS",
        "created_at": "2012-12-17T17:12:51Z",
        "deleted_at": null,
        "disk": "30GB",
        "display_order": 1,
        "id": 137,
        "image_url": "/assets/smartos.png",
        "kind": "SmartOS",
        "memory": "1GB",
        "name": "SmartOS Small 1",
        "os": "SmartOS",
        "price": "8.1",
        "sdc_cpucap": 200,
        "sdc_dataset": "sdc:sdc:base64:1.8.4",
        "sdc_disk": 30720,
        "sdc_memory": 1024,
        "sdc_package": "Small_1GB",
        "sdc_vcpus": 1,
        "series": "SmartMachine",
        "subject": "Machine",
        "summary": "SmartOSはOpenSolarisベースの仮想OSで、高性能、堅牢、強力な分析機能が提供されます。",
        "trial_period": null,
        "updated_at": "2012-12-17T17:12:51Z",
        "vendor_url": "http://www.joyent.com/products/smartos/"
    }
]

実際は全ての組み合わせが出てくるので結構数が多いです。

マシンを作成しよう

マシンを作成するにはRESTよろしくmachinesリソースをcreateのためPOSTします、GETならマシン一覧が。

https://my.z-cloud.jp/machines.jsonにPOSTする内容は下記のようにデータセットとパッケージを指定したJSONです。

{
        "dataset": "sdc:sdc:base64:1.8.4",
        "package": "Small_1GB",
        "name": "testmachine01"
}

SmartDataCenterには応用として便利に使えるmetadataというパラメータがありますが、ここはひとまず省略して作成しましょう。

ヘッダのContent-TYpe: application/jsonをつけて、POST。 zcloudapi4.jpg

これで新しくマシンが1つ作成されました。

作成されたマシンのデータを取得

レスポンスのBodyにマシン情報が入ってます。

zcloudapi3.jpg

ちなみに単体の情報は/machines/{マシンID}.jsonで取得できます。

{
    "id": "3dedfab7-9704-481c-b994-f37db2252ff2",
    "name": "testmachine01",
    "type": "smartmachine",
    "state": "provisioning",
    "dataset": "sdc:sdc:base64:1.8.4",
    "memory": 1024,
    "disk": 30720,
    "ips": [
        "210.152.137.50"
    ],
    "metadata": {},
    "created": "2013-01-03T11:29:46+00:00",
    "updated": "2013-01-03T11:29:46+00:00",
    "account_id": 27,
    "os": "SmartOS",
    "kind": "SmartOS",
    "package": "Small_1GB",
    "subdomain": null,
    "alert": null
}

作成したマシンにログイン

とりあえずsshで。

zcloudapi04.jpg

だいぶ手軽にサーバの作成ができるようになっています。

応用編:user-script, user-data

マシンの作成や情報の更新ではSDCの機能Metadata APIが使えます、Joyent SmartDataCenterはこれを活用して色々やるようになっているのでそのうち紹介できればと思います。

Using the Metadata API >> http://wiki.joyent.com/wiki/display/sdc/Using+the+Metadata+API

Joyent SmartOSのSun_SSHでパスワード認証を無効にする

SmartOSのSSHデーモンはSun_SSH、設定は2つ必要だ。

smartos-blue

PasswordAuthentication no
KbdInteractiveAuthentication no

従来のSolarisで使われているPAMAuthenticationViaKbdIntは古いみたい、一応動くけど警告が出る。

PAMAuthenticationViaKbdInt has been deprecated. You should use KbdInteractiveAuthentication instead (which defaults to “yes”).

設定したらリスタート、コンフィグテストを忘れずにね。

# /usr/lib/ssh/sshd -t  # Only test configuration
# svcadm restart ssh

AWS EBS プロビジョンド IOPS ボリューム にベンチマーク

EBS プロビジョンド IOPS ボリュームは、EBS最適化インスタンスにアタッチすると、指定したIOPSの維持に努めてくれるボリュームだ。

http://aws.typepad.com/aws_japan/2012/11/ebs-volume-status-checks.html

想定のIOPSが出ているかどうかは標準のモニタリング機能でチェックでき、CloudWatchのメトリクスとして扱えるのでトリガもできる。

名前からしてなんとなく良さそう凄そう?という印象だけあったので特性を試してみたところ、文字通りの最適化であってコスト試算の精度向上なんかに役に立ちそうと分かった。

続きを読む AWS EBS プロビジョンド IOPS ボリューム にベンチマーク