まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2015/11

IDC フロンティア様が運営する IDCF クラウドが(今の形になって)1周年を迎えました。おめでとうございます!
IDCF クラウド1周年記念キャンペーン!
2015112700


私自身は(当時はノアクラウドとか呼ばれてたと思うけど・・・まだ残ってるよね?)以前から IDC フロンティア様のクラウド利用させていただいていたので「1周年」という感覚はあまりないのですが、代名詞※にもなった「ワンコイン(=月額500円)」でありながら一級品のネットワークバックボーンを備えたこの IDCF クラウドが個人のウェブサービス運用では手放せないくらい便利で、使わせていただいています。

「500円 クラウド」で検索すると、広告を抜いたトップは IDCF クラウドになってます。

なお、以前に私が別クラウドを使っていて、IDCF クラウドに乗り換えた時の様子は当時のブログエントリにしているので、そちらも参照ください:
IDCFクラウドに乗り換えました


で、この「ワンコイン」のインスタンスは、IDCF クラウド的には light.S1 と呼ばれるマシンタイプのものです。スペックは 0.8GHz の vCPU 1つ、メモリ 1GB(ここまで200円/月)、ディスク 15GB(300円/月)、これをCentOS などの無料 OS で運用すると 200 + 300 = 500円/月 というものです:
2015112701
2015112702


実際にインターネットに公開するサービスを作ろうとすると、パブリック IP アドレスが必要になります。パブリック IP アドレスは1つに付き 500円/月 ですが、アカウントに対して最初の1つ目(ソースアドレス)は無料で提供されます。なので1インスタンス月額500円運用が可能になります:
2015112703


さて、では2台目のインスタンスを同じスペックで作るとどうでしょう。インスタンス自体は 500円/月ですが、2つ目以降のパブリック IP アドレスは 500 円/月です。つまり2台目以降は1台につき 1000 円/月かかる、ということになります。。。

月500円くらいケチケチすんな! という声が聞こえてきそうですが、でも割合で言えば 500 か 1000 かは倍違います。3台目、4台目となった時にそれなりの差が出てきてしまいます。また IDCF 以外でも IP アドレス付きで1インスタンス500円前後で提供している所はあるので、比較した際に価格的な差も生じてしまいます。

そんな理由で愛する IDCF クラウドが不利になるのは納得できない!

というわけで、2台目以降の light.S1 インスタンスを 500 円で使ってみました(IDC フロンティア様が期待しているのはそういう使い方じゃないかも・・・)。

まずサーバー用途でなく、クローラー用途など、「外部からアクセスして利用するわけではない用途」のインスタンスであれば、そもそもパブリック IP アドレスを付与する必要はありません(あると直接ログインできて何かと便利だけど)。外部に公開する IP アドレスが不要な使い方であれば、プライベート IP アドレスだけで運用すれば月額 500 円です。

次にサーバー用途の場合、こちらが本題です。端的に言えば「ポートフォワーディングでなんとかする」という考え方です。2つ目以降のパブリック IP アドレスに料金がかかるならそこは使わず、1つ目の IP アドレスをうまい具合に流用して2台目以降のインスタンスでも使っちゃおう、というやり方です。多くの人にとっては今更感のある方法かもしれませんが、貴重な無料クーポンを効率よく使う IDCF といえばワンコインクラウド、を実践するための知恵です。

具体的にはこんな感じです。まず現状、light.S1 の仮想マシンが2台あるとします:
2015112704


この2台をそれぞれこんな感じで使えるようにしたい、とします:
1台目(dotnsf-neppico)2台目(dotnsf-misc)
目的接続ポート番号目的接続ポート番号
SSH22SSH10022
HTTP80HTTP1880
MySQL3306MQTT1883


要は1台目は一般的な LAMP サーバーで MySQL まで外部に公開。SSH もデフォルトの 22 番ポートで公開する、というものにします。一方2台目はちょっと目的が異なり、流行りの Node-RED 環境を用意しようとしています。外部に公開するポートは Node-RED サーバーのデフォルトである 1880 と、MQTT ブローカーの 1883、そしてこのサーバーにも SSH でアクセスできるようにしたいのですが、デフォルトの 22 番ポートだと1台目の SSH と衝突してしまうので、2台目の SSH には 10022 番を割り当てるものとしています。

実際には2台目のマシンで MySQL を動かして公開したり、1台目のマシンに別の HTTP を動かしたりすることもできますが、いずれのケースでもポート番号だけは衝突しないようにする必要があります(そしてその結果、デフォルト設定とは違う値を設定する必要が出てきます)。

この内容を IP アドレスの設定に反映させます。まずはファイアウォールの設定で開ける必要のある全ポート番号(上記例では 22(ssh), 80(http), 1880(http), 1883(mqtt), 3306(mysql), 10022(ssh) の6つ)を通すよう設定しておきます:
2015112705


次にポートフォワードの設定です。先程ファイアウォール設定で開けた各ポート毎に振り分け先を指定してあげます。その際、パブリックポートには開けたポート番号を、プライベートポートには実際に動いているポート番号を指定します。多くの場合は同じ数字(実際に動いているポート番号)を指定しますが、今回の例だと2台目の SSH だけは実際には 22 番ポートで動いている SSH に、ファイアウォールで開けた 10022 番ポートから繋がるよう設定する必要があります。そのため、パブリックポートを 10022 に、プライベートポートを 22 に指定しています:
2015112706


これで1つのパブリック IP アドレスを2台のマシンで共有する形で割り振ることができました。なお、実際に2台目のマシンに SSH でログインする場合は、ポート番号に 10022 を指定して接続する必要があります(デフォルトの 22 番だと1台目のマシンに繋がります):
2015112707


これで「2台目以降も 500 円の IDCF クラウド」になりました。

これからも遠慮無く使わせていただきます。よろしくおねがいします。

このエントリの続きです:
IBM IoT Foundation サービスへのデバイス登録方法

IBM IoT Foundation サービスを使うために、同サービスにデバイスを登録する方法を上記で紹介しました。では IBM IoT Foundation サービスに登録したデバイスのセンサーデータを Node-RED で集めるための方法を紹介します。


まずは上記手順の完了した IBM IoT Foundation サービスの環境変数を参照し、apiKey と apiToken の値を確認しておきます。これらの値は後に利用します:
2015112600


次に Node-RED のフローエディタを開き、IBMIoT インプットノードを1つ用意します:
2015112601


同ノードをダブルクリックして、属性を編集する画面に切り替えます:
2015112602


IBM IoT Foundation サービスを使う場合、Authentication は QuickStart ではなく、API Key にする必要があります。また API Key は "Mine" を選択、その他は以下のようにチェックボックスを付けます(名前も IBM IoTF に変更しています):
2015112603


API Key の横にある鉛筆マークをクリックしてノードの属性を確認します。ここではデバイスを追加した IBM IoT Foundation サービスの API Key と API Token(上記で確認したもの)が入っていることを確認してください(入っていなかったら入力してください):
2015112604


最後にこのノードにデバッグ output ノードを足して&繋いで、送られてきたデータが参照できるようにしておきます。この状態でデプロイしておきましょう:
2015112605


次に IoT Foundation サービスにに登録したデバイスから実際に MQTT メッセージをパブリッシュして、Node-RED のフローに送られたデータが表示されることを確認してみましょう。今回想定している環境ではこのようなデバイスを IoT Foundation サービスに登録していました:
属性属性値
組織IDttb8bh
デバイスタイプMyDevice
デバイスID(MACアドレス)112233445566
認証トークン(自分で指定する接続パスワード)K.Kimura777


このデバイスの場合、MQTT パブリッシャーとしては以下のような条件で IBM IoT Foundation サーバーにメッセージをパブリッシュすることになります:
設定項目設定値
MQTT ブローカーホストttb8bh.messaging.internetofthings.ibmcloud.com
(組織ID).messaging.internetofthings.ibmcloud.com
MQTT ブローカーポート1883
(固定値)
クライアントIDd:ttb8bh:MyDevice:112233445566
d:(組織ID):(デバイスタイプ):(デバイスID)
認証ユーザーIDuse-token-auth
(固定値)
認証パスワードK.Kimura777
(認証トークン)
トピックiot-2/evt/event_id/fmt/json
(固定値)
メッセージ{"d":{"a":"x","b":"y","c":"z"}}
(任意のJSONテキスト)


実際に動くデバイスがあれば、この内容でパブリッシュするようなコードを記述することでメッセージを送信することができます。ここでは MQTTLens を使って同じ動きをエミュレートして、動作を確認してみることにします。

まずコネクション画面では以下の様な内容でホスト名、クライアントID、ユーザー名、パスワードを指定して接続してください:
iotf08


実際にパブリッシュする際には、上記の Topic と JSON メッセージを指定してパブリッシュします:
iotf09


メッセージが正しく送信されれば、Node-RED 側の Debug タブに送信した JSON が表示されるはずです:
2015112601


期待通りに動きました。これで QuickStart を使わずに IBM IoT Foundation サーバーを使う方法が分かりました。QuickStart でなければ QOS = 1 の制約もなく、より自由度の高い MQTT ブローカー利用が可能になりますね。


(参考資料)
https://docs.internetofthings.ibmcloud.com/ja/messaging/mqtt.html
https://docs.internetofthings.ibmcloud.com/ja/messaging/devices.html


 

IBM BluemixIoT Foundation サービスにデバイスを登録する手順をまとめておきます:
2015112501


IBM IoT Foundation の QuickStart サービスを使うと、特定の1台のデバイスのデータを簡単に集めて Node-RED に送る、なんてことができるようになるのですが、QuickStart には QuickStart なりの制約(QOS=1のみ、とか)が存在したり、Bluemix サービスの中には IoT Foundation サービスにデバイスが登録されている前提で提供しているサービスもあったりするので、QuickStart で繋がればよい、というわけにはいかないケースもあります(さすがに本番サービスを QuickStart で、というケースは逆に珍しいと思うけど・・)。

というわけで、IoT Foundation サービスへのデバイス登録手順を以下に紹介します。なお、ここでは以下のような条件のデバイス1台を IoT Foundation サービスに登録するものとします。自分の手持ちのデバイスを登録する場合は適宜自分の環境のデータと読み替えてください:
属性属性値
デバイスタイプMyDevice
デバイスID(MACアドレス)112233445566
認証トークン(自分で指定する接続パスワード)K.Kimura777


まだ自分の Bluemix アプリケーションに IoT Foundation サービスをバインドしていない場合は Bluemix 上から IoT Foundation サービスを指定して追加&バインドします:
2015112502


Bluemix 上のアプリケーション概要から IoT Foundation サービスのアイコンをクリックします:
2015112503


IoT Foundation サービスの説明画面が表示されるので、「ダッシュボードの起動」と書かれたボタンをクリックして、IoT Foundation ダッシュボードに移動します:
2015112504


IoT Foundation ダッシュボード画面が表示されます。この時点で一意に割り振られた組織ID(下図では ttb8bh)が確認できます。この組織 ID は MQTT パブリッシャーからメッセージを送信する際に必要になるのでメモしておきましょう。 ではデバイスを登録してみます。デバイスタブから「デバイスの追加」ボタンをクリックします:
iotf01


まずは(QuickStart でも使った)デバイスタイプを指定します。今回は MyDevice というデバイスタイプを指定します。初めてこのデバイスタイプを指定する場合は「デバイス・タイプの作成」ボタンから、以前に作ったことがあればセレクションボックスの選択肢から選んで、MyDevice デバイスタイプを指定します:
iotf02


次にデバイス ID を指定します。今回の例では 112233445566 というデバイス ID を指定します(ここにはネットワーク上で一意な ID を指定するので、一般的には MAC アドレスを指定します):
iotf03


次にセキュリティの認証トークン(パスワード)を指定します。自動生成することも、自分で指定することもできますが、この値は一度作ってしまうと後から変更できず、また後から参照することもできなくなるため、メモするなり、絶対に忘れないようにするなり、注意が必要です。今回は自分で認証トークン K.Kimura777 を指定することにします:
iotf04


追加するデバイスの内容確認画面が表示されます:
iotf05


デバイスを登録すると、資格情報が表示されます。この画面(特に認証トークン情報)は二度と見ることができないため、絶対に忘れないようにしましょう(忘れてしまった場合は一度デバイスを削除し、登録し直してください):
iotf06


改めて IoT Foundation ダッシュボードに戻ると、いま登録したデバイスがデバイス一覧に追加されているはずです。2台以上のデバイスを登録する場合は、上記の手順を繰り返してください:
iotf07


ちなみに、こうして登録したデバイスから IoT Foundation に対して JSON メッセージを送信(パブリッシュ)する場合、以下の内容を指定して MQTT パブリッシュを実行することになります:
項目指定する値
MQTTブローカーホストttb8bh.messaging.internetofthings.ibmcloud.com
(組織ID).messaging.internetofthings.ibmcloud.com
MQTTブローカーポート番号1883
(固定値)
クライアントIDd:ttb8bh:MyDevice:112233445566
d:(組織ID):(デバイスタイプ):(デバイスID)
認証ユーザー名use-token-auth
(固定値)
認証パスワードK.Kimura777
(認証トークンの値)
トピックiot-2/evt/event_id/fmt/json
evnet_id 部分は任意文字列


 

CentOS デスクトップ計画に不可欠な要素として、やはり動画視聴があります。CentOS で動画を観るには Totem というメディアプレイヤーアプリがあるのですが、これをそのまま入れても非対応のコーデックが多く(例えばそのまま普通に導入すると MP4 や WMV は観れない)、色々不便です。

というわけで「デコーダーも入れて MP4 なども見れる Totem の導入方法」を紹介します。

まず、既に Totem を導入済みの場合は手順の途中で衝突が生じてしまって邪魔なので、一度 Totem を削除しておきます:
# yum remove totem

改めて Totem を導入するのですが、今回は RPMforge の YUM リポジトリを使います。というわけで、まずは RPMforge の GPG キーを導入します:
# cd /tmp
# wget http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt
# rpm --import RPM-GPG-KEY.dag.txt

次に RPMforge の yum.repo ファイルを用意します。vi などで /etc/yum.repos.d/rpmforge.repo ファイルを新規に以下の内容で作成して保存します:
# vi /etc/yum.repos.d/rpmforge.repo

[rpmforge]
name=RPMforge RPM repository for Red Hat Enterprise Linux
baseurl=http://ftp.riken.jp/Linux/dag/redhat/el6/en/$basearch/rpmforge/
gpgcheck=1
enabled=0

これで RPMforge リポジトリが使えるようになったので、RPMforge リポジトリからデコーダーなどをまとめてインストールします:
# yum --enablerepo=rpmforge install gstreamer gstreamer-plugins-good gstreamer-plugins-bad gstreamer-plugins-ugly gstreamer-ffmpeg libdvdread libdvdnav lsdvd

最後に RPMforge リポジトリから Totem をインストール:
# yum -y install --enablerepo=rpmforge totem

これで CentOS の GNOME デスクトップの「サウンドとビデオ」メニューから「動画プレイヤー」という名前で Totem がインストールされました:

2015111801


試しに MP4 ファイルを指定して開いても問題なく観れます:
2015111801


これで動画視聴についても CentOS で出来ない理由はなくなりました!

日本時間の 2015/Nov/17 に IBM Bluemix 内に Globalization Pipeline サービスがベータリリースされました:
2015111701


このサービスはアプリケーションの国際化を促進するための機能を提供しています。具体的には特定言語で記述された文字リソースファイルを元に他言語翻訳した文字リソースファイルを生成してくれます。

具体的な使い方を以下で説明します。まずは翻訳元になる文字リソースファイルを用意します。この例では Java 言語でよく使われる .properties 形式の英語リソースファイル(resource.properties)を用意しました。このリソースを元にして英語以外の文字リソースを生成してみます:
common.body.dndavailable=Drag & Drop to change location.
common.body.htmltagavailable=Some HTML tags(ex. <br/>(=new line)) are available.
common.body.update=Information Updated.
common.body.updatelatlng=Geo Information Updated.
common.body.clickfordetail=Click for detail page.
common.body.clickdescformap=Click underlined description for map.
common.body.notactivated=(This image is not visible to other. Go Edit page to activate.)
common.body.activate=Activate
common.body.twitterlinkmsg='s twitter profile.
common.body.fordeveloper=For Developer
common.body.apidownload=Download ManholeMap API here
common.body.iphoneapplink=Download iPhone App.
common.body.apiziplastmodified=Last Modified
common.body.logintoseefaceicon=Sign in with Twitter to see face icon
common.body.nomsiesupported=MSIE not supported in this site.
common.body.imgoftoday=Manhole of Today
:

まず Bluemix 上に Globalization Pipeline サービスを生成します。ランタイムにバインドしてもしなくても構いません:
2015111701


Bluemix のダッシュボード画面などから生成したサービスを選びます:
2015111702


Globalization Pipeline サービスの画面が表示されます。最初は「概要」タブの内容が表示されているはずです。ここでは新規にリソースバンドルを定義するので、「新規バンドル」ボタンをクリックします:
2015111702


新規バンドルの定義画面になったらバンドルID(バンドルごとにつけるユニークな名称、以下の例では ManholeBundle)、翻訳元リソースファイルの言語(今回は英語リソースから翻訳するので英語)、「参照」ボタンをクリックして、翻訳元リソースファイルを指定し、そのファイルフォーマット(今回は Java の Properties ファイル形式)を指定します。そして翻訳先言語を指定するために「追加」をクリックします:
2015111703


今回は翻訳元のリソースファイルが英語で、その翻訳結果として「フランス語」、「日本語」、「韓国語」をチェックしました。実際に必要な翻訳結果を必要なだけ指定してください。
2015111704


自分が必要な翻訳言語が全て選択されていることを確認して「保存」ボタンをクリックします:
2015111705


しばらく処理が行われた後、画面は「バンドル」タブに切り替わります。成功していると「正常に保存されました」をいうメッセージが表示され、その下に自分が指定した翻訳元のバンドル ID が表示されています。処理結果を確認するため、「操作」と書かれた箇所の目のアイコンをクリックします:
2015111706


すると翻訳先として指定した言語ごとに翻訳結果が表示されています。この例では3つの言語それぞれで16箇所のリソース翻訳が行われ、全て成功していることがわかります。では日本語の翻訳結果を確認してみましょう。日本語と書かれた行の目のアイコンをクリックします:
2015111707


日本語リソースの翻訳結果が表示されます。ざっと見て翻訳結果が正しそうかどうかが分かります。翻訳結果として手で修正したい場合は、修正したい文字列の右にあるペンアイコンをクリックします:
2015111708


すると翻訳結果を編集できるダイアログがポップアップ表示されます。この中で翻訳を変更し、「更新」ボタンをクリックすると翻訳結果を上書きできます:
2015111709


改めて一覧で翻訳結果を確認します。編集が必要な箇所があれば上記手順で修正し、特に問題がなくなったら「ダウンロード」ボタンでこのリソースファイルをダウンロードしてみましょう:
2015111710


日本語リソースのダウンロード方法を確認するダイアログがポップアップ表示されます。ここではダウンロードファイルのフォーマットを指定しますが、今回は Java Properties ファイルを元に作ったので、翻訳結果も Java Properties ファイルにチェックして「ダウンロード」ボタンをクリックします:
2015111711


すると、(バンドルID)_(言語).properties というファイル名でダウンロードが開始されます:
2015111712


このダウンロード結果を改めてテキストエディタで開くとこのような結果になっていることが分かります。日本語部分が正しく数値参照文字列になっていることがわかります。この形式であればそのまま日本語プロパティファイルとして使えそうです:
#Generated by IBM Globalization
#Tue Nov 17 14:19:17 UTC 2015
common.body.nomsiesupported=MSIE\u306F\u3053\u306E\u30B5\u30A4\u30C8\u3067\u652F\u3048\u3089\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002
common.body.update=\u60C5\u5831\u306F\u66F4\u65B0\u3057\u307E\u3057\u305F\u3002
common.body.iphoneapplink=iPhone\u9069\u7528\u6027\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002
common.body.apiziplastmodified=\u6700\u7D42\u5909\u66F4\u65E5
common.body.apidownload=ManholeMap API \u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9
common.body.fordeveloper=\u958B\u767A\u8005\u306E\u305F\u3081\u306B
common.body.dndavailable=\u30C9\u30E9\u30C3\u30B0\u30FB\u30A2\u30F3\u30C9\u30FB\u30C9\u30ED\u30C3\u30D7\u3057\u3066\u5834\u6240\u3092\u5909\u3048\u3066\u4E0B\u3055\u3044\u3002
common.body.twitterlinkmsg=\u3055\u3048\u305A\u308A\u304C\u3001\u624B\u77ED\u306B\u8A18\u8FF0\u3059\u308B\u3068\u3044\u3046\u3053\u3068\u3067\u3059\u3002
common.body.clickdescformap=\u5730\u56F3\u306B\u306F\u4E0B\u7DDA\u3092\u3072\u304B\u308C\u305F\u8A18\u8FF0\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
common.body.imgoftoday=\u4ECA\u65E5\u306E\u30DE\u30F3\u30DB\u30FC\u30EB
common.body.notactivated=(\u3053\u306E\u30A4\u30E1\u30FC\u30B8\u306F\u3001\u305D\u306E\u4ED6\u3067\u898B\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093\u3002\u6D3B\u52D5\u7684\u306B\u3059\u308B\u3079\u304D\u30DA\u30FC\u30B8\u3092\u7DE8\u96C6\u3057\u306B\u884C\u3063\u3066\u4E0B\u3055\u3044\u3002)
common.body.updatelatlng=\u5165\u308A\u6C5F\u60C5\u5831\u306F\u66F4\u65B0\u3057\u307E\u3057\u305F\u3002
common.body.htmltagavailable=\u3042\u308BHTML\u306F\u30BF\u30B0\u3092\u3064\u3051\u307E\u3059(ex\u3002<br/>(\=new\u7DDA))\u306F\u5229\u7528\u3067\u304D\u307E\u3059\u3002
common.body.logintoseefaceicon=\u3055\u3048\u305A\u308A\u3067\u767B\u9332\u3057\u3066\u9854\u30A2\u30A4\u30B3\u30F3\u3092\u898B\u3066\u4E0B\u3055\u3044
common.body.activate=\u6D3B\u52D5\u7684\u306B\u3057\u3066\u4E0B\u3055\u3044
common.body.clickfordetail=\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u3068\u7D30\u90E8\u30DA\u30FC\u30B8\u306B\u306A\u308A\u307E\u3059\u3002
  :


同様にして、フランス語と韓国語の翻訳結果も確認できます。必要であれば同様に編集して、同様にダウンロード可能です:
2015111713

2015111714


確かにアプリケーションの国際化では翻訳が面倒だし、同じ処理を色んな言語に対して行わないと行けないという点は不便でした。こういったリソースファイル特化の翻訳サービスは多言語対応のアプリケーション開発を行う上では便利です。

このページのトップヘ