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

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

2015年10月

前回の続きです:
Bluemix のビルドパックを作る(1/3)


このシリーズは3回に分けて IBM Bluemix 用のビルドパックをゼロから作成する手順を説明するもので、今回はその2回目です:
(1) ビルドパックを作る上で知っておくべきこと
(2) ビルドパックを作るための準備作業      ←今回はここ
(3) ビルドパックを作成して、実際に動作確認


前回は、ビルドパックを作成する上で知っておくべき仕組みや制限事項についてをまとめました。おおまかには次のような仕組み/条件でビルドパックを作ります:
- ビルドパック自体は detect, compile, release の3つのスクリプトからなる。
- これら3つのスクリプトは一般ユーザー権限で実行される。su や sudo は使えない。
- 素の Ubuntu Linux に対して、これら3つのスクリプトが実行された後に必要な環境が整っているようにする。

今回と次回の2回に分けて、実際にビルドパックをゼロから作成します。正確には実際にビルドパックそのものを作る手順は次回紹介しますが、今回はそのための準備作業を紹介します。具体的には実際にビルドパックを作るスクリプトは一般ユーザー権限でしか実行できないため、ビルドなどの root 権限が必要な作業はあらかじめ(Ubuntu 環境下で)済ませておく必要があります。そのための作業の説明を今回のブログエントリの中で紹介します。

また、今回作成するビルドパックの内容は「比較的緩めな日本語対応 PHP アプリケーションサーバーを作る」こととします。具体的には以下の様なスペック PHP アプリケーションサーバーのビルドパックを作ります:
・ PHP 5.6.14
・ Apache HTTPD 2.4.16
・ PHP の MySQL モジュールと Postgresql モジュールを追加
・ PHP の設定は日本語 UTF-8 ベースで、エラー発生時のエラー内容を出力、ファイルアップロードは1ファイル10MB まで許可、・・・などなど php.ini を緩めに設定
・ Apache HTTPD も .htaccess での設定上書きを許可するなど、ゆるゆるにする

簡単にいえば「php.ini と httpd.conf を緩めに設定するような環境で PHP のビルドパックを作成する」ということです。


では本エントリでの作業に入ります。まずは 64bit の Ubuntu Linux 14.02 環境を用意します。デスクトップ環境は必須ではありません。SSH 等でログインしてターミナル上での操作ができれば大丈夫です:
2015100900



この Ubuntu の中に PHP と Apache HTTPD 環境を構築していきます。といっても、ただインストールすればいいというわけではありません。インストールだけなら "sudo apt-get install php5 apache2 libapache2-mod-php5" とかを実行すればいいのですが、これは sudo が使える前提での話です。上記のようにビルドパック作成時の権限は sudo の使えないユーザー権限なので、この apt-get による簡単なインストール方法は使えないのです。

ではどうするか? その答は (2) まず Ubuntu 内で必要なモジュールを、ソースからのコンパイルなど全て手作業で作り、 (3) 作ったモジュールを tar などでまとめておき、ビルドパック作成時は一般ユーザーが展開してコピーすればよい、という状態にしておく 必要があるのでした。要は root 権限が必要な部分((2))と、不要な部分((3))に作業を分断し、ビルドパック作成時は root がなくてもできる作業だけを行います。そしてそのような作業だけで済むように、root 権限が必要な作業は(ビルドパック作成作業の前)あらかじめ済ませてまとめておく、という作業を行うようにします。これが全体作業でいうところの (2) と (3) を分けた理由でもあります。

では、あらためて今回行う作業の内容をまとめておきます:
(2-1) Apache HTTPD 2.4.16 をソースからビルドして /app/apache/ 以下にインストール
(2-2) PHP 5.6.14 をソースからビルドして /app/php/ 以下にインストール
(2-3) 出来上がった Apache HTTPD 2.4.16 および PHP 5.6.14 のモジュールを /app/apache/ および /app/php/ 以下からそれぞれ取り出してアーカイブ

こうして出来上がったアーカイブファイルは、Ubuntu 環境の /app/apache/ & /app/php/ 以下であれば動くように作られているので、同じ状態を作り出すようにビルドパックを構成(次回)すればよい、ということになります。今回はそのための準備を行います。


では具体的な作業手順の説明です。まずは Ubuntu 14.02(64bit) のターミナル環境に SSH 等でログインします:
2015100901


まずは作業ディレクトリを作成します。今回は /tmp/build を作業ディレクトリとします:
$ mkdir -p /tmp/build
$ cd /tmp/build


(2-1) Apache HTTPD 2.4.16 のソースコード一式をダウンロードし、作業ディレクトリ内に展開します:
$ curl -L http://www.carfab.com/apachesoftware/httpd/httpd-2.4.16.tar.gz | tar xzf -


Apache HTTP のビルドに必要な apr-1.5.2 および apr-util-1.5.2 をそれぞれダウンロードし、作業ディレクトリ内の srclib/ ディレクトリ内に展開します:
$ cd httpd-2.4.16/srclib
$ curl http://www.us.apache.org/dist/apr/apr-1.5.2.tar.gz | tar xzf -
$ mv apr-1.5.2 apr
$ curl http://www.us.apache.org/dist/apr/apr-util-1.5.4.tar.gz | tar xzf -
$ mv apr-util-1.5.4 apr-util
$ cd ..


Apache HTTP のビルドに必要なライブラリ(libpcre3, libpcre3-dev)を apt-get で入手します:
$ sudo apt-get install libpcre3 libpcre3-dev


Apache HTTP ビルド後のインストールディレクトリを /app/apache/ とする前提でビルド(configure して make して make install )します:
$ ./configure --prefix=/app/apache --with-included-apr --enable-rewrite
$ sudo mkdir -p /app/apache
$ sudo chmod -R 777 /app/
$ make && make install


(2-2) PHP インストール先のディレクトリ(/app/php/)を用意します:
$ sudo mkdir -p /app/php


(2-1) の作業でビルドしたモジュールの一部を PHP のライブラリとしてコピーします:
$ sudo mkdir -p /app/php/ext
$ sudo chmod -R 777 /app/php
$ cp /app/apache/lib/libapr-1.so.0 /app/php/ext
$ cp /app/apache/lib/libaprutil-1.so.0 /app/php/ext
$ cd /app/php/ext
$ ln -s libapr-1.so.0 libapr-1.so
$ ln -s libaprutil-1.so.0 libaprutil-1.so


PHP のビルドに必要なライブラリ(libxml2, libxml2-dev, libssl-dev, ...)を apt-get で入手します。平行して PostgreSQL をサポートするために必要な環境を整えます:
$ cd /tmp/build
$ sudo echo “deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main”> /etc/apt/sources.list.d/pgdg.lis
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc |  sudo apt-key add -OK
$ sudo apt-get update
$ sudo apt-get install libxml2 libxml2-dev libssl-dev libvpx-dev libjpeg-dev libpng12-dev libXpm-dev libbz2-dev libmcrypt-dev libcurl4-openssl-dev libfreetype6-dev postgresql-server-dev-9.4


PHP のソースコード一式をダウンロードし、作業ディレクトリ内に展開します:
$ curl -L http://php.net/get/php-5.6.14.tar.gz/from/us1.php.net/mirror | tar xzf -


PHP ビルド後のインストールディレクトリを /app/php/ とする前提でビルド(configure して make して make install )します:
$ cd php-5.6.14
$ ./configure --prefix=/app/php --with-apxs2=/app/apache/bin/apxs --with-mysqli --with-pdo-mysql --with-pgsql --with-pdo-pgsql --with-iconv --with-gd --with-curl=/usr/lib --with-config-file-path=/app/php --enable-soap=shared --enable-libxml --enable-simplexml --enable-session --with-xmlrpc --with-openssl --enable-mbstring --with-bz2 --with-zlib --with-gd --with-freetype-dir=/usr/lib --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --with-xpm-dir=/usr/lib
$ make && make install


MySQL クライアントライブラリを apt-get で入手して、PHP / Apache のライブラリとしてコピーします:
$ sudo apt-get install libmysqlclient-dev
$ cd /app/php/ext
$ cp /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.0.0 ./
$ ln libmysqlclient.so.18.0.0 libmysqlclient.so.18
$ ln libmysqlclient.so.18.0.0 libmysqlclient.so
$ cp /tmp/build/php-5.6.14/.libs/libphp5.so /app/apache/modules/


(2-3) コンパイルが終了した Apache HTTP のモジュールをアーカイブします:
$ cd /app
$ echo '2.4.16' > apache/VERSION
$ tar -zcvf apache-2.4.16.tar.gz apache


コンパイルが終了した PHP のモジュールをアーカイブします:
$ echo '5.6.14' > php/VERSION
$ tar -zcvf php-5.6.14.tar.gz php




これで (2) の作業が完了して、ビルドパックを作るための作業準備が整いました。今回の作業で出来上がった apache-2.4.16.tar.gz および php-5.6.14.tar.gz はどちらも /app/ 以下にコピーすれば正しく動く前提で作られているので、これらのモジュールを使い、この条件でビルドパックを作ってあげればよい、ということになります。

次回はいよいよ実際にビルドパックを作って、動作確認までしてみます。ゴールは目前!


(注 2015/Oct/16 追記)
続きはこちら

 

IBM Bluemix 上のランタイムとして使えるビルドパックを自分でゼロから作る、ということに挑戦してみます。今回は作業は行わず、その仕組とか概要の説明になります。 とはいえ、ここで知っておかないと作ったり、うまく動かなかった時の調整に困ったり、一度作ったものを自分なりに再カスタマイズする際に手間取ったりすると思ったので、一応知っておくべきことをまとめておきます。

予定としてはこんな感じで、3回に分けて説明するつもりです:
(1) ビルドパックを作る上で知っておくべきこと ←今回はここ
(2) ビルドパックを作るための準備作業
(3) ビルドパックを作成して、実際に動作確認



ビルドパックとは?

ビルドパックとは Bluemix 上で動作するランタイムの実行基盤を準備するための仕組みです。元々は Heroku 用に開発されたカスタマイズのための仕組みで、CloudFoundry では V2 から採用されています。Bluemix のランタイムメニューからも、GitHub 上に公開されたコミュニティー提供のものも、多くのビルドパックが公開され、利用可能です。


ビルドパックの環境

Bluemix 上に作成されるランタイムには Ubuntu Linux が使われます。2015年10月時点では Bluemix のスタックは Ubuntu 14.04.2 trusty (x86_64) です。

ビルドパックで用意した環境は、最終的にこの Ubuntu サーバー上にコピーされて動くことになります。つまり、Ubuntu 14.04.2 上で動くようなものを作る必要があるわけです。

ビルドパックを構築する作業の中で C のコンパイルなどの作業を行いますが、それらは Ubuntu 14.04.2(x86_64) 上で動くようなモジュールにする必要があります。作ったビルドパックの動作確認時の手間などを考えると、ビルドパックのカスタマイズは事実上 Ubuntu 環境上で作業する必要があります。

というわけで、次回以降で実際に行う作業は全て Ubuntu 14.04 環境上で行います。この環境を用意しておく必要があります:
2015101001



ビルドパックの構成

ビルドパックは detect, compile, release という3つのスクリプトから構成され、これらが順次実行されます:
スクリプト説明
bin/detectアプリケーションの構造をチェックして、導入可能な構成か(次に進んでいいか)をチェックする
bin/compileランタイム環境を作成する
bin/release起動時のコマンド等を作成する


注意点として、これら3つのスクリプトは vcap という一般ユーザー権限で実行される、ということです(セキュリティ上の制約)。なお、この vcap ユーザーには sudo 権限はありません。つまり、これら3つのスクリプトは一般ユーザー権限で実行できるようなものにする必要があります。管理者権限が必要な作業はこれらのスクリプト実行の前に全て終わらせておく必要があり、これらのスクリプトの中では一般ユーザー権限で実行できるものしか使えません。

具体的には、例えば apt-get install などはこれらのスクリプトの中では使えません。ただし wget であれば使える、などです。

したがって例えば Apache HTTP Server をビルドパックに含めるには、bin/compile スクリプトの中で Apache HTTP Server を apt-get install して・・・というわけにはいきません。予め Apache HTTP Server のソースファイル一式を入手しておいて、コンパイルして Ubuntu 上で動くバイナリを作っておいて、それを bin/compile スクリプトで実行ディレクトリにコピーして使う、という流れになります。共有ライブラリなどを使う場合にも同様の注意が必要です。

また、各スクリプトで生成したり、配置したりするファイルは "/app/" 以下に配置するようなスクリプトにする必要があります。"/tmp" や "/var/tmp" 以下には永続性保証がありません。

これら3つのスクリプト、それぞれについて詳細を以下で紹介します。


detect スクリプト

このスクリプトはビルドパックの実行条件を判断するためのスクリプトです。プッシュしようとしている内容が、このビルドパックで用意された環境向けの内容としてふさわしいかどうかを判断し、(例えば PHP ランタイムなのに PHP ファイルが含まれていないなど)ふさわしくないと判断したら compile には進みません。

このスクリプトには引数が1つ渡されて実行されます。渡される引数はプッシュされるアプリケーションのパスです。

そしてその引数を参照して(しなくてもいいけど) detect スクリプトが実行され、ビルドパック実行にふさわしいと判断したら標準出力に 0 を出力します。ビルドパック実行にふさわしくないと判断したら標準出力に 1 を出力します。detect スクリプトは 0 か 1 を標準出力に出力して完了します。


compile スクリプト

実際のビルドパック環境を構築するスクリプトです。実際に動くアプリケーションサーバー環境を作り上げるスクリプトとなり、いわば、ここがビルドパックの肝になる部分です。

このスクリプトは detect スクリプトの出力結果が 0 だった場合のみ実行されます。

このスクリプトには引数が2つ渡されて実行されます。第一引数はプッシュされるアプリケーションのパス、第二引数はキャッシュディレクトリのパスです。detect スクリプトとは違い、標準出力への内容がルール化されているわけではありません。

繰り返しになりますが、このスクリプトは一般ユーザー権限で実行されます。なので、例えば HTTP サーバーを導入する場合、apt-get install では導入できません。あらかじめソースファイルからバイナリを生成しておいて、compile スクリプト内では生成済みバイナリを実行パスにコピーする、といった形で環境構築を行う必要があります。


release スクリプト

アプリケーション起動時の動作を指定するスクリプトです。

このスクリプトには引数が1つ渡されて実行されます。渡される引数はプッシュされるアプリケーションのパスです。

このスクリプトの実行結果は、以下の様な YAML フォーマットで出力する必要があります。最後の commandLine の部分にアプリケーションサーバーを稼働させるためのスクリプトを記述します:
config_vars:
 name: value
default_process_types:
 web: commandLine



今回の内容はここまでです。ビルドパックを作る上での制限というか、制約というか・・・は理解できたでしょうか? 普通に Bluemix を使う上では知らなくてもいいことが多かったと思いますが、ビルドパックという低レベルなカスタマイズを行おうとすると、こういった知識も必要になってきます。ちょっと面倒に感じるところがあるかもしれませんが、勝手に変なスクリプトが実行されることのないよう、現状のような(比較的制限の大きな)仕様になっているのでした。

次回は、実際にビルドパックをゼロから作るための、その準備段階を紹介する予定です。 実際の作業はプログラミングというよりも「どれだけ Linux に詳しいか」を痛感するような内容になります(苦笑)。がんばって着いてきてくださいっ!

(2015/Oct/15 追記)
続きはこちら


ペネトレーションテスト向けにカスタマイズされた Linux ディストリビューションである『Kali Linux』に VNC サーバー機能を導入する手順を紹介します。

まず、インストールする VNC サーバーアプリケーションは vnc4server です。これを apt-get でインストールします:
# apt-get install vnc4server

vnc4server の起動は以下の vncserver コマンドで行います。起動後にパスワードを聞かれるので入力内容を覚えておきます。なお、VNC クライアントでアクセスする際には、この vnc4server を実行したユーザーのユーザー権限でログインするので、必要であれば su でユーザーを切り替えてから実行してください。また ":" の後の数字はポート番号を意味する数字(この数字 + 5900 番ポートで実行する)で、この例であれば 5901 番で実行されます:
# vncserver :1

You will require a password to access your desktops.

Password: (パスワードを入力)
Verify: (パスワードを再入力)
   :
   :

これで VNC サーバーが起動しますが、少しカスタマイズを加えます。そのために一旦起動した VNC サーバーを終了します。終了は以下のコマンドで行います(最後の : の後の数字は実行時に指定したものを同じもの):
# vncserver -kill :1

この vncserver コマンドを実行したユーザーのホームディレクトリ以下の ~/.vnc/xstartup というファイルに VNC 実行時の X11 サーバーの設定が記述されているので、このファイルを編集します。具体的にはデフォルト Window Manager を使うのではなく、GNome セッションを使うことにします(赤字の3行を変更):
# vi ~/.vnc/xstartup
  :
  :
xsetroot -solid grey
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
gnome-session &

ここまでのカスタマイズが終わったら、改めて VNC サーバーを実行します。
# vncserver :1

では、この Kali Linux マシン以外から VNC クライアントでこのマシンに接続を試みてみます:
2015101201


今のところ、この VNC サーバーを自動起動させる方法が分からないので、再起動するたびに vncserver コマンドを実行する必要がありますが、一応 VNC サーバーを使えることがわかりました。


 

ペネトレーションテスト向けにカスタマイズされた Linux ディストリビューションである『Kali Linux』。いろいろアレな機能が標準搭載されていることに加え、見た目もカッコいいし、LibreOffice とかも入れれば普段使いのデスクトップ環境としても使える、という印象を持っています:


なお Kali Linux の導入手順および日本語化他については以前に作成した以下のエントリを参照してください:
Kali Linux を使ってみる


デスクトップ環境が目の前に使える状態になっていると便利なのですが、ペネトレーションテスト用のこだわりなのか、一般的な Linux ではデフォルト状態で使えるサービスの多くが使えません。例えば sshd も無効なので SSH によるリモートログインなども無効になっています。

これはこれでちょっと不便に感じることもあるので、Kali Linux で sshd を有効にする方法を紹介します。手順は簡単で、root でログインして以下のコマンドを実行します:
# update-rc.d ssh enable

で Kali Linux を再起動すると sshd が有効になっており(というか、自動で起動するようになり)、SSH によるリモートログインもできるようになります。


 

現在、世界中の IBM が学生を対象にメインフレーム上でのアプリケーション開発コンテストを開催しています:
Master the Mainframe 2015(メインフレーム・コンテスト)

2015100908


このプログラムに参加すると、IBM の最新版メインフレームである IBM z13 の環境にリモートログイン可能なアカウントを入手することができます。そのアカウントを利用して課題をクリアしつつ、最終的にはアプリケーションを開発して世界中の参加者とその出来を競い合う、というものです。リモートログイン先はネイティブ OS である z/OS だけでなく、Linux 専用メインフレームである LinuxONE 上の RedHat Enterprise Linux(RHEL) 7.1 を利用することもできます:
2015101004


zSystems の環境、一度使ってみたかったんだよなあ。でもこのコンテスト、学生向けなんだよなあ・・・ 社員がやったら怒られるかなあ・・・ いいなあ・・・ 残念だなああああああああああ


というわけで、以下のスクリーンショットは私の脳内を念写したものです(笑)。

まずは z/OS にアクセス。なんか学生時代の Fortrun の授業でこんなの使っていたような記憶が・・・
2015100907


vi がかわいく見えるレベルで操作方法がかなーり独特なテキストエディタ。。。
2015100909


・・・うん、わかった。ごめんなさい、部屋を間違えました(?)

問題はこっちだ。RHEL 7.1 環境へログイン。そうそう、このプロンプトが出ると安心(苦笑):
2015100901


まずはシステムを確認。"el7.s390x" の文字が目新しい:
2015100902


念のためディストリビューションも確認。RHEL 7.1 ですね、と:
2015100903


/proc/cpuinfo を確認。"IBM/S390" の CPU を3つも使わせてくれるっぽい:
2015100904


root 権限は・・・ NG っぽい。しかも root になろうとしたこの操作がレポートされる、とな!? の、脳内で助かった(震え声):
2015100905


最後に top を実行。CPU 3つ、メモリ 4GB、スワップ 1GB のえらく贅沢な環境:
2015100906


コンテストは 11月20日まで応募を受け付けています。最優秀賞は NY で開催される世界大会へ招待される他、優秀賞は来年のラスベガスイベントへのご招待、メインフレーム賞として Oculus Rift など、副賞もメインフレーム級なものが用意されているっぽいです。



 

このページのトップヘ