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

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

タグ:foundry

IBM Bluemix のアプリケーションベースの1つが Cloud Foundry です。オープンソース版の PaaS 環境でもある Cloud Foundry を拡張したものが IBM Bluemix ですが、この Cloud Foundry が利用するコンテナ技術に新しいテクノロジーが加わりました。それが Diego です:
https://docs.cloudfoundry.org/concepts/diego/diego-architecture.html

2016120700


これまでの Cloud Foundry では DEA(Droplet Execution Agent) というコンテナ技術を使っていました。この進化版としての、新しいコンテナフォーマットや SSH ログインをサポートした新しいコンテナ、それが Diego です。DEA と Diego の技術的な相違点など、詳細はこちらをご覧ください:
https://docs.cloudfoundry.org/concepts/diego/dea-vs-diego.html


さて、この Diego は先日 IBM Bluemix でも有効になりました。現状は DEA と Diego が両方サポートされている状態で、デフォルトは DEA になっています。またこれまでに Bluemix 上で作成して動いていた CloudFoundry ランタイム(以下、 "CF ランタイム")アプリケーションは DEA コンテナのまま実行されています。なので、以下に紹介するような特別なことをしなければ特に何も変わらずに動いている/動く、ということになります。


一方、Diego コンテナでは DEA ではできなかったいくつかの新しい機能が有効になっています。その1つが ssh によるリモートログインです。というわけで、Bluemix アプリケーションを Diego コンテナに切り替えて、ssh ログインができることを確認する手順を以下に紹介します。


まず、現状で Diego コンテナを利用するには cf コマンドラインツールを利用する必要があります。また Diego コンテナを使う場合、cf ツールのバージョンは 6.13.0 以上である必要があります。なお cf ツールのバージョンを確認するには "cf -v" と実行してください:
$ cf -v
cf version 6.22.2+a95e24c-2016-10-27

cf コマンドを使ったことがなかったり、古い cf コマンドを使っている Bluemix ユーザーは、まずは自分の環境にあった cf ツールを GitHub からダウンロードしてインストールしておいてください:
https://github.com/cloudfoundry/cli/releases


次に Diego 機能を使うために cf コマンドに Diego-Enabler プラグインをインストールします。これは以下のコマンドでインストールできます:
$ cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org/
$ cf install-plugin Diego-Enabler -r CF-Community

これで Diego-Enabler が使える cf コマンドが用意できました。では実際に Bluemix 上の CF ランタイムアプリケーションを Diego コンテナに移行してみましょう。

今回、サンプルとして "dotnsf-diego-java" という名前の CF アプリケーションを Liberty for Java ビルドパックで作成しました。以下、この名前を使ってコマンドを実行する様子を紹介しますので、みなさんのアプリケーションの名前に置き換えてお読みください。なお、この時点では(これまで通り)DEA コンテナ上で動いているアプリケーションです:
2016120701


ためしにブラウザからアクセスすると、デフォルトの "Hello World!" が表示されます:
2016120702


このランタイムを Diego コンテナ上に移行してみましょう。まずは cf ツールでログインを行います:
$ cf login -a https://api.ng.bluemix.net/ -u (ユーザーID)
API エンドポイント: https://api.ng.bluemix.net/

Password> (パスワードを入力)
※↑の例では USA データセンターにログインしています。他のデータセンターの場合は "ng" の部分をデータセンターに合わせて変更してください。

最初に対象のランタイムアプリケーションを停止させる必要があります:
$ cf stop dotnsf-diego-java

停止が確認できたら、このランタイムのコンテナを Diego に変更します:
$ cf enable-diego dotnsf-diego-java

そして再スタートです:
$ cf start dotnsf-diego-java
  :
  :
要求された状態: started
インスタンス: 1/1
使用: 512M x 1 インスタンス
URL: dotnsf-diego-java.mybluemix.net
最終アップロード日時: Wed Dec 7 01:51:43 UTC 2016
スタック: cflinuxfs2
ビルドパック: Liberty for Java(TM) (WAR, liberty-16.0.1_3, buildpack-v3.5-20161114-1152, ibmjdk-1.8.0_20161019, env)

     状態   開始日時                 CPU      メモリー            ディスク           詳細
#0   実行   2016-12-07 11:05:40 AM   181.1%   512M の中の 97.9M   1G の中の 189.8M

この時点でアプリケーションは Diego コンテナ上で動いています。ただアプリケーションそのものには何の変更も加えていないので、見た目は変わっていません:
2016120702


ではこの Diego コンテナに SSH でログインして、アプリケーションを直接書き換えてみましょう。SSH でログインするには以下のコマンドを実行します:
$ cf ssh dotnsf-diego-java
vcap@18ce933a-65ca-4e3f-5f0c-d9fac300d6f9:~$  ←プロンプトが変わった!

ここは既に CF アプリケーションの中です。もちろん使えるコマンドには制約がありますが、例えば top コマンドを使ってサーバーリソースの利用状態を確認することもできます:
2016120703


ではアプリケーションを書き換えてみましょう。Liberty for Java ビルドパックの場合、アプリケーションは app/wlp/usr/servers/defaultServer/apps/myapp.war/ ディレクトリにあるのでここで移動し、vi で index.html を直接編集します:
$ cd app/wlp/usr/servers/defaultServer/apps/myapp.war
$ vi index.html

変更内容はどうでもいいのですが、とりあえず <body> タグの直後に目立つように <h1> タグのメッセージを追加してみました(↓赤枠部分を追加して保存):
2016120704


この状態で(再プッシュとかなしで)同アプリケーションをブラウザでリロードすると、入力したメッセージが画面に表示されて、アプリケーションが書き換わったことが確認できました:
2016120705


CF ランタイムは今までこれができないという制約があったのですが、Diego コンテナに切り替えることで課題を1つ克服できることになりますね。

自宅のローカル環境に Cloud Foundry v2 を導入してみました(注 自宅 Bluemix Local ではありません)

Cloud Foundry はオープンソースの PaaS(Platform as a Services) の名称です。IBM Bluemix を始め、多くの商用/非商用クラウドサービスの基盤として利用されている実績があります。元々は VMWare 社によって開発を行っていましたが、現在は 2014年12月に設立されたコミュニティ Cloud Foundry Foundation によって開発・管理・リリースが行われています(IBM も参画しています):
2016050203



【前提条件】

Intel x86_64 版の Ubuntu 14.04 環境が前提として必要です。同環境上に Cloud Foundry v2 Nise Installer を使って Cloud Foundry 環境を構築します。

なお、自分は以下の様なスペックの物理マシンを1台用意して、そこに Ubuntu 14.04 を導入しました:
メモリ: 12GB
HDD: 1TB
導入OS: Ubuntu Desktop 14.04 (要ネット接続)


ちなみに自分が使ったのは ASUS P30AD の(旧モデルの)現品処分特価品でした:
https://www.asus.com/jp/Tower-PCs/P30AD/

2016050201



メモリだけ 12GB に増設して、〆て50000円といった所です。この約 50000 円の ASUS 機が自宅 Cloud Foundry 環境になっています。今後同様の環境を作る人にとって、1つの目安となれば。


【Cloud Foundry 導入手順】


導入作業自体はシンプルです。まず Cloud Foundry v2 Nise Installer を動かすには Rbenv が必要です。そのため最初に Rbenv と、その前提となるパッケージをインストールします:
$ sudo apt-get install build-essential bison libreadline6-dev curl git-core zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev autoconf libncurses5-dev

そして Cloud Foundry v2 Nise Installer を使って Cloud Foundry v2 を導入します:
$ sudo bash < <(curl -s -k -B https://raw.githubusercontent.com/yudai/cf_nise_installer/${INSTALLER_BRANCH:-master}/scripts/bootstrap.sh)

なお、この(2番目の)コマンドを実行してから完了するまでに、自分の環境で1時間ちょっとかかりました。コーヒーでも飲みながら完了を待ちましょう。

成功すると、最後に以下のようなメッセージが表示されてプロンプトに戻ります。「Ubuntu 10.04 の場合は再起動しろ」というメッセージが表示されていますが、自分は 14.04 でしたが念のため再起動しました:
  :
  :
Done!
You can launch Cloud Foundry with './scripts/start.sh'
Restart your server before starting processes if you are using Ubuntu 10.04

これで Cloud Foundry のローカル環境構築自体は完了です。Cloud Foundry は上記の導入手順を実行したユーザーのホームディレクトリの ~/cf_nise_installer/ フォルダ以下に導入されているはずです。

なお、この後で cf コマンドを使ったオペレーションを行うため、cf コマンドも同環境上にダウンロードして導入しておきます。cf コマンドのウェブページから Debian 64 bit の最新版インストーラをダウンロードします:
2016050201



自分が 2016/May/02 にこの作業を行ったタイミングでは、cf ツールの最新版のバージョンは 6.17.0 で、ダウンロードファイル名は cf-cli-installer_6.17.0_x86-64.deb でした。異なるバージョンおよびファイル名だった場合は適宜読み替えて以下を実行してください。

ダウンロードした cf コマンドラインツールを dkpg を使ってインストールします:
$ sudo dpkg -i cf-cli-installer_6.17.0_x86-64.deb

【Cloud Foundry 起動】

ではローカル環境に導入した Cloud Foundry を起動します。起動は以下のコマンドを実行します:
$ sudo ~/cf_nise_installer/scripts/start.sh

少しずつ Cloud Foundry のモジュールが起動していく様子がわかります。最後に以下のようなメッセージが表示されてコマンドプロンプトが戻ったら、全ての Cloud Foundry モジュールの起動が完了したことを意味します(自分の環境だと Cloud Foundry 起動完了まで10分くらいかかりました):
  :
  :
+ tail -n +3
+ grep -v -E '(running|accessible)$'
+ sudo /var/vcap/bosh/bin/monit summary
+ break
+ grep -v -E '(running|accessible)$'
+ tail -n +3
+ sudo /var/vcap/bosh/bin/monit summary
+ set +x
All processes have been started!
Login : 'cf login -a https://api.192.168.0.10.xip.io -u admin -p c1oudc0w --skip-ssl-validation'
Download CF CLI from https://github.com/cloudfoundry/cli

最後のメッセージを見ると分かるのですが、API サーバー名が api.192.168.0.10.xip.io となっています。この NISE Installer を使うと、このような名前(xxxxx.IPアドレス.xip.io)で動作する DNS サーバーが自動的にローカルマシンに導入されて動きます。自分の環境では Cloud Foundry 導入マシンの IP アドレスが 192.168.0.10 だったので、このようなサーバー名になっていますが、皆さんの環境ではこの部分は皆さんの Cloud Foundry 導入マシンの IP アドレスになっているはずです。以下を適宜置き換えて参照ください。


【cf ツールで動作確認】

では cf ツールを使って動作確認してみます。まずは api サーバーを指定して Cloud Foundry にログインします。なお API サーバーに指定する名前は api.(このサーバーのIPアドレス<この例では 192.168.0.10>).xip.io と指定します。またログイン時に指定するメールアドレスとパスワードですが、デフォルトではそれぞれ admin / c1oudc0w となっています:
$ cf login -a api.192.168.0.10.xip.io -u admin -p c1oudc0w --skip-ssl-validation

最初の段階ではデフォルトの組織は DevBox となっていますが、スペースが未定義です。そこでスペース dev を作成して、組織 DevBox と紐付けます(最初の1回だけ、この作業が必要です):
$ cf create-space dev
$ cf target -o DevBox -s dev

では適当なアプリケーションをローカルの Cloud Foundry 上にデプロイしてみましょう。今回は PHP アプリケーションをデプロイしてみます:
$ mkdir phpinfo
$ cd phpinfo
$ echo "<?php phpinfo(); ?>" > index.php $ cf push phptest -b https://github.com/cloudfoundry/php-buildpack

↑のコマンドライン操作では、中身が <?php phpinfo(); ?> だけの index.php ファイル1つだけからなる phpinfo フォルダを作り、このフォルダを丸ごと phptest という名前のアプリケーションとしてプッシュ(デプロイ)しています。またプッシュの際に GitHub 上の PHP ビルドパックを指定して、これを使ってプッシュしています。

このプッシュ操作が成功すると、以下のように実行中のステータスが表示されます:
2016050202


いまプッシュした phptest アプリケーションを "cf apps" コマンドで確認すると、同アプリケーションは phptest.192.168.0.10.xip.io というサーバー名で動いていることがわかります(青字部分が出力メッセージ):
$ cf apps
admin として組織 DevBox / スペース dev 内のアプリを取得しています...
OK

名前      要求された状態   インスタンス   メモリー   ディスク   URL
phptest   started          1/1            1G         1G         phptest.192.168.0.10.xip.io

早速同マシンのデスクトップ環境のウェブブラウザから http://phptest.192.168.0.10.xip.io/ にアクセスしてみました:
2016050204


動いたーっ!! これで我が自宅にも Cloud Foundry 環境を構築することができました!


【今後の課題?】
一応動いたこの環境ですが、必ずしもあまり安定していない気がしています。使っているうちに同じ URL にアクセスしても、"502 Bad Gateway" エラーになってしまうこともあります:
2016050205


この場合は以下のコマンドでアプリを再ステージングすると復活するのですが・・・原因とかまだよく分かっていません:
$ cf restage phptest


まあ Cloud Foundry 環境としてはマシンがちと貧弱すぎる感は否めないのですが、どーなんでしょ。


ともあれ、とりあえず github のビルドパックを指定して、PHP ランタイムが動く、ということは確認できました。カスタマイズとかほとんどしてないけど、インストーラーを実行するだけなので楽ちんでした。今後はサービスとかも組み合わせてアプリを作ってみよう。


IBM Bluemix はオープンソース PaaS である Cloud Foundry をベースに作られています。ということは Cloud  Foundry の API を Bluemix に対して使う、ということもできるわけです。

実際に試してみた様子を以下に記載します。なお、実行にあたっては Bluemix のアカウントと、実行環境として curl を利用します。以下の例では CentOS 6 上の curl を使っていますが、他のプラットフォームでもほぼ同様に使えるはずです。また以下の例では北米データセンターを対象に API を実行しますが、他のデータセンターを使う場合は、"ng" の部分を "eu-gb"(英国)か "au-syd"(オーストラリア)といった具合に書き換えて実行してください:


(1) アクセストークンの取得

具体的な API の利用の前に OAuth のアクセストークンを取得しておく必要があります(このアクセストークンを使って個別の API を実行します)。

以下の curl コマンドを実行します(青字部分がレスポンスです):
# curl -XPOST -H"Application/json" -u "cf:" --data "username=username@xxxx.com&password=P@ssw0rd&grant_type=password&scope=" https://login.ng.bluemix.net/UAALoginServerWAR/oauth/token

{
 "access_token":"(accessToken)", 
"token_type":"bearer",
"refresh_token":"*******", "expires_in":43199, "scope":"cloud_controller.read password.write cloud_controller.write openid", "jti":"********" }

"--data" に続く部分にログイン情報を含めています。username は Bluemix のログインIDです(上の例では username@xxxx.com を指定しています)。また password にパスワードを指定しています(上の例では P@ssw0rd を指定します)。それぞれ自分の情報に書き換えて実行してください。すると青字のような JSON テキストが返ってきます。この中の access_token の値(青太字の部分)がアクセストークンです。実際にはかなり長い文字列になっているはずですが、これを使って (2) 以降で API を実行します。


(2) API の実行

アクセストークンが取得できたら、その情報を使って Cloud Foundry API を実行します。Cloud Foundry API そのもののリファレンスはこちらを参照ください:
https://apidocs.cloudfoundry.org/231/

例えば「現在利用中のアプリケーションランタイムの一覧を取得」するには、この API を使います:
https://apidocs.cloudfoundry.org/231/apps/list_all_apps.html

具体的には以下の様な curl コマンドを実行します。ヘッダ情報(Authorization ヘッダ)に上記で取得したアクセストークンを指定しています:
# curl -H"Authorization: bearer (accessToken)" https://api.ng.bluemix.net/v2/apps

{
 "total_results": 15,
 "total_pages": 1,
   :
   :
 "resources":[
  {
   "metadata": {
    "guid": "(appGuid1)",
    "url": "/v2/apps/(appGuid1)",
    "created_at": "2015-03-09T02:49:49Z",
    "updated_at": "2016-02-20T06:23:39Z"
   },
    :
    :
  },
  {
   "meatadata": {
    "guid": "(appGuid2)",
     :
     :
  },
     :
     :
  }
] }

"resources" 内に配列形式でランタイムアプリケーションの情報が含まれているはずです。各ランタイムアプリケーションにはアプリケーション GUID と呼ばれる ID が割り振られており、その値は各ランタイムアプリケーション内の metadata.guid として確認できます。

では、今度はこのアプリケーション GUID を使って、このランタイムアプリケーションの環境変数情報を API で確認してみましょう。具体的にはこちらの API を利用します:
https://apidocs.cloudfoundry.org/231/apps/get_the_env_for_an_app.html
# curl -H"Authorization: bearer (accessToken)" https://api.ng.bluemix.net/v2/apps/(appGuid1)/env

{
 "staging_env_json": {
  "BLUEMIX_REGION": "ibm:yp:us-south"
 },
 "running_env_json": {
  "BLUEMIX_REGION": "ibm:yp:us-south"
 },
 "environment_json": {
 },
 "system_env_json": {
  "VCAP_SERVICES": {
   "relationship_extraction": [
    {
     "name": "Relationship Extraction-dc",
     "label": "relationship_extraction",
     "tags": [
      "ibm_beta",
      "watson",
      "ibm_created",
      "ibm_dedicated_public"
     ],
     "plan": "relationship_extraction_free_plan",
     "credentials": {
      "url": "https://gateway.watsonplatform.net/relationship-extraction-beta/api",
      "sids": [
       {
        "sid": "ie-es-news",
        "description": "information extraction from Spanish news"
       },
       {
        "sid": "ie-en-news",
        "description": "information extraction from English news"
       }
      ],
      "username": "(username)",
      "password": "(password)"
     }
    }
   ],
    :
    :
    :
   ]
  }
 },
 "application_env_json": {
   :
   :
 }
}

(appGuid1) に上記で確認したアプリケーション GUID を指定して実行します。すると上記のようなフォーマットで、このランタイムアプリケーションの環境変数情報が(VCAP_SERVICES もそれ以外も)まとめて取得できます。特に VCAP_SERVICES の credentials(上記の青太字部分)にはバインドしているサービスの接続情報が含まれており、その値を外部から API で確認できたことになります。


curl(HTTP) だけで Cloud Foundry API を Bluemix に対して使うことができる、ということが確認できました。これで複数のランタイムアプリケーションのステータスを確認する、といった管理用のアプリケーションも作れそうです。もちろん管理用途だけでなく、Bluemix のダッシュボードで実現しているようなアプリケーションを独自に作る、といったことも含めてできそうです。

 

Stackato を使ってプライベート環境に構築した Cloud Foundry 環境に、App Store というアプリケーション一覧からアプリケーションをデプロイしてみます。Stackato 環境構築の手順はこちらを参照してください:
Stackato を導入してプライベートな Cloud Foundry 環境を(KVM に)構築する
 ↑これの続きです


Stackato 管理コンソールにログインして、最初のページを下にスクロールすると "Deploy from the App Store" と書かれたリンクがあります。ここをクリックします:
2014051501


"App Store" という、Stackato 対応アプリケーション(正確にはサーバー&アプリケーション)の一覧が表示されます。CMS の Joomla やアプリケーション開発フレームワークの cakePHP など、メジャーどころが結構対応しています。これらは全て以下に紹介する簡単な手順で Stackato にデプロイできるようになっています:
2014051502


試しに、ブログや CMS では定番の1つになっている WordPress をデプロイしてみます。一覧の最後の方までスクロールして、"WordPress" を見つけたら、"Deploy App" ボタンをクリックします:
2014051503


WordPress アプリケーションサーバーのデプロイ情報を入力します。といってもここで気をつけるべきは一番上の "App Name" 欄だけです。デフォルトで設定されている名称をそのまま使ってもいいし、変更してもいいのですが、これがアプリケーションサーバー名の一部(****.stackato-mm7d.local の **** 部)になります。とりあえずこの例では "wordpress-y7unx" という名称にしています。最後に "Deploy Application" ボタンをクリックすると Stackato 環境にデプロイが開始されます:
2014051504


デプロイ中の画面はこんな感じでログが表示されます。しばらく待ちます・・・:
2014051505


ログに "Created app 'wordpress-y7unx(App Nameの値)'" と表示されて、ログの動きが止まったらデプロイが完了しています:
2014051506


この状況で画面左の "Instance" をクリックすると、Stackato 環境内で動いているサーバーインスタンスの一覧が表示されます。先程作成した WordPress サーバーがちゃんと Stackato 内で動いていることが確認できます。またこの画面から再起動などの管理オペレーションが可能になっています:
2014051507
 ↑仮想環境の KVM の中で動いている Stackato の中で動いている WordPress サーバー、です


では実際のアプリケーションにアクセスしてみます。

・・・が、その前に、このアプリケーションは Stackato 内で動いていて、IP アドレス自体は Stackato と同じものです。(恐らく VirtualHost 設定などで)アクセスサーバー名で切り替えられるようなので、この WordPress にアクセスするには改めて /etc/hosts を編集するなどして、サーバー名(wordpress-y7unx.stackato-mm7d.local)でアクセスできるようにしておく必要があります。

前回も紹介したように、ブラウザを利用するマシンの hosts ファイルを更に変更して、サーバー名と IP アドレスの対応を追加しておきます:
192.168.0.101 stackato-mm7d.local api.stackato-mm7d.local wordpress-y7unx.stackato-mm7d.local
(↑内容は各自の環境に合わせるようにして赤字部分を追加します


そしてブラウザで http://wordpress-y7unx.stackato-mm7d.local/ を開くと、、、WordPress の初期設定画面が表示されています。あっけなく動いてますね:
2014051508


初期設定を済ませれば、そのまま WordPress を使いはじめることができます:
2014051509


この WordPress の例に限らず、Stackato の App Store には初めから使えるアプリケーションが数多く用意されているので、これらを使ってアプリケーションをすぐに構築したり、ミドルウェア環境を手早く用意する、といったことができそうです。この WordPress アプリケーションの場合は 128MB メモリ環境で動作するようなので、これ1つ作った時点であればまだまだ余裕があるので他のアプリケーションを同時に作って動かす、ということもできると思っています(他のリソースはともかくメモリ的には)。

今回使った Stackato の mini Cloud Foundry 環境の場合はメモリ上限が 4GB と比較的小規模運用が前提になっていますが、この範囲で収まる使い方であれば、社内やチーム内利用には充分すぎる環境だと思います。仮に収まりきらなくなった場合でも、(有料の)上位エディションに移行したり、各社から提供されている Cloud Foundry ベースの環境に移行ことで運用先に困ることはないと思っています。 

こういう移行選択肢がある、ということがオープン環境の素晴らしいところです。


このページのトップヘ