2015年12月13日日曜日

【Microsoft Azure】Azure Media Services の配信をサイトに埋め込む

Azure Media Services(以下AMS)は、簡単に言うと動画配信プラットフォームです。
オンデマンドやストリーミングを手軽にできます。
https://azure.microsoft.com/ja-jp/services/media-services/

AMSの設定などはいろんな方が書いてる?ようですので、
実際にハマったプレイヤーをHTMLに埋め込むところを説明してみようと思います。

HTML5で見ることができる Azure Media Player(以下AMP)は、タグを埋め込むだけで設置完了です。
こんな感じですね。


<!DOCTYPE html>
<html>
<head>
<link href="//amp.azure.net/libs/amp/latest/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet"></link>
<script src="//amp.azure.net/libs/amp/latest/azuremediaplayer.min.js"></script>
</head>
<body>
<video id="vid1" class="azuremediaplayer amp-default-skin" autoplay controls width="640" height="400"
 data-setup='{ "logo": { "enabled": false }, "nativeControlsForTouch": false, "techOrder": ["azureHtml5JS","html5","silverlightSS","flashSS"]}'>
<source src="ストリーミング開始時に発行されたURL" type="application/vnd.ms-sstr+xml"></source>
<div class="amp-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
</div>
</video>
</body>
</html>


詳しいドキュメントはこちらです。
https://amp.azure.net/libs/amp/latest/docs/

クライアントごとの対応は基本的にはJSで行われるのですが、今回実際に問題が発生した箇所があったので、簡単な回避策を。

問題点:"azureHtml5JS"(DASH)でのストリーミング配信がiPadだけで見れない
原因:おそらくiPadだけDASHのコードがうまく動かない。なおiPhoneはOK
対応:iPadだけtechOrderを出力しない(そうすると"html5"が優先になる)

HTMLを分けるのが一番早いので、例えばPHPなら以下のようにtechOrderの出力を分岐します。


<!DOCTYPE html>
<html>
<head>
<link href="//amp.azure.net/libs/amp/latest/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet"></link>
<script src="//amp.azure.net/libs/amp/latest/azuremediaplayer.min.js"></script>
</head>
<body>
<video id="vid1" class="azuremediaplayer amp-default-skin" autoplay controls width="640" height="400"
 data-setup='{ "logo": { "enabled": false }, "nativeControlsForTouch": false, "
<?php
$ua = mb_strtolower($_SERVER['HTTP_USER_AGENT’]);
if (strpos($us, ‘iPad’) === false) {
  echo ‘,"techOrder":["azureHtml5JS”,”html5","silverlightSS","flashSS”]’;
}
?>
}'>
<source src="ストリーミング開始時に発行されたURL" type="application/vnd.ms-sstr+xml"></source>
<div class="amp-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
</div>
</video>
</body>
</html>



他のクライアントでも同様に対応できるのではないかと思います。


2015年12月6日日曜日

【Microsoft Azure】Azure Security Center がプレビューになったので設定した

Azure Security Center(以下Security Center)は、利用しているAzureリソースのセキュリティの脅威を通知、可視化して解決するためのサービスといったところでしょうか。
詳しくは以下の2つのリンクをどうぞ。

Azure Security Center now available
https://azure.microsoft.com/en-us/blog/azure-security-center-now-available/?mkt_tok=3RkMMJWWfF9wsRoiv6nJeu%2FhmjTEU5z16u8sWKe0g4kz2EFye%2BLIHETpodcMTcFlNb3GRw8FHZNpywVWM8TILdUXt9JsLgzhAGk%3D

Security Center
https://azure.microsoft.com/ja-jp/services/security-center/

先ごろ更新されたポータルから利用することができますので、簡単な手順を説明します。

まず、メニューから「Security Center」を選択します。


選択すると、Security Center が表示されます。
ここで脅威やアラートをグラフや一覧で見ることができます。
最初にSecurity Centerにアクセスすると、有効にするために以下の画面になります。

有効になると、こうなります。
右上の赤い円が、対応したほうが良い脅威を表しています。
赤はHighレベルのアラートです。

「Recommendations」(右上の円)をクリックすると、一覧が表示されます。
初回は、仮想マシンなどの情報を収集するためのストレージなどの設定がされていないため、まずはこれを対応してみます。

「Enable data collection」をクリックします。
サブスクリプションを選択します。

データ収集の設定を保存して終了します。
「Collect data from virtual machines」をOnにしてストレージを選択すればOKです。

設定が終わると、以下のように表示が変わります。
オレンジ色の円は、Mediumの脅威があることを示しています。

視覚的に確認しながら対応できるのは大変便利だと思いますので、ぜひ使ってみてフィードバックしてみましょう。




















今更ながら、IoTの話をしよう

IoTが何なのかあらゆるところで語られているし、そもそもの概念が今更って感じなのですが、今年は特に大きく変化したと思われるので敢えて話してみようか。

そもそも、「Internet of Things」を「モノのインターネット」と訳したことが惜しい。
これは「あらゆるモノ・コトがインターネットにつながる」ことを上手に表現できてない。

人間に例えて図示してみるとこうなる。

1.情報を捉えて(センサー)
2. 情報をクラウドに伝達して(インターネット)
3. 情報を処理して(クラウド+機械学習)
4. その情報を元に次のアクションをオーダーして
5. 実行する

…というのが簡単な説明。

ここで、それぞれをマッピングするとこうなる。

1.入力センサー(情報家電は内部でこれらを内包してると考えられる)
Arduino、RaspberryPi、mbedなどと繋がったセンサー群

2.ネットワーク接続できるもの(現在では主に無線)
Wi-Fi、BluetoothLEなどのネットワークに接続できて、情報をクラウドへ送ることができる

3.クラウド+機械学習など
MicrosoftAzure、AmazonAWSなどの大量の情報を受け取り、大量に解析、処理を行う

4と5.処理結果に基づくアクションとその実行
発注処理とかリコメンド、動作の変更、故障箇所の処理など

以前IPv6を推進する意見の中に、すべてのデバイスをインターネットに繋げるためにはIPv4では足りない(当たり前だが)というものがあったが、そこからは一歩先に進んでいる。

現状気になることは、各ベンダーが「総合的かつ一元的」にIoTサービスを提供しようとしている流れである。
メリットは、すべてがプログラマブルであるが故、共通の開発環境、開発言語ですべてに対応できるところだろう。
デメリットは(ここが重要だが)、本来別々のものであるそれぞれのコンポーネントを、自由に選択し実装できる部分が少ないように見えることだ。

近いうちに、.NETを使わないAzure IoTについて解説しようと思うけれども、選択の自由がエンハンスの一歩じゃないかと思うのだ。





2015年9月30日水曜日

【Microsoft Azure】BootDiagnostics(起動時の診断)を使って起動しないCentOS6のトラブルを解決してみる

今までAzureで一番(ほんとならふたつみっつあるけど)困ってたことは、起動してからログに書くまでのエラーで立ち上がらないLinux仮想マシンの問題である!

過去にCentOS6が起動しなくなったり(SCSIドライバの問題だが完全には解決してないし)、yumでアップデートしたら起動しなくなったり。

いろいろ苦労してましたが、先日機能追加されたBootDiagnosticsで起動時のログがPreviewポータルから見れるようになりまして。
https://azure.microsoft.com/en-us/blog/boot-diagnostics-for-virtual-machines-v2/

ここでは仮想マシンV2じゃないとできないような書き方ですが、仮想マシン(クラシック)でも、仮想マシンの「診断」で「Boot diagnostics」にチェックを入れて有効にすると使えます。(何度か設定が保存できなかったりしましたが...)

再起動すると、以下のように起動時のログを見ることができます。


今まで起動しなかった仮想マシンを起動すると、こんなメッセージが出ました。
ちなみに、この問題はSELinuxがらみのようです。下記のブログにありました。
http://stackoverflow.com/questions/12867591/how-to-solve-kernel-panic-not-syncing-attempted-to-kill-init-without-er

私の場合は、他のマシンでディスクをマウントして、一旦kernelをダウングレード(/etc/grub.confを編集)から起動することで対応しましたが、これでかなりまともなデバッグができるのではないかと思います。

なお、Linux仮想マシンのエージェントをちょっと設定すると、起動時のログのみならずシリアルコンソール経由で画面のログを見ることができます。
https://azure.microsoft.com/ja-jp/documentation/articles/virtual-machines-linux-agent-user-guide/

このサイトの記事を参考に、管理者権限で以下のコマンドを実行すると再起動後から有効になります。
# waagent -install
# waagent -serialconsole






2015年9月19日土曜日

【Microsoft Azure】通知ハブのObjective-Cサンプルがそのまま動作しないので指摘してみる

Objective-Cはすっかり忘却の彼方にあったのですが、ふとしたことで触って気がついたのでメモ。

まずはこちら、Azureの通知ハブの使い方。
https://azure.microsoft.com/ja-jp/documentation/articles/notification-hubs-ios-get-started/

結構細かく書いていて、コピペでもイケるんじゃないかと思わせる。
ただ、問題点が2つある。さらに、Xcode7+iOS9でもうひとつ。

1.認証エラーになる
正直なところ「ここでエラーになるのか」と思うのだが、401エラーなのでしょうがない。
「通知を送信する」の段落にある6のコード。SAS認証トークン作成部分。
// Construct authorization token string
        token = [NSString stringWithFormat:@"SharedAccessSignature sr=%@&sig=%@&se=%qu&skn=%@",
            targetUri, signature, expires, HubSasKeyName];
どうもここのパラメーターの並び順が違うようです。
srを一番最後にします。
// Construct authorization token string
        token = [NSString stringWithFormat:@"SharedAccessSignature sig=%@&se=%qu&skn=%@&sr=%@",
            signature, expires, HubSasKeyName, targetUri];
正直謎です...

2.正常な場合のHTTPの応答コード
次はREST APIのメソッド、APNSネイティブ通知の送信です。
https://msdn.microsoft.com/ja-jp/library/azure/dn223266.aspx
ここにある正常な応答コードは「200」と書かれていますが、どうも「201」のようです。
同じく「通知を送信する」の段落にある7のコード。
    // Send the REST request
    NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
    {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
        if (error || httpResponse.statusCode != 200)
        {
            NSLog(@"\nError status: %d\nError: %@", httpResponse.statusCode, error);
        }
        if (data != NULL)
        {
            xmlParser = [[NSXMLParser alloc] initWithData:data];
            [xmlParser setDelegate:self];
            [xmlParser parse];
        }
    }];
この中の「httpResponse.statusCode != 200」が「201」になるわけです。
    // Send the REST request
    NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
    {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
        if (error || httpResponse.statusCode != 201)
        {
            NSLog(@"\nError status: %d\nError: %@", httpResponse.statusCode, error);
        }
        if (data != NULL)
        {
            xmlParser = [[NSXMLParser alloc] initWithData:data];
            [xmlParser setDelegate:self];
            [xmlParser parse];
        }
    }];
なお、通知ハブのPythonでのチュートリアルでは「201」になっているので、これが正しいんでしょうね。
https://azure.microsoft.com/ja-jp/documentation/articles/notification-hubs-python-backend-how-to/

3.Xcode7から「Enable Bitcode」がデフォルトでYESに
Bitcodeについて調べるとこちらの方がXcode7でのコンパイル方法をブログで解説しています。(助かりました!)
http://qiita.com/Takumi_Mori/items/ace01198c43c8bac6df0
WindowsAzureMessaging.frameworkが「ENABLE_BITCODE」のオプションに対応した形式でビルドされていないので、Xcodeの「Build Settings」の「Build Options」の「Enable Bitcode」をNOにしてね、ってことです。

それよりも、サンプルをswiftにしていただきたい、今日この頃です。



2015年9月14日月曜日

【Microsoft Azure】SQLサーバー/SQL Databaseへ接続するSQLCMDとBCPをCentOSにインストールする

以前FreeTDSを使ってLinuxからSQL Databaseへの接続を試みましたが、今度はMicrosoftが提供しているSQLCMDから接続してみたいと思います。

なお、Ubuntuの手順はここに書いてあります。
http://blogs.msdn.com/b/joseph_idzioreks_blog/archive/2015/09/13/sql-server-sqlcmd-and-bcp-on-ubuntu-linux.aspx

もちろん、CentOSから挑戦します。
今回は6.7に導入してみますが、7系もほぼ同様かと思います。

まず、Cコンパイラとライブラリをインストールします。
# yum -y install gcc
yum -y install libssl glibc

次は、unixODBCをソースからインストールします。
RPMだと2.2系が入りますが、今回必要なのは2.3系です。
最後に、ライブラリのシンボリックリンクを作っておきます。
wget ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.0.tar.gz
# tar zxvf unixODBC-2.3.0.tar.gz 
cd unixODBC-2.3.0
# ./configure --disable-gui --disable-drivers --enable-iconv --with-iconv-char-enc=UTF8 --with-iconv-ucode-enc=UTF16LE
make
# make install
ln -s /usr/local/lib/libodbcinst.so.1 /lib/libodbcinst.so.1
ln -s /usr/local/lib/libodbc.so.1 /lib/libodbc.so.1
ldconfig

さて、SQLCMDとBCPのインストールです。
lddで依存するライブラリがあるか確認してからインストールします。
wget http://download.microsoft.com/download/B/C/D/BCDD264C-7517-4B7D-8159-C99FC5535680/RedHat5/msodbcsql-11.0.2270.0.tar.gz
# tar zxvf msodbcsql-11.0.2270.0.tar.gz 
# cd msodbcsql-11.0.2270.0/lib64/
# ldd ./libmsodbcsql-11.0.so.2270.0 
ldd: warning: you do not have execution permission for `lib64/libmsodbcsql-11.0.so.2270.0'
linux-vdso.so.1 =>  (0x00007ffc16a5e000)
libcrypto.so.6 => /usr/lib64/libcrypto.so.6 (0x00007ffa831d3000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007ffa82fcf000)
librt.so.1 => /lib64/librt.so.1 (0x00007ffa82dc6000)
libssl.so.6 => /usr/lib64/libssl.so.6 (0x00007ffa82b77000)
libuuid.so.1 => /lib64/libuuid.so.1 (0x00007ffa82973000)
libodbcinst.so.1 => /lib/libodbcinst.so.1 (0x00007ffa8275b000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007ffa82474000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007ffa82230000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ffa81f29000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffa81ca5000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffa81a8f000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffa81871000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffa814dd000)
libz.so.1 => /lib64/libz.so.1 (0x00007ffa812c7000)
/lib64/ld-linux-x86-64.so.2 (0x0000003093c00000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007ffa810c2000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007ffa80e96000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007ffa80c8b000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007ffa80a87000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007ffa8086d000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007ffa8064d000)
# cd ..
# ./install.sh install --force

インストールが終わったら、SQLCMDとBCPコマンドの動作を確認します。
# sqlcmd -S xxxx.database.windows.net -U ユーザー名 -P パスワード
1> Select @@version;
2> go
                                                                                                                                                                                                                                                                                                            
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Azure (RTM) - 12.0.2000.8 
Sep  2 2015 20:51:51 
Copyright (c) Microsoft Corporation
                                                                                                                                                                                                       

(1 rows affected)
1> exit
# bcp
usage: bcp {dbtable | query} {in | out | queryout | format} datafile
  [-m maxerrors]            [-f formatfile]          [-e errfile]
  [-F firstrow]             [-L lastrow]             [-b batchsize]
  [-n native type]          [-c character type]      [-w wide character type]
  [-N keep non-text native] [-q quoted identifier]
  [-t field terminator]     [-r row terminator]
  [-a packetsize]           [-K application intent]
  [-S server name or DSN if -D provided]             [-D treat -S as DSN]
  [-U username]             [-P password]
  [-T trusted connection]   [-v version]             [-R regional enable]
  [-k keep null values]     [-E keep identity values]
  [-h "load hints"]         [-d database name]

大雑把ですが、CentOSでもUbuntu同様に動かすことができました。





2015年8月26日水曜日

【Microsoft Azure】RaspberryPi(Raspbian)からPythonでEventHubsを経由してSQLDatabaseへデータを保存してみる

IoTな機器からデータを収集するのにEventHubsを使ってようと思います。
ただし、Windows10 IoT Coreではなく、もちろんLinuxからです。

今回は、RaspbianからPythonスクリプトでEventHubsへデータを登録します。

まず、Raspbianの実行環境を設定します。
管理者権限で、python-pipをインストールします。
その後、pipを使ってAzureSDKをインストールします。
# apt-get install python-pip
# pip install azure

次は、SQL Database の準備です。
今回は、testデータベースを作成し、以下のCreateTable文でテーブルを作成しました。
create table Test (
  id int identity(1,1) not null primary key,
  insert_date datetime2 default getutcdate() not null,
  test varchar(256)
);

クラシックポータルから、ServiceBusを作成します。
まずは名前空間を作成します。
名前空間名は「pythontest」、地域は「米国中南部」(個人的な都合なので使えるところならどこでも)にします。

次はイベントハブの作成です。
左下の「新規」を押して作成します。
イベントハブ名は「testhub」、地域は「米国中南部」(名前空間と合わせます)、名前空間は先ほど作った「pythontest」とします。

作成したイベントハブに、共有アクセスポリシーを追加します。
今回は名前に「writer」、アクセス許可に「送信、リッスン」を設定して保存します。




接続に必要な情報は、共有アクセスポリシーの名前「writer」、プライマリーキー、イベントハブ名、名前空間名です。

ここまで出来たら、EventHubsとSQLDatabaseを繋ぐためのStreamAnalyticsを作成します。
ジョブ名を「teststream」、地域は「South Central US」(名前空間に合わせます)に設定します。

作成したジョブの「入力」タブを見ると何もないので作成します。

データストリームを選んだ状態で次へ。


 イベントハブを選んだ状態で次へ。

入力に割り当てるイベントハブの設定です。
入力のエイリアスに「input」、名前空間は「pythontest」を選択、EVENTHUBは「testhub」(名前空間を設定すると自動的に選択されてる)、イベントハブポリシーを「writer」にして次へ。

シリアル化の設定はひとまずJSONで。

入力が設定できたので、次は「クエリ」タブを選択し、クエリの設定をします。
ここでは、ひとまず「SELECT input.test FROM input」としておきます。


「出力」タブに移動して、出力を作成します。
まずは出力先を「SQL Database」にします。

出力先のデータベースの情報を環境に合わせて設定します。
テーブルは、最初に作成した「test」とします。


長々と説明しましたが、これでイベントハブからSQLDatabaseまでの設定が終わりました。

次は、Pythonスクリプトです。
名前空間名、イベントハブ、共有イベントポリシー名、アクセスキーを設定して接続、値の送信を行います。
$ vi eventhub_test.py

from azure.servicebus import ServiceBusService

namespace        = 'pythontest'
eventhub_name = 'testhub'
sas_name          = 'writer'
sas_key             = 'SECRET'

sbs = ServiceBusService(namespace, shared_access_key_name=sas_name, shared_access_key_value=sas_key)
sbs.send_event(eventhub_name, '{"test":"35.689556 139.691722"}')

では、実際に動かしてみます。
まず、ポータルから作成したストリーム「teststream」を開始します。
次に、上記のスクリプトを実行します。
$ python eventhub_test.py


そして、SQLDatabaseのテーブルを確認します。
もちろんWindowsは使わずに、FreeTDSで確認です。(過去記事を御覧ください)
$ tsql ....
1> select * from test;
2> go
id    insert_date   test
1     2015-08-26 04: 02: 22.3330000    35.689556 139.691722
(1 rows affected)


これで、Raspbianから、イベントハブからSQLDatabaseへのデータ保存ができました。
RaspberryPiからPythonで連携できると、何かと幅が広がるかと思います。

次はREST APIかなー。
























2015年7月14日火曜日

MicrosoftAzureでAsteriskを動かしてみる(CentOS7編)

MicrosoftAzure上のCentOS7で出来るわけですが、いくつか注意点があります。

1. エンドポイントの許可
Asteriskは5060/UDPがデフォルトです。(変更すればTCPでも通信できます)
該当するポート番号へのエンドポイントの設定を忘れずに。


2. SELinuxを無効に
今回はAsteriskをコンパイルしてインストールするので、無効にします。
「/etc/sysconfig/selinux」のSELINUXを「disabled」もしくは「permissive」に設定してサーバーを再起動します。
# cat /etc/sysconfig/selinux 
SELINUX=permissive
SELINUXTYPE=targeted 

3. コンパイル用のツールをインストール
yumで必要なものを一通り入れておきましょう。
# yum groupinstall 'Development Tools'
# yum -y install make gcc ncurses-devel libtermcap-devel kernel-devel zlib-devel libtool libxml2-devel libxml2

4. firewalldで5060/UDPを許可
firewalldを設定している場合は、5060/UDP(もしくは設定した任意のポート番号)を許可します。
「/etc/firewalld/zones/public.xml」の「」内に、「」を追加して、firewalldを再起動します。

上記の準備ができたら、Asteriskのコンパイルとインストールです。
今回は、なんとなく1.8系をインストールしたいと思います。(現時点での最新は1.8.32.3かなー)
# wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.8.32.3.tar.gz
# tar zxvf asterisk-1.8.32.3.tar.gz 
# cd asterisk-1.8.32.3
# ./configure
# make
# make install
# make samples
# make config

Linuxに慣れた人はいつものヤツですね。
インストールが終わったら、sip.confとextensions.confを設定します。

/etc/asterisk/sip.conf(変更、追加のみ)
# cat /etc/asterisk/sip.conf 
language=ja 

[201]
type=friend
defaultuser=201
secret=pass
host=dynamic
canreinvite=no
dtmfmode=rfc2833
transport=udp

[202]
type=friend
defaultuser=202
secret=pass
host=dynamic
canreinvite=no
dtmfmode=rfc2833
transport=udp

/etc/asterisk/extensions.conf(変更、追加のみ)
# cat /etc/asterisk/extensions.conf
[default]
exten => 201,1,Dial(SIP/201,30,r)
exten => 201,2,Hangup()

exten => 202,1,Dial(SIP/202,30,r)
exten => 202,2,Hangup()

設定したら、Asteriskを起動します。
systemctl start asterisk

後は、適当なSIPクライアントで確認してみましょう。






2015年7月13日月曜日

CentOS6.6をAzureで(kernelのバグを避ける)

CentOS6をAzureで使おうと思ったら、このバグを避けないと起動しなくなる場合があります。
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=e86fb5e8ab95f10ec5f2e9430119d5d35020c951

CentOS6.6(というよりはOpenLogic6.6かな)のデフォルトイメージで仮想マシンを作るとこのバグを踏むことになるので、以下のようにするといいかもしれない。

・仮想マシンを新規で作る場合、OpenLogic6.5を選択
・作成後、yum upgradeで6.6にアップデート

なお、上記リンクのパッチが当たったパッケージは「kernel-2.6.32-504.23.4.el6」になります。
CentOS7はかなり前に対応しています。

2015年6月23日火曜日

さっそくruncを動かしてみた

DockerCon 2015 で 「Open Container Project」発足と新しいランタイム「runC」が発表になりました。
https://www.opencontainers.org
http://www.publickey1.jp/blog/15/dockerrunclinuxwindows.html

すでにrunCもダウンロード可能です。
https://github.com/opencontainers/runc

こうなったら、やってみるしかありません。
みんながあまり好きではない、CentOS7で試してみましょう。

GOのインストールからスタートです。
エクセレントなやり方がわからず強引にやってます。
PATH、GOPATHの設定は.bash_profileにするといいと思います。
 # yum install golang
 # export GOPATH=$HOME/go
 # export PATH=$PATH:$GOHOME/bin
 # go get github.com/opencontainers/runc/libcontainer/utils
 # go get github.com/opencontainers/runc/libcontainer/nsenter
 # go get github.com/opencontainers/runc/libcontainer/devices
 # go get github.com/opencontainers/runc/libcontainer/configs
 # go get github.com/opencontainers/runc/libcontainer/cgroups
 # git clone https://github.com/opencontainers/runc.git
 # cd runc
 # make
 # make install


次は、dockerイメージをexportして、適当なディレクトリに展開します。
 # docker export コンテナID > image.tar
 # mkdir rootfs
 # cd rootfs
 # tar xvf ../image.tar

最後に、container.jsonを例にしたがって作成します。
長くなりますが、githubのREADME.mdをコピーして、ユーザーのみrootに変更します。
 # cat container.json 
{
    "version": "0.1",
    "os": "linux",
    "arch": "amd64",
    "processes": [
        {
            "tty": true,
            "user": "root",
            "args": [
                "sh"
            ],
            "env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "TERM=xterm"
            ],
            "cwd": ""
        }
    ],
    "root": {
        "path": "rootfs",
        "readonly": false
    },
    "cpus": 1.1,
    "memory": 1024,
    "hostname": "shell",
    "namespaces": [
        {
            "type": "process"
        },
        {
            "type": "network"
        },
        {
            "type": "mount"
        },
        {
            "type": "ipc"
        },
        {
            "type": "uts"
        }
    ],
    "capabilities": [
        "AUDIT_WRITE",
        "KILL",
        "NET_BIND_SERVICE"
    ],
    "devices": [
        "null",
        "random",
        "full",
        "tty",
        "zero",
        "urandom"
    ],
    "mounts": [
        {
            "type": "proc",
            "source": "proc",
            "destination": "/proc",
            "options": ""
        },
        {
            "type": "tmpfs",
            "source": "tmpfs",
            "destination": "/dev",
            "options": "nosuid,strictatime,mode=755,size=65536k"
        },
        {
            "type": "devpts",
            "source": "devpts",
            "destination": "/dev/pts",
            "options": "nosuid,noexec,newinstance,ptmxmode=0666,mode=0620,gid=5"
        },
        {
            "type": "tmpfs",
            "source": "shm",
            "destination": "/dev/shm",
            "options": "nosuid,noexec,nodev,mode=1777,size=65536k"
        },
        {
            "type": "mqueue",
            "source": "mqueue",
            "destination": "/dev/mqueue",
            "options": "nosuid,noexec,nodev"
        },
        {
            "type": "sysfs",
            "source": "sysfs",
            "destination": "/sys",
            "options": "nosuid,noexec,nodev"
        }
    ]
}

やっとコンテナを動かせます。
コマンドひとつです。
 # runc
(ここからコンテナのシェルです)
# ls
bin  boot  dev etc  home  lib lib64  media  mnt  opt proc  root  run  sbin  srv  sys  tmp  usr  var
# pwd
/
# hostname
shell
# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 04:13 ?        00:00:00 sh
root         7     1  0 04:13 ?        00:00:00 ps -ef

もうちょっと突っ込んだことは、ぼちぼちみなさんやり始めるんでしょうね。
次はWindowsコンテナかw



2015年6月11日木曜日

CentOS on Azure 小ネタたち

AzureでCentOSを動かすときに、ちょっとしたことが違ったりするので思いつくままに書き出してみる。

1. yumを実行するとkernelも自動的にアップデートされる

確かオンプレではkernelはyumのアップデート対象から外れてるはずなんだけどなー。
kernelの問題で起動しないことも考えられるので、以下のように設定して無効にしたほうがいいかも。
管理者権限で、「/etc/yum.conf」に「exclude=kernel*」を追記するだけです。


2. fsckが実行されるかも

「tune2fs -l /dev/sda1」を実行すると、fsckの定期実行は無効(-1)になっている。
しかし、/dev/sdb1を使う場合は定期実行が有効になってる場合があるので、気をつけましょう。
「tune2fs -c -1 /dev/sdb1」で無効にします。
まあ、起動時のコンソールを見ることができればいいんですけど...


3. CentOS6.6の仮想マシンで最初から固まる

プロビジョニングに失敗してどうしようもない場合、以下の手順をやってみるといいかもしれません。

CentOS6.5で仮想マシンを作成→yum.confに「exclude=kernel*」を追記→yum upgradeで6.6へ



2015年6月8日月曜日

CentOS on Azure のリポジトリを見る

Microsoft Azure で提供されているCentOSは、米OpenLogicから提供されています。
通常使うCentOSとの違いは、Azureで動かすためのWALinuxAgentパッケージとそれを提供するリポジトリが追加されているところです。

ついでですが、WALinuxAgentは、こちらにソースなど一式があります。
https://github.com/Azure/WALinuxAgent

実際に設定を見てみます。
「/etc/yum.repo.d/OpenLogic.repo」を開きましょう。
# cat OpenLogic.repo 
[openlogic]
name=CentOS-$releasever - openlogic packages for $basearch
baseurl=http://olcentgbl.trafficmanager.net/openlogic/$releasever/openlogic/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://olcentgbl.trafficmanager.net/openlogic/$releasever/openlogic/$basearch/OpenLogic-GPG-KEY

以下のURLへパッケージを取得しにいきます。

CentOS6.6

CentOS7

なお、OpenLogicが提供するCentOSリポジトリは更新が遅れる場合が多いので、yum-plugin-fastestmirrorを導入するなどして運用する方が無難です。
もちろん、OpenLogic.repo以外のbaseurlは、近くのCentOSリポジトリに変更しても構いません。

2015年6月3日水曜日

RaspberryPi2同士でシリアル通信

RaspberryPi2は、起動時にHDMI経由でモニターに繋いでセットアップしますよね?
はっきり言って面倒です。

よく考えたら、普通のLinuxなりBSDが動く訳ですから、シリアル接続してminicomで繋げばモニター不要じゃない?
という訳でやってみました。

※もっと面倒だって思うでしょうが、そんな大人の意見はあえて聞きません。

必要なモノはこちら。

1.ラズパイ2台(今回はみんな大好きRaspbianを使用)
2.ジャンパーコード(メス-メス)を3本
参考までに、秋月さんのページ。

ジャンパーコードで、以下のようにラズパイ2台をつなぐのです。

PIN#6(Ground) - PIN#6(Ground)
PIN#8(TX) - PIN#10(RX)
PIN#10(RX) - PIN#8(TX)

ピン番号はこちらを参考にどうぞ。

なお、シリアルコンソールは「/dev/ttyAMA0」になります。

次は、OSをインストールしたという前提で、シリアルコンソール出力を見たいラズパイにminicomをインストールします。
# apt-get update
# apt-get install minicom

「/boot/cmdline.txt」を編集します。「console=ttyAMA0,115200」を消して保存します。
# vi /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

「/etc/inittab」の最後の行をコメントアウトします。
# vi /etc/inittab
 #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

終わったら一旦再起動します。
再起動後、minicomで接続すると、シリアルコンソールから見ることができます。
# minicom -b 115200 -o -D /dev/ttyAMA0

終了したい場合は、「CTRL-a」を押して「q」で、プロンプトに「YES」と答えます。

お試しあれ。

PHP + MySQLのフェイルオーバー(mysqlnd_msを使う)

PHPをお使いの方、mysqlnd_msというPECL拡張モジュールをご存知でしょうか?
http://php.net/manual/ja/book.mysqlnd-ms.php

mysqlndを使って、レプリケーションやロードバランシングするモジュールです。
以前取り上げたPerconaなどのMySQLマルチマスタレプリケーションを組み合わせると、
お手軽にフェイルオーバー構成が出来ちゃいます。(もちろん自己責任で!!!!!)

CentOS7でのインストール方法は以下の通りです。
# yum -y install php_mysqlnd
# pecl install mysqlnd_ms

インストール後、モジュールの読み込みに必要な設定をphp.iniまたは設定ファイルに記述します。
CentOS7なので、「/etc/php.d/」の下に「mysqlnd_ms.ini」と名前をつけて保存します。
内容は下記の通りです。
extension=json.so
extension=mysqlnd.so
extension=mysqlnd_ms.so
mysqlnd_ms.enable = 1
mysqlnd_ms.disable_rw_split = 1
mysqlnd_ms.force_config_usage = 1
mysqlnd_ms.multi_master = 1
mysqlnd_ms.config_file = "/etc/mysqlnd_ms.json"

なお、json.soは、後ほどコマンドラインで実行するために追記しています。
今回はマルチマスタ構成なので、mysqlnd_ms.multi_master=1としています。
mysqlnd_ms.config_fileには、設定ファイル(JSON形式)の絶対パスを記述します。

設定ファイルはこのようにしました。
{
  "myapp": {
    "master": {
      "master_1": {
        "host": "10.0.0.6",
        "port": "3306"
      },
      "master_2": {
        "host": "10.0.0.7",
        "port": "3306"
      }
    },
    "slave": {},
    "filters": { "roundrobin": [] },
    "failover": { "strategy": "loop_before_master", "remember_failed": true }
  }
}

"myapp"は、mysqli関数を呼ぶ際にホスト名の代わりに入力する文字列です。後ほどPHPのサンプルを確認してください。
マルチマスタなので、masterの中にmaster_1、master_2と記述があります。
2台のサーバーへラウンドロビンで接続するので、"filters"に"roundrobin"を設定します。
ここまで設定してhttpdを再起動すると、phpinfoでmysqlnd_msの設定が反映されます。

そして、実験用PHPプログラムはこちらです。nameに$iを入れて10回ループします。
$mysqli = new mysqli("myapp", "username", "password", "testdb");

for ($i=0; $i<10 i="" p="">
  echo $mysqli->query("insert into test(name) values('".$i."');") . "\n";
}

$mysqli->close();

今回は、無停止で動作するとわかりにくいので、独立した2台のMySQLサーバーにデータを書き込んで確認してみます。

最初は2台とも動作している場合です。5件ずつ交互にデータが追加されています。
# php -c /etc/php.d/mysqlnd_ms.ini test.php
# mysql -u username -h 10.0.0.6 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 0    |
|  2 | 2    |
|  3 | 4    |
|  4 | 6    |
|  5 | 8    |
+----+------+
5 rows in set (0.00 sec)

> exit
# mysql -u username -h 10.0.0.7 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 3    |
|  3 | 5    |
|  4 | 7    |
|  5 | 9    |
+----+------+
5 rows in set (0.00 sec)

> exit


master_1を停止して実行してみましょう。master_1が停止しているので、master_2に10件追加されています。
# php -c /etc/php.d/mysqlnd_ms.ini test.php
# mysql -u username -h 10.0.0.6 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 0    |
|  2 | 2    |
|  3 | 4    |
|  4 | 6    |
|  5 | 8    |
+----+------+
5 rows in set (0.00 sec)

> exit
# mysql -u username -h 10.0.0.7 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 3    |
|  3 | 5    |
|  4 | 7    |
|  5 | 9    |
|  6 | 0    |
|  7 | 1    |
|  8 | 2    |
|  9 | 3    |
| 10 | 4    |
| 11 | 5    |
| 12 | 6    |
| 13 | 7    |
| 14 | 8    |
| 15 | 9    |
+----+------+
15 rows in set (0.00 sec)

> exit


master_2を停止して実行してみましょう。master_2が停止しているので、master_1に10件追加されています。
# php -c /etc/php.d/mysqlnd_ms.ini test.php
# mysql -u username -h 10.0.0.6 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 0    |
|  2 | 2    |
|  3 | 4    |
|  4 | 6    |
|  5 | 8    |
|  6 | 0    |
|  7 | 1    |
|  8 | 2    |
|  9 | 3    |
| 10 | 4    |
| 11 | 5    |
| 12 | 6    |
| 13 | 7    |
| 14 | 8    |
| 15 | 9    |
+----+------+
15 rows in set (0.00 sec)

> exit
# mysql -u username -h 10.0.0.7 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 3    |
|  3 | 5    |
|  4 | 7    |
|  5 | 9    |
|  6 | 0    |
|  7 | 1    |
|  8 | 2    |
|  9 | 3    |
| 10 | 4    |
| 11 | 5    |
| 12 | 6    |
| 13 | 7    |
| 14 | 8    |
| 15 | 9    |
+----+------+
15 rows in set (0.00 sec)

> exit


最後に、2台とも動かして実行してみましょう。5件ずつ追加されています。
# php -c /etc/php.d/mysqlnd_ms.ini test.php
# mysql -u username -h 10.0.0.6 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 0    |
|  2 | 2    |
|  3 | 4    |
|  4 | 6    |
|  5 | 8    |
|  6 | 0    |
|  7 | 1    |
|  8 | 2    |
|  9 | 3    |
| 10 | 4    |
| 11 | 5    |
| 12 | 6    |
| 13 | 7    |
| 14 | 8    |
| 15 | 9    |
| 16 | 0    |
| 17 | 2    |
| 18 | 4    |
| 19 | 6    |
| 20 | 8    |
+----+------+
20 rows in set (0.01 sec)

> exit
# mysql -u username -h 10.0.0.7 -p test.db
Enter password:

> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 3    |
|  3 | 5    |
|  4 | 7    |
|  5 | 9    |
|  6 | 0    |
|  7 | 1    |
|  8 | 2    |
|  9 | 3    |
| 10 | 4    |
| 11 | 5    |
| 12 | 6    |
| 13 | 7    |
| 14 | 8    |
| 15 | 9    |
| 16 | 1    |
| 17 | 3    |
| 18 | 5    |
| 19 | 7    |
| 20 | 9    |
+----+------+
20 rows in set (0.00 sec)

> exit


PHPプログラムの接続時のホスト名のみ変更するだけで、プログラム自体を変更することなく導入できることがわかってもらえたかと思います。

なお、WindowsでもDLLがコンパイルできれば利用可能なようです。
http://php.net/manual/ja/install.windows.building.php

※追記 2015/06/03
こちらから各バージョン用DLLがダウンロードできます。
http://pecl.php.net/package/mysqlnd_ms/1.5.2/windows

なお、ドライバが対応しているので、mysqli関数のみならず、PDOやmysql関数からも利用できます。
http://php.net/manual/ja/mysqlnd-ms.quickstart.usage.php

お手軽にできるという点で、試してみる価値はあると思います。