IBM Bluemix Diegoランタイムの変更に備えよう

﻿
## はじめに
IBM Bluemix Cloud Foundry コンポーネントにも展開された Diego の話です。はじめに重要な話。IBM Bluemix では 2017/1/31(米国時間)にデフォルトのランタイムが Diego になる予定です。この記事が役立てば幸いです。

## 1. Diego開発の背景

### 1.1 コンテナ標準化の流れ
クラウドテクノロジーは目まぐるしく変わっていますが、2016年にさらに脚光をあびたテクノロジーの一つに コンテナをあげても良いかと思っています。諸議論はあると思いますが、コンテナを動作させるテクノロジーとして Docker もしくは Docker が採用するオープンなコンテナランタイム [runC](https://runc.io/) はもはや標準であると言えます。

Cloud Foundry もコンテナテクノロジーを採用していますが、Warden として登場したのは 2011年でした(おそらくそれ以前から開発はされていた）。2011年のコンテナテクノロジーは lxc が主流でしたが、大きすぎるという理由で独自の開発をしたようです。

2013年に dotCloud社が新しいPaaSの仕組みのために、Docker をオープンにして以来、lxcを超えて Dockerテクノロジー採用が増えてきました。また、コンテナ実行環境の標準化を進める団体 [Open Container Initiative (OCI)](https://www.opencontainers.org/) が設立されコンテナ稼働の標準が確立されつつあります。

Cloud Foundry Diego では様々な経緯はあったものの、最終的にコンテナ環境を標準にすることに決め、runC を採用しています。

### 1.2 コンテナクラスタ管理

コンテナ動作環境の標準化と並行して、コンテナを複数あるマシンにどう配置するか？　またどう監視するか？　といういわゆるオーケストレーション技術やクラスタ管理も進歩してきました。Google社は多くのシステムをコンテナで稼働していることで有名ですが、Google社が独自に発明した技術が [Borg][1] というものです。Borg の技術を一般に公開したのが Kubernetes と言われています。また、カルフォルニア大学バークレイ校で研究されていた Mesosテクノロジーが Twitter社やApple社に採用されることでこのクラスタ管理テクノロジーも急速に着目が上がってきました。

Cloud Foundry では Cloud Controller, Health Manager と呼ばれるモジュールがコンテナ配置、コンテナ死活監視機能を担っていますが、様々な課題を抱えていました。2014年に Onsi Fakhouri が新しい Diego に書き換える理由をこう説明しています([参考文献２][2])。


- Tight Coupling : Cloud Controller, Health Manager, DEA間の連携が密接すぎる。
- Domain Specific : アプリケーションしか動作しない
- Platform Specific: Linuxコンテナだけ

特に先に説明した Dockerのようなコンテナエコシステムを享受できないのも理由としてあげられています。

様々な経緯があり、最終的に Cloud Foundryを外部に提供するプロバイダーは Diego を採用することが認定プロバイダーとしての責務になることが決定しました。



## 2. さて Diegoとは？

### 2.1 Diego の特徴とメリット

Diegoは、コンテナ実行環境の標準化やオーケストレーション、クラスタ管理に関係する諸問題を解決するために新規に開発され、v1.0 が2016年11月23日にリリースされました。Diego は

>  **DEA + Go → Diego**

で Cloud Foundry で開発言語の標準となりつつあるGo言語で書かれています。既存のCloud Foundryアプリケーション互換性を担保する他、以下の特徴をもっています。

- セキュア通信がデフォルト
- buildpack、Docker イメージ、.NET アプリケーション対応
- ssh アクセスが可能
- クラスタリングのサポート
- 様々なタイプのジョブの稼働 (LRP:Long Running Process, Task)

とくに Docker イメージのサポートは大きいのではないかと思われます。DockerHub には様々なソフトウェアが用意されているので、それを気軽に利用できるのは恩恵が深いと思われます。ただ、IBM Bluemix Publicではいまのところ利用できません(2016/12月時点）。



## 3. Diegoへの移行

### 3.1 初期設定

Diego がデフォルトのランタイムになっている場合は気にする必要はありませんが、DEAがデフォルトになっている場合や、DEAからDiegoに移行する場合（あるいはその逆）には Cloud Foundry へのアクセスに利用される "cf" コマンドに "Diego-Enabler" プラグインを導入する必要があります。

    $ cf install-plugin -f Diego-Enabler -r CF-Community
    Looking up 'Diego-Enabler' from repository 'CF-Community'
    10370188 bytes downloaded...
    Installing plugin diego-enabler_darwin_amd64...
    OK
    Plugin Diego-Enabler v1.2.2 successfully installed.

"Diego-Enabler" プラグインが正常に導入されると幾つかのコマンドが増えているはずです。

    $ cf plugins
    Listing Installed Plugins...
    OK

    Plugin Name     Version   Command Name        Command Help
    Diego-Enabler   1.2.2     enable-diego        Migrate app to the Diego runtime
    Diego-Enabler   1.2.2     disable-diego       Migrate app to the DEA runtime
    Diego-Enabler   1.2.2     has-diego-enabled   Report whether an app is configured to run on the Diego runtime
    Diego-Enabler   1.2.2     diego-apps          Lists all apps running on the Diego runtime that are visible to the user
    Diego-Enabler   1.2.2     dea-apps            Lists all apps running on the DEA runtime that are visible to the user
    Diego-Enabler   1.2.2     migrate-apps        Migrate all apps to Diego/DEA

### 3.2 移行にあたってアプリケーションコードを見直す

さて、Diego に移行する前にちょっとしたアプリケーションの見直しが必要になる場合があります。Diegoでは以下の環境変数が廃止されています。

|DEAの環境変数|Diegoでの環境変数|説明|
|:--|:--|:---|
|VCAP_APP_PORT| PORT | アプリケーションがlisten()するポート|
|VCAP_APP_HOST| なし　| アプリケーション名。最新DEAでも利用されていない|

特に VCAP_APP_PORT が使われている場合も多いと思われるので、この設定を見直します。また ルートなしコンポーネントの場合は Diego に移行した後に、 heath-check タイプを "none" に設定する必要があります。

    cf set-health-check APPLICATION_NAME none


このコマンド名をみると死活監視が行われなくなるのでは？と思われがちですが、これはあくまで死活監視機能のうちポートが開いているかどうかをオフにするだけですので、ご安心ください。ちなみに、DEAでは起動時にのみポートが開いているかどうかをチェックしていましたが、Diegoでは定期的にチェックするようになりました。したがって、アプリケーションがハングしているように見える場合（ポートにアクセスできない）場合はDiegoが再起動してくれます。

### 3.3 新規にアプリケーションを push する場合

Diegoがデフォルトのランタイムになっている場合は以下の対応は不要です。

    #1. --no-startオプションでアプリケーションを push します
    $ cf push APPLICATION_NAME --no-start

    #2. ランタイムに Diego を選択します。
    cf enable-diego APPLICATION_NAME

    #3. アプリケーションを開始します
    cf start APPLICATION_NAME



### 3.4 既存のアプリケーションを diego で稼働する場合

既存のアプリケーションがDEAで稼働している場合は、diego-enable フラグをたててアプリケーションを再ステージします。

    cf enable-diego APPLICATION_NAME
    cf restage APPLICATION_NAME



### 3.5 逆にアプリケーション実行環境を DEA に戻したい場合

仮にアプリケーション起動に問題があった場合には DEA に戻すことができます。

    cf disable-diego APPLICATION_NAME


### 3.6 簡単なサンプルで確認

折角なので簡単なサンプルを動かしてみましょう。セクション3.2で説明した VCAP_APP_HOST 環境変数が Diego では存在しないことを逆手にとって、アプリケーションが DEA か Diego で稼働しているかを判別してみます。

    # index.php ファイル
    <html>
    <head></head>
    <body>
    	<?php
    		$is_dea=getenv('VCAP_APP_HOST');

    		if ($is_dea) {
    			print("Running on DEA/Warden");
    		} else {
    			print("Running on Diego/Garden");
    		}

    	?>
    </body>
    <html>

index.php ファイルを作成します。同じディレクトリで アプリケーションを push します。ここでは DEA がデフォルトのランタイムであると仮定しています。

    $ cf push --random-route myphpapp -m 64M
    Creating route myphpapp-unsided-strainedness.mybluemix.net...
    OK
    -----> Uploading droplet (45M)

    0 of 1 instances running, 1 starting
    1 of 1 instances running

    App started
    requested state: started
    instances: 1/1
    usage: 64M x 1 instances
    urls: myphpapp-unsided-strainedness.mybluemix.net
    last uploaded: Thu Dec 1 08:06:36 UTC 2016
    stack: cflinuxfs2
    buildpack: php 4.3.10

         state     since                    cpu    memory         disk           details
    #0   running   2016-12-01 05:07:31 PM   0.3%   38.7M of 64M   124.7M of 1G

起動したアプリケーションをブラウザで開くと "Running on DEA/Warden" と出るはずです。

![running-on-dea.png](https://qiita-image-store.s3.amazonaws.com/0/74673/91c6701e-1bfa-df8d-d3fa-d611bd1fdec1.png)

このアプリケーションを Diego で動かします。

    $ cf enable-diego myphpapp
    Setting myphpapp Diego support to true
    OK

    Verifying myphpapp Diego support is set to true
    OK

    $ cf restage myphpapp
    requested state: started
    instances: 1/1
    usage: 64M x 1 instances
    urls: myphpapp-unsided-strainedness.mybluemix.net
    last uploaded: Thu Dec 1 08:06:36 UTC 2016
    stack: cflinuxfs2
    buildpack: php 4.3.10

         state     since                    cpu    memory         disk         details
    #0   running   2016-12-01 05:17:23 PM   0.0%   16.3M of 64M   126M of 1G

初めて Diego で動かす場合、おや？と思われたかもしれませんね。出てくるメッセージが微妙に異なっています。さて、ブラウザをリフレッシュしてみましょう。

![running-on-diego.png](https://qiita-image-store.s3.amazonaws.com/0/74673/a7cd5126-b277-442d-9030-ce896a25ed49.png)

Diegoで稼働しているようです。ログをみると CELL や　APP といった Diego 独自のメッセージが確認できるはずです (DEAの場合アプリケーションログは App/[X] )。

      2016-12-01T17:17:16.53+0900 [CELL/0]     OUT Creating container
      2016-12-01T17:17:18.12+0900 [CELL/0]     OUT Successfully created container
      2016-12-01T17:17:21.43+0900 [CELL/0]     OUT Starting health monitoring of container
      2016-12-01T17:17:22.01+0900 [APP/0]      OUT 08:17:22 httpd   | [Thu Dec 01 08:17:22.006181 2016] [mpm_event:notice] [pid 35:tid 140070285522752] AH00489: Apache/2.4.20 (Unix) configured -- resuming normal operations

## 4. まとめ

IBM Bluemix でも Diego がサポートされるようになりました。なんとなく、DEAが End of Life を迎えるから Diego 対応しただけじゃね？と思われるかも知れません。しかし、今後 Diego に対して機能が拡張されていくと思われるので、いままで以上に使える IBM Bluemix Cloud Foundry になるのではないかと思われます。

一つには、現在開発が進められているコンテナ間ネットワークです。現時点(2016/12)では他のコンテナと通信したい場合は、改めて Gorouter を通じて行われなければなりません。もしくはメッセージキューサービスなどを利用してメッセージのやり取りを実施しています。

コンテナ間ネットワークが実現できた場合には、

    cf allow-access frontend backend --port 9876 --protocol tcp

といった形で、フロントエンドとなるアプリケーション (frontend) と、
バックエンドサービス (backend) がプトコトルとポートを指定することで通信ができるようになるようです。

もう一つはDEAではできなかったクラスタ管理機能です。現在、[isolation segument][3] として開発が進められています。IBM Bluemix public環境では専用区画というものが存在しませんが、この機能が実現すると public な Cloud Foundry クラウド上でも専用区画を設けることができるようになるようです。




### 参考文献

[1]: http://research.google.com/pubs/archive/43438.pdf "Large-scale cluster management at Google with Borg (2015)""

[2]: http://www.slideshare.net/Pivotal/cloud-foundry-summit-2014-diego-reenvisioning-the-elastic-runtime "Diego: Re-envisioning the Elastic Runtime (Cloud Foundry Summit 2014)"
 
[3]:  https://docs.google.com/document/d/1JPjKxo0JT5rqKZV1XtpydL6ehlyKIk7ipNWMCz2xyKE/ "Isolation Segments in Cloud Foundry"

[1] http://research.google.com/pubs/archive/43438.pdf "Large-scale cluster management at Google with Borg (2015)""

[2] http://www.slideshare.net/Pivotal/cloud-foundry-summit-2014-diego-reenvisioning-the-elastic-runtime "Diego: Re-envisioning the Elastic Runtime (Cloud Foundry Summit 2014)"
 
[3]  https://docs.google.com/document/d/1JPjKxo0JT5rqKZV1XtpydL6ehlyKIk7ipNWMCz2xyKE/ "Isolation Segments in Cloud Foundry"