Build Insiderオピニオン:花井志生(2)

Build Insiderオピニオン:花井志生(2)

自宅サーバーか、クラウドか ― 開発/テスト機の採用基準と最適なミックス

2016年5月17日

個人の開発/テスト機でもクラウド(調達)の方が安いといえるのだろうか? 自宅サーバー(所有)の方が割安なケースを考え、両者のメリットを生かす手法と実践手順の例を示す。

花井 志生
  • このエントリーをはてなブックマークに追加

 「クラウドを活用することでTCO(Total Cost of Ownership)の削減を」というのは、クラウド導入時のじょうとうであったが、最近はそういったセールストークより、柔軟な構成が可能なことや、必要に応じて瞬時にサーバーを調達できるといった点が評価されつつある。とはいえ、物理サーバーを自分で用意するよりもクラウドの方が安いという感覚は今でも健在であろう。

 今回は、開発者の方が誰しも個人的に所有していると思われる自分専用の開発/テスト機に焦点を当て、果たしてクラウドが安いのかどうかを検討してみたい。

自宅サーバーを置く場合の問題点

 今回検討する開発/テスト機には、例えば継続的統合(CI)のためのビルドサーバーや、あるいは新技術を一定期間評価してみるためのサーバー機を想定している。まずはこうしたサーバー機を自宅に置く場合の問題点を挙げてみたい。

固定IPアドレス

 現在多くのコンシューマー向けのISP(インターネット・サービス・プロバイダー)は、固定IPアドレスの提供をしていないか、あるいは提供していても高額なケースが多い。逆に固定IPアドレスの提供を売りにしているISPもあるが、速度があまり出ないなど、他の面で不利なケースが少なくない。このため自宅サーバーを置こうと思うと、その点だけでISP代金がかさんでしまったり、ISP選択の幅が狭まったりしてしまう。DDNS(ダイナミック・ドメイン・ネーム・システム)の活用なども考えられるが、IPアドレスの切り替えの手間など課題が多い。

電気代

 開発や評価に使用するサーバー機であれば、常に高負荷をかけるわけではないので、それほど多くの電力を使用するわけではないが、仮に平均で100Wと考えても、1カ月当たり2000円くらいかかる計算となる(26円/kwhとして、0.1×26×24×30=1872円)。

保守

 SSDが一般的になる前までは、自宅サーバーを持つ上での懸念の筆頭が、HDDのクラッシュであった。PC用のHDDは2年も連続稼働すれば壊れるため、RAIDを用いる必要がある。しかも「RAIDを用いれば問題は解決」という単純な話ではない。RAIDであろうとエラーは、そのセクターにアクセスしてみなければ検出できないからだ。このため長年アクセスしていなかったファイルが知らないうちに壊れていて、いざ取り出そうとしたら復旧不可能という憂き目に遭遇する可能性がある。

 業務であればテープやフラッシュメモリへの全セクターコピーを定期的に行うことになるが、自宅サーバーでこのような対策はおおだろう。RAID製品によってはScrubという機能があって、定期的に全セクターを読み出してエラーを検出してくれる。SSDになって、信頼性は大幅に上がったが、とはいえ絶対に壊れないというわけではない。自宅サーバーを置く場合は、こうした保守回りを自分で考えておかなければならない。

クラウド化で解決されること、解決されないこと

 自宅サーバーをクラウド化することで、上記の課題は解決されるのだろうか。一口にクラウドといっても、クラウドベンダーによって特性は異なる。例として、さくらのVPSを見てみよう。メモリ1GBytesでSSD 30GBytes、CPU 2Coreのプランだと月額972円(2016年5月現在、以下の金額表示については同様)となっている。これは上で試算した電気代と比較してみても驚異的である。もう1つの例として、Bluemixの料金を見てみよう。このページは料金計算ができるようになっているが、コンテナー(Docker)でメモリ512MBytes、固定のグローバルIPアドレス2つを選択した場合、無料と表示される(恐らくバーゲン価格なので、料金については常に最新の状況を確認してほしい)。なるほど確かに、これらを見るとクラウド化によってTCOが削減できるというのは間違いなさそうである。

 ここで注意が必要なのは、上記はいずれも(主にメモリやディスクサイズの面で)低スペックの環境であるという点である。例えばインメモリデータグリッドが使い物になるかどうか、ある程度、長期間試験運用してみるため32GBytesのメモリが搭載されたサーバー機が必要だとしよう(多くのクラウドでは、メモリ量とCPUコア数を独立して選択できないので、32GBytesメモリ量を実現できる最低のスペックで比較)。さくらのVPSでは月額3万240円となる。VPSでない、さくらのクラウドで試算すると、月額2万6892円となる。AWSでリザーブドインタンスを使った場合、r3.xlarge(RAM 30.5GBytes)で月額$152.57である。

 AWSの料金は一見、さくらより安く見えるが、AWSではネットワークトラフィックにも課金されるため。実際の請求額はこれよりも高くなるだろう。つまり、このクラスのクラウドを使おうと思うと月額料金は数万となってしまう。もしも2年間維持すれば総額は50万円前後となり、電気代を考えたとしてもハイエンドのPCを自宅に置く方が確実に安上がりとなるだろう。

 もちろんハイスペックサーバーなら常にクラウドが割高というわけではない。きちんと準備をした上で、2時間だけ大量の計算を実行したいという用途であれば、料金は2時間分だけで済むのでクラウドの方が圧倒的に安くて済むだろう。要は特性を考えて適所に使わないとクラウドといえど、かえって割高になってしまうということだ。

最適な「クラウド+自宅サーバー」ミックスを考える

 自宅サーバーとクラウドの強み・弱みが見えてきた。そもそもどちらかに統一する必要はない。最適なコストパフォーマンスを発揮できるような構成を考えてみよう。

クラウドをリバースプロキシにする

 図1はNginxのようなWebサーバーをリバースプロキシとして使用し、自宅サーバーでAPサーバーを稼働する構成例である。この構成では自宅サーバーでは苦手な固定IPアドレスの取得をクラウド側に任せ、クラウドでは割高になってしまうハイスペックサーバーを自宅側に任せることで特性に合わせたすみ分けを実現している。今回はこの構成を実現するための実装を考えてみよう。

図1 クラウド/自宅でサーバーをすみ分け
図1 クラウド/自宅でサーバーをすみ分け

リバースプロキシを構成する

 この構成で問題となるのは、自宅サーバー側に固定IPアドレスがないことだ。Nginxでリクエストを受けても、そのままでは自宅サーバー側にリクエストを転送できない。今回はSSHのリバースポートフォワードを用いて、これを解決することにする。図2はリバースプロキシの構成を詳細化したものである。

図2 リバースプロキシの構成

 autosshコマンドを自宅サーバー側で実行してリバースポートフォワードを用いることで、クラウド側のNginxから自宅サーバー側にリクエストを転送できるようにしている。autosshコマンドは、SSHで接続しつつ、エラーが起きた際には自動的に再接続が実施される。図2で指定しているオプションの意味は以下の通りである。

  • -f autosshコマンドをバックグラウンド実行する
  • -M0 古いポート監視のやり方を無効化する
  • -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" 監視方法の指定(1分に1回接続状態の調査。リトライを3回まで行う)
  • -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null Dockerでsshdを動かすと、コンテナー実行ごとにSSHサーバー側のホスト鍵が変わって確認を求められるため、それを回避する設定
  • -N SSHでリモートコマンドを実行できないようにする(ポート転送専用としてセキュリティを高める)
  • -R3000:localhost:8000 クラウド上でのポート3000へのアクセスを自宅PCのポート8000に転送する
  • -i /path/to/id_rsa 秘密鍵ファイル
  • nginx@cloud001 SSHの接続先

 HTTP/HTTPSポートへのアクセスを図3に示す。クラウド側のポート3000は、自宅サーバーのポート8000に転送されている。Nginxはあらかじめ(ポート80で受け取った)リクエストをポート3000に転送するように設定しておく。これによりクラウドのHTTP/HTTPSリクエストを自宅サーバー側で処理することが可能となる。

図3 クラウド側のポート3000へのHTTP/HTTPSリクエストは自宅サーバーのポート8000へ転送する

リバースプロキシを動かしてみる

 今回は無料で使用できるBluemixを用いてリバースプロキシを構成してみることにする。図2に示したクラウド側の構成はあらかじめDockerコンテナー上に実装し、docker hubコマンドでビルドしてある(イメージ名:「ruimo/reverse-proxy」)。Dockerfileはこちらに置いてある

1. キーペアの作成

 あらかじめssh-keygenコマンドを用いてキーペアを生成しておく。このときパスフレーズはなしにする。キーペアの生成の詳細については、ここでは割愛する。

2. ファイルの配置

 ディレクトリを作成して、以下のようにファイルを配置する。

authorized_keys
Dockerfile
nginx
  +-- conf.d
    +-- my.conf
配置するファイルの構造

 authorized_keysファイルは、1で生成した公開鍵の内容である(.pubという拡張子の付いたファイル)。

 Dockerfileファイルの内容は以下のように、ほぼ空である(必要な処理はベースにしているruimo/reverse-proxy内で実行される)。

FROM ruimo/reverse-proxy
MAINTAINER Shisei Hanai<ruimo.uno@gmail.com>
Dockerfileファイルの内容

 Nginxの設定ファイル(my.confファイル)にはNginxからAPサーバーへの転送設定を記述する(今回は、ポート3000に転送するようにしている)。

Nginx設定ファイル
server {
  listen 80 default_server;
  index index.html index.htm;
 
  location / {
    proxy_pass http://localhost:3000;
    proxy_set_header host $host;
  }
}
my.confファイルの内容
3. Dockerイメージのビルド/タグ付け/プッシュ

 docker buildコマンドを用いてイメージをビルドする(ruimoの部分は、Dockerでの自分のユーザー名としてほしい。以降同様)。

コンソール
$ docker build -t ruimo/my-reverse-proxy .
Dockerイメージのビルド

 Bluemixのプライベートリポジトリに上げるためにタグ付けを行う。ここでregistry.ng.bluemix.net/ruimo/my-reverse-proxy内のruimoの部分は、Bluemix上でのprivate dockerイメージレポジトリの名前空間名である(BluemixでのDockerの使用方法については以下の4を参照のこと)。

コンソール
$ docker tag ruimo/my-reverse-proxy registry.ng.bluemix.net/ruimo/my-reverse-proxy
Dockerイメージへのタグ付け

 Bluemixのプライベートリポジトリにpushする(なお、ここでauthentication errorが表示される場合は、cf ic loginコマンドを実行する。cfコマンドについては以下の4を参照のこと)。

コンソール
$ docker push registry.ng.bluemix.net/ruimo/my-reverse-proxy
Dockerイメージのプッシュ
4. Dockerイメージの実行

 Bluemix上で実行する。なおBluemixのcf icコマンドのセットアップについては、ここでは省略するので適宜(「BluemixでDockerを使う」などを参照して)設定しておいてほしい。

コンソール
$ cf ic run --name my-reverse-proxy -P -m 512 registry.ng.bluemix.net/ruimo/my-reverse-proxy
BluemixでのDockerイメージの実行
5. グローバルIPアドレスの取得とコンテナーへのバインド

 グローバルIPアドレスを取得する(以降の解説では、169.44.8.170の部分を、ここで得られたIPアドレスに読み替えてほしい)。

コンソール
$ cf ic ip request
OK
The IP address "169.44.8.170" was obtained.
グローバルIPアドレスの取得

 上で取得したグローバルIPアドレスを、4で実行したコンテナーにバインドする。

コンソール
$ if ic ip bind 169.44.8.170 my-reverse-proxy
グローバルIPアドレスのコンテナーへのバインド
6. アプリが開始されるまで待機

 cf ic psコマンドで、STATUSRunningになるまで待つ。

コンソール
$ cf ic ps -a
CONTAINER ID  IMAGE                                                  COMMAND  CREATED         STATUS                       PORTS                                                                        NAMES
a25a2b28-a68  registry.ng.bluemix.net/ruimo/my-reverse-proxy:latest  ""       55 seconds ago  Running 24 seconds ago   169.44.8.170:22->22/tcp, 169.44.8.170:80->80/tcp, 169.44.8.170:443->443/tcp  my-reverse-proxy
アプリの実行が始まるまで待機

cf ic psコマンドでSTATUSRunningになっているかを確認する(強調書体部分)。

7. 自宅サーバーからリバースプロキシへの接続の確認

 リバースプロキシ側が起動したので、自宅サーバーから接続する。今回は自宅サーバー側に、ポート8000で待ち受けるAPサーバーが存在すると仮定している。

 まず1で作成した秘密鍵を、自宅サーバー上に転送しておく。そしてchomdコマンドを用いて、ファイル属性を400に変更する(このファイルは他人から見えない場所に配置する。この処理専用にユーザーを作成するのがよい)。

コンソール
$ chmod 400 id_rsa
$ ls -l id_rsa
-r-------- 1 shanai shanai 1679  5月  6 15:46 id_rsa
秘密鍵ファイルのファイル属性の変更

 以下のコマンドを実行して、接続を確認する。

コンソール
$ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -N -g -R3000:localhost:8000 -i /path/to/id_rsa sshnginx@169.44.8.170
リバースプロキシへの接続の確認

 リバースプロキシ側ではNginxのリクエストをポート3000に転送するように設定し、自宅サーバー側のAPサーバーはポート8000をリッスンしているので、-R3000:localhost:8000を指定している(必要に応じて変更してほしい)。「/path/to/id_rsa」の部分には、上で配置した秘密鍵ファイルの場所を記述する。

 ここまでできれば、http://169.44.8.170にブラウザーでアクセスすることで、自宅サーバーのAPサーバーのコンテンツが見えるはずである。

8. 自宅サーバーの設定を変更

 動作が確認できたら、自宅サーバーでリバースプロキシとの接続を自動実行するようにしておく。簡単なのは、/etc/rc.localファイルに以下のように記述を追加することである。

コンソール
su - user -c "autossh -f -M0 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -N -R3000:localhost:8000 -i /path/to/id_rsa sshnginx@169.44.8.170"
/etc/rc.localファイルに追記する内容

 suコマンドに指定している「user」というのは、今回のポート転送を実行するため専用に作成したユーザーである。また、id_rsaファイルをchownコマンドを用いてこのユーザーの所有に変更しておくこと。

 Bluemixは現在のところ日本にリージョンがないため、応答速度が若干遅いが、今のところは無料でリバースプロキシを運用することが可能だ。Dockerを使用しているので、Docker対応したクラウドであれば、他のクラウドでも、今回の仕組みをほぼそのままで利用可能のはずだ。もちろんIaaSの場合は自分でDockerをインストールすれば利用可能だ。

 なお、クラウドによってはネットワーク転送に対して従量課金されるケースがあるので、今回のようにリバースプロキシとして利用するケースでは十分に注意してほしい。

まとめ

 クラウドを活用することで、一般にはコストが削減できるが、適用箇所によっては割高になってしまう場合がある。今回は開発/テスト機に焦点を当て、高スペックなサーバー機のみを自宅で稼働することでトータルの料金を抑える方法を紹介した。これは業務でも同様で、クラウドの特性と価格体系をよく理解した上で、適切なクラウド+オンプレのミックスを考えないと、割高になってしまうケースも出てくるだろう。

花井 志生(はない しせい)

花井 志生(はない しせい)

 

入社当時はC/C++を用いた組み込み機器(POS)用のアプリケーション開発に携わる。

10年ほどでサーバーサイドに移り、主にJavaを使用したWebアプリケーション開発に軸足を移す。

2015年夏からクラウドを用いたソリューションのテクニカル・コンサル、PoCを生業としている。

主な著書にJava、Ruby、C言語を用いたものがある。

 

1. Dockerでビルドを改善する

開発現場で役立つ記事や書籍を多数著している花井志生氏がオピニオンコラム初登場。今回は、コンテナー型の仮想実行環境「Docker」を使ってCIを行うことのメリットを考察。

2. 【現在、表示中】≫ 自宅サーバーか、クラウドか ― 開発/テスト機の採用基準と最適なミックス

個人の開発/テスト機でもクラウド(調達)の方が安いといえるのだろうか? 自宅サーバー(所有)の方が割安なケースを考え、両者のメリットを生かす手法と実践手順の例を示す。

3. 歳を取ってもエンジニアを続けられるのか

エンジニアが年を取るとはどんなことだろう。年を取ることのデメリットとメリット、加齢に対する心構えを筆者自身の経験を基に語ってくれた。

4. Mac の 良いところ、悪いところ

スタバでMacでドヤ顔ブームも一息ついた今、エンジニア目線であらためてMacの良いところ、悪いところを考えてみよう。

サイトからのお知らせ

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • グレープシティ株式会社
  • 日本マイクロソフト株式会社