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

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