IK.AM

@making's tech note


Cloud FoundryにSpring Boot/Java EEアプリケーションをデプロイしよう

🗃 {Service/PaaS/CloudFoundry}
🏷 Cloud Foundry 🏷 Spring Boot 🏷 Java EE 
🗓 Updated at 2015-12-05T10:15:32Z  🗓 Created at 2015-12-05T10:15:32Z   🌎 English Page

Java EE アドベントカレンダー 2015 5日目の記事です。

Cloud FoundryにJavaアプリをデプロイする方法を紹介します。

Cloud Foundryとは

Cloud FoundryはオープンソースのPaaSプラットフォームです。

PaaSというとHerokuやGoogle App Engine、AWS Elastic Beanstalkあたりを思うかもしれませんが、これらはプロプライエタリなPaaSであり、Cloud Foundryとは若干カテゴリが異なります。Cloud FoundryはOSSのオープンPaaSなので、通常はIaaS(AWS, OpenStack, VMWare vSphereなど)や普通のLinux上にインストールすることもできます。先日、Azureでも利用できることがMicrosoftからアナウンスされました。 同様なオープンPaaSにはOpenShiftがあります。

Cloud FoundryはCloud Foundry FoundationというJavaでいうところのJCPのような標準団体で開発されています。PivotalやIBMが中心のようですが、日本からもNTT、富士通、日立が参加しています

色々な会社がCloud FoundryをベースにパブリックなPaaSサービスを展開したり、自社開発向けのPaaS基盤を作成したりしています。

有名なパブリックCloud Foundryには

があります。自分でPaaSのインストールをする手間が省けます。 日本国内でも

でCloud Foundryが使用されています。

Cloud Foundryを使用しているこれらのサービスに対してはどれも同じコマンドでアプリケーションをデプロイすることができ、移植性が高いです。 各社は周辺サービスや運用機能、管理画面、料金体系などで差別化しているようです。

自社のPaaS基盤を構築する場合は、OSSを自前でインストールして運用するか、Cloud foundryのディストリビューション(Linuxに対するRedHat Enterprise Linuxみたいなもの)を利用することになります。

ディストリビューションで有名なものには

があります。 PCFはOSS版に含まれていない様々なサービス(Hadoop, RabbitMQ, Neo4J, Riak, Cassandra, Jenkins, Spring Cloudなど)を含んでいたり、運用面でもOSパッチなどソフトウェアアップデートをダウンタイムなしに実施していく機能があったりで、使えている人が羨ましい限りです。

先日、NTTデータがアジャイル開発基盤としてPCFを利用することをニュースリリースしました。 また12/3に行われたPivotal Japan Summit 2015でYahoo! Japanが自社の次期PaaS基盤としてPCFを採用することを発表しました

日本でもじわじわCloud Foundryの採用が進んできていますね。

Cloud Foundryの概要は↓の資料がわかりやすいです。

https://speakerdeck.com/ozzozz/tokyo

Cloud Foundryを使ってみよう

前置きが長くなりましたが、早速Cloud Foundryを使ってアプリケーションをデプロイしましょう。

今回はPivotal Web Servicesを使用します。60日間の無料期間があります。無料期間はクレジットカードの登録も不要なので気軽に利用できると思います。それ以降はクレジットカードを登録し、起動しているアプリのメモリ量 x 時間に従って課金されます($0.03/GB-hour)。 無料期間は計2GB、10アプリまで運用することができます。

Cloud FoundryではアプリはHerokuと同じくbuildpackという仕組みでビルドされます。 標準で対応している言語(というかランタイム)は

  • Java
  • Node.js
  • Ruby
  • Binary
  • Go
  • PHP
  • Python
  • Staticfile

です。当然、本記事ではJavaを扱いますが、Java以外も使い方は同じです。 (ぶっちゃけ、JavaよりもGoで書くほうがメモリ使用量が少ないので安く運用できます)

JavaアプリはSpring Bootのような実行可能なjarの相性が良いのは間違いありませんが、 普通のwar形式でもbuildpackがTomcatを埋め込んでくるので使えますし、Java EEも利用可能です。いまのところWebSphere Liberty Profileだけですが。

また、自分でbuildpackを作ることもできるので、標準ラインナップが気に入らなければ、自作すればだいたい何でもできるでしょう。

ちなみにCloud Foundryの最新版ではbuildpack以外にもDockerイメージや.NETアプリケーションに対応しています。

PWSにサインアップ

こちらからアカウントを作って下さい。

signup.png

私は既に登録済みで、再現できないのでこの後の手順は割愛します・・・簡単です。

Organizationの作成

サインアップがおわったら、まず最初にOrganizationを作成します。 Organizationはプロジェクト単位のようなもので、メンバー情報を紐づけることができます。課金もOrganization単位です。

アカウント作成後はこちらからログインして、左の「ORG」の右の「∨」時の記号をクリックしてOrganizationを作成します。

スクリーンショット 2015-12-05 14.09.53.png

Org名を入力して、「Create Org」をクリックしてください。 Organizationができると以下のような画面ができます。

スクリーンショット 2015-12-05 14.33.48.png

Organizationの下にはSpaceという単位があります。Spaceは環境のようなもので、「開発」、「ステージング」、「プロダクション」のような単位で作成します。デフォルトでdevelopmentが作られています。Spaceの下にApplicationがデプロイされます。

コマンドラインインターフェースのインストール

ここまで画面をぽちぽちしてきましたが、Cloud Foundryの操作はREST APIで用意されており、CLI(cfコマンド)で実行可能です。

CLIはこちらからダウンロードしてください。

Macの場合はbrewで以下のようにインストールすることもできます。

$ brew tap pivotal/tap
$ brew install cloudfoundry-cli

記事作成時点でのcfコマンドの最新版は6.14です。

$ cf -v
cf version 6.14.0+2654a47-2015-11-18

cfコマンドはPWS専用のツールではなく、全てのCloud Foundryサービスで利用可能です(CF v1のものを除く)。PWSを操作するには、まずAPIのエンドポイントを設定する必要があります。

$ cf api api.run.pivotal.io
Setting api endpoint to api.run.pivotal.io...
OK

                   
API endpoint:   https://api.run.pivotal.io (API version: 2.43.0)   
Not logged in. Use 'cf login' to log in.

次にログインします。

$ cf login
API endpoint: https://api.run.pivotal.io

Email> メールアドレス

Password> パスワード
Authenticating...
OK

Targeted org maki-org

Targeted space development


                   
API endpoint:   https://api.run.pivotal.io (API version: 2.43.0)   
User:           メールアドレス   
Org:            maki-org   
Space:          development 

対象のOrgとSpaceが選択されます。先ほど作成したOrgが使用されていますことがわかります。

アプリケーションのデプロイ

いよいよアプリケーションをデプロイします。まずは簡単なSpring Bootアプリを使います。一応、Java EEアドベントカレンダーなので、後でJava EEアプリもデプロイします。

Javaアプリのデプロイは基本的に

  1. jar or warを作成
  2. cf push

以上です。簡単。

以下のようなアプリケーションを使用します。getenvのところは今は気にしないでください。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class HelloPwsApplication {

    @RequestMapping("/")
    String hello() {
        return "Hello from " + System.getenv("CF_INSTANCE_ADDR");
    }

    public static void main(String[] args) {
        SpringApplication.run(HelloPwsApplication.class, args);
    }
}

GitHubにpushしてあるので、cloneしてビルドしてください。

$ git clone https://github.com/making/hello-pws
$ cd hello-pws
$ ./mvnw package

デプロイは基本的に

$ cf push hello-pws -p target/hello-pws.jar

で良いのですが、今回はメモリをけちって-mオプションをつけます。

cf pushの後はhello-pwsはドメイン内でユニークである必要があり、重複している場合はエラーになります。本記事の内容を試す場合は、別の名前を使用することをお勧めします。

$ cf push hello-pws -p target/hello-pws.jar -m 256M
Creating app hello-pws in org maki-org / space development as メールアドレス...
OK

Creating route hello-pws.cfapps.io...
OK

Binding hello-pws.cfapps.io to hello-pws...
OK

Uploading hello-pws...
Uploading app files from: target/hello-pws.jar
Uploading 485.1K, 89 files
Done uploading               
OK

Starting app hello-pws in org maki-org / space development as メールアドレス...
Creating container
Successfully created container
Downloading app package...
Downloaded app package (11.7M)
No buildpack specified; fetching standard buildpacks to detect and build your application.
Downloading buildpacks (staticfile_buildpack, java_buildpack, ruby_buildpack, nodejs_buildpack, go_buildpack, python_buildpack, php_buildpack, liberty_buildpack, binary_buildpack)...
Downloading staticfile_buildpack...
Downloading java_buildpack...
(略)
Staging...
-----> Java Buildpack Version: v3.3.1 | https://github.com/cloudfoundry/java-buildpack.git#063836b
-----> Downloading Open Jdk JRE 1.8.0_65 from https://download.run.pivotal.io/openjdk/trusty/x86_64/openjdk-1.8.0_65.tar.gz (3.9s)
       Memory Settings: -Xmx160M -Xms160M -XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=64M -Xss853K
-----> Downloading Spring Auto Reconfiguration 1.10.0_RELEASE from https://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.10.0_RELEASE.jar (0.0s)
Exit status 0
Staging complete
Uploading droplet, build artifacts cache...
Uploading droplet...
Uploading build artifacts cache...
Uploaded build artifacts cache (44.7M)
Uploaded droplet (56.7M)
Uploading complete

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

App started


OK

App hello-pws was started using this command `CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-2.0.1_RELEASE -memorySizes=metaspace:64m.. -memoryWeights=heap:75,metaspace:10,native:10,stack:5 -memoryInitials=heap:100%,metaspace:100% -totMemory=$MEMORY_LIMIT) && SERVER_PORT=$PORT $PWD/.java-buildpack/open_jdk_jre/bin/java -cp $PWD/.:$PWD/.java-buildpack/spring_auto_reconfiguration/spring_auto_reconfiguration-1.10.0_RELEASE.jar -Djava.io.tmpdir=$TMPDIR -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh $CALCULATED_MEMORY org.springframework.boot.loader.JarLauncher`

Showing health and status for app hello-pws in org maki-org / space development as メールアドレス...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: hello-pws.cfapps.io
package uploaded: Sat Dec 5 06:26:35 UTC 2015
stack: cflinuxfs2
buildpack: java-buildpack=v3.3.1-https://github.com/cloudfoundry/java-buildpack.git#063836b java-main open-jdk-like-jre=1.8.0_65 open-jdk-like-memory-calculator=2.0.1_RELEASE spring-auto-reconfiguration=1.10.0_RELEASE

     state     since                    cpu    memory        disk           details   
#0   running   2015-12-05 03:27:34 PM   0.0%   79M of 256M   162.7M of 1G

PWSではデフォルトで[APPNAME].cfapps.ioにルーティングされます。 アクセスしてみましょう。

$ curl http://hello-pws.cfapps.io
Hello from 10.10.114.65:64587

アプリケーションが簡単にデプロイできることがわかりました。

ログは

$ cf logs hello-pws --recent

で確認できます。

PWSのSpace管理画面では以下のように表示されます。

スクリーンショット 2015-12-05 15.37.07.png

また、アプリケーションの画面では以下のように表示されます。

スクリーンショット 2015-12-05 15.39.45.png

Cloud Foundryの運用面を試そう

Cloud Foundryの良さはデプロイが簡単なことだけではありません。運用面でも色々な優れた機能があります。

簡単スケール

アプリケーション画面の右上の「Configuration」に「Instances」と「Memory Limit」が見えると思います。ここを変更するだけでアプリケーションをスケールさせることができます。奮発して4インスタンスにスケールアウトしてみます。

スクリーンショット 2015-12-05 15.43.06.png

あっという間にスケールアウトしました。

スクリーンショット 2015-12-05 15.45.35.png

Cloud Foundryにはルーターが含まれており、複数のインスタンスが設定不要でロードバランスされます。

http://hello-pws.cfapps.ioに何度かアクセスすると、4種類のインスタンスからレスポンスが返ってきているのがわかります。

$ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo ;done
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.114.43:61547
Hello from 10.10.115.78:62878
Hello from 10.10.115.91:60224
Hello from 10.10.114.43:61547
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.114.43:61547
Hello from 10.10.115.78:62878
Hello from 10.10.114.43:61547
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.115.78:62878
Hello from 10.10.114.43:61547
Hello from 10.10.114.65:64587

スケールの変更はコマンドラインからも行えます。

$ cf scale hello-pws -i 4

自動復旧

今回デプロイしたアプリケーションにはSpring Boot Actuatorのシャットダウン機能を有効にしています。

以下のアクセスでインタンスが落ちます。

$ curl -X POST http://hello-pws.cfapps.io/shutdown
{"message":"Shutting down, bye..."}

この状態で再度アプリケーションにアクセスしましょう。

$ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo; done
Hello from 10.10.115.78:62878
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.114.65:64587
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.115.78:62878
Hello from 10.10.114.65:64587

さっきまでいた10.10.114.43:61547からのレスポンスがなくなっていることがわかります。 ルーターがインスタンスのダウンを検知して、ロードバランス対象から外してくれます。 そして、さらに素晴らしいことにCloud Foundryはダウンしたインスタンスの復旧を試みます。しばらくして再度アプリケーションにアクセスすると、

$ for i in `seq 1 20`; do curl http://hello-pws.cfapps.io; echo; done
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.115.78:62878
Hello from 10.10.114.60:63367
Hello from 10.10.114.60:63367
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878
Hello from 10.10.114.60:63367
Hello from 10.10.114.60:63367
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.114.65:64587
Hello from 10.10.115.91:60224
Hello from 10.10.115.78:62878

新たに10.10.114.60:63367が追加され、4インスタンスが保たれていることがわかります。

Cloud Foundryはアプリのデプロイが簡単なのはもちろんですが、ヘルスチェック付きLB構成のインフラを自分で構築する必要もなくて、とても楽チンです。

遊び終わったので1インスタンスに戻しておきます。

$ cf scale hello-pws -i 1
Scaling app hello-pws in org maki-org / space development as メールアドレス...
OK

オートスケール

オートスケールの機能はCloud Foundry標準では用意されていません。自分で用意する必要があります。ただしPWSやPCFはオートスケール用のサービスを提供しています。

「Marketplace」というサービス一覧からアプリケーションへバインドするサービスとプランを選択できます。Marketplaceのラインナップは各社で異なります。

スクリーンショット 2015-12-05 17.15.59.png

App Autoscalerがオートスケーリング用のサービスです。現時点でPWSには無償のプランのみが用意されています。

スクリーンショット 2015-12-05 17.16.12.png

詳細はこちらを参照してください。

Blue/Greenデプロイメントを実現

Cloud Foundryの機能を使うことでBlue/Greenデプロイメントというダウンタイムをできるだけ減らすリリーステクニックを簡単に実現できます

Blue/Greenデプロイメントは簡単にいうと、Blueと呼ばれる現行バージョンとGreenと呼ばれる次期バージョンを同時にプロダクション環境にデプロイし、Greenを十分にテストした後、Greenにルーティングを向くように変更し、Blueへのルーティングを外すという手法です。

まずはcf routesコマンドでルーティング情報を確認します。

$ cf routes
Getting routes as メールアドレス ...

space         host        domain      apps   
development   hello-pws   cfapps.io   hello-pws   

アプリケーションをバージョンアップします。(レスポンスの文字列を変えるだけ)

$ git checkout v2
$ ./mvnw clean package

これをGreenとして別のアプリ名でデプロイします。

$ cf push hello-pws2 -p target/hello-pws.jar -m 256M

再度cf routesコマンドでルーティング情報を確認しましょう。

$ cf routes
Getting routes as メールアドレス ...

space         host         domain      apps   
development   hello-pws    cfapps.io   hello-pws   
development   hello-pws2   cfapps.io   hello-pws2

ちなみにアプリ名とホスト名を別にしたい場合は-nオプションで指定できます。

$ curl http://hello-pws2.cfapps.io
Hello v2 from 10.10.115.76:62708

Green環境にアクセスして問題ないことを確認したので、hello-pws2アプリをhello-pwsへのアクセスでルーティングされるようにマッピングします。

$ cf map-route hello-pws2 cfapps.io -n hello-pws
Creating route hello-pws.cfapps.io for org maki-org / space development as メールアドレス...
OK
Route hello-pws.cfapps.io already exists
Adding route hello-pws.cfapps.io to app hello-pws2 in org maki-org / space development as メールアドレス...
OK

cf routesで確認すると

$ cf routes
Getting routes as メールアドレス ...

space         host         domain      apps   
development   hello-pws    cfapps.io   hello-pws,hello-pws2   
development   hello-pws2   cfapps.io   hello-pws2 

この時点でhello-pws.cfapps.ioはBlueとGreenのどちらかにルーティングされます。

$ curl http://hello-pws.cfapps.io
Hello from 10.10.114.65:64587
$ curl http://hello-pws.cfapps.io
Hello v2 from 10.10.115.76:62708

次にBlueへのルーティングを外します。

$ cf unmap-route hello-pws cfapps.io -n hello-pws
Removing route hello-pws.cfapps.io from app hello-pws in org maki-org / space development as メールアドレス...
OK

再度ルーティング情報を確認しましょう。

$ cf routes
Getting routes as メールアドレス ...

space         host         domain      apps   
development   hello-pws    cfapps.io   hello-pws2   
development   hello-pws2   cfapps.io   hello-pws2  

これで無事にhello-pwsがバージョンアップされました。

hello-pws2からのルーティングは不要なのでアンマップしておきます。

cf unmap-route hello-pws2 cfapps.io -n hello-pws2

この段階で前バージョンのアプリへのルーティングは無くなりましたが、アプリ自体は存在しています。

$ cf apps
Getting apps in org maki-org / space development as メールアドレス...
OK

name         requested state   instances   memory   disk   urls   
hello-pws    started           1/1         256M     1G        
hello-pws2   started           1/1         256M     1G     hello-pws.cfapps.io 

新バージョンに予期せぬ不具合が生じた場合に前バージョンを切り戻すということも簡単です。

前バージョンが不要になった場合は削除すれば良いです。

$ cf delete hello-pws

Really delete the app hello-pws?> y
Deleting app hello-pws in org maki-org / space development as メールアドレス...
OK

Cloud Foundryを使うとデプロイが本当に簡単になります。

データベースの利用

Cloud Foundryではデータベースはサービスとして用意されており、それをアプリにバインドする形でアクセスできます。

Cloud FoundryではMarketplaceという形でサービスが公開されています。cf marketplaceコマンドで一覧表示できます。

$ cf marketplace
Getting services from marketplace in org maki-org / space development as メールアドレス...
OK

service          plans                                                                                description   
3scale           free_appdirect, basic_appdirect*, pro_appdirect*                                     API Management Platform   
app-autoscaler   bronze, gold                                                                         Scales bound applications in response to load (beta)   
blazemeter       free-tier, basic1kmr*, pro5kmr*                                                      Performance Testing Platform   
cedexisopenmix   opx_global*, openmix-gslb-with-fusion-feeds*                                         Openmix Global Cloud & Data Center Load Balancer   
cedexisradar     free-community-edition                                                               Free Website& Mobile App Performance Reports   
cleardb          spark, boost*, amp*, shock*                                                          Highly available MySQL for your Apps.   
cloudamqp        lemur, tiger*, bunny*, rabbit*, panda*                                               Managed HA RabbitMQ servers in the cloud   
cloudforge       free, standard*, pro*                                                                Development Tools In The Cloud   
elephantsql      turtle, panda*, hippo*, elephant*                                                    PostgreSQL as a Service   
flashreport      trial, basic*, silver*, gold*, platinum*                                             Generate PDF from your data   
ironworker       production*, starter*, developer*                                                    Job Scheduling and Processing   
loadimpact       lifree, li100*, li500*, li1000*                                                      Automated and on-demand performance testing   
memcachedcloud   100mb*, 250mb*, 500mb*, 1gb*, 2-5gb*, 5gb*, 30mb                                     Enterprise-Class Memcached for Developers   
memcachier       dev, 100*, 250*, 500*, 1000*, 2000*, 5000*, 7500*, 10000*, 20000*, 50000*, 100000*   The easiest, most advanced memcache.   
mongolab         sandbox                                                                              Fully-managed MongoDB-as-a-Service   
newrelic         standard                                                                             Manage and monitor your apps   
pubnub           free                                                                                 Build Realtime Apps that Scale   
rediscloud       100mb*, 250mb*, 500mb*, 1gb*, 2-5gb*, 5gb*, 10gb*, 50gb*, 30mb                       Enterprise-Class Redis for Developers   
searchify        small*, plus*, pro*                                                                  Custom search you control   
searchly         small*, micro*, professional*, advanced*, starter, business*, enterprise*            Search Made Simple. Powered-by Elasticsearch   
sendgrid         free, bronze*, silver*                                                               Email Delivery. Simplified.   
stamplay         plus*, premium*, core, starter*                                                      API-first development platform   
statica          starter, spike*, micro*, medium*, large*, enterprise*, premium*                      Enterprise Static IP Addresses   
temporize        small*, medium*, large*                                                              Simple and flexible job scheduling for your application   
* The denoted service plans have specific costs associated with them. If a service instance of this type is created, a cost will be incurred.

TIP:  Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service.

サービス名はCloud Foundryの運用元によって異なります。例えば、PWSではelephantsqlがPostgreSQLのサービスです。

ここではPostgreSQLを使いましょう。プランは次の通りで、無償のプランはturtleです。

$ cf marketplace -s elephantsql
Getting service plan information for service elephantsql as メールアドレス...
OK

service plan   description                                            free or paid   
turtle         4 concurrent connections, 20MB Storage                 free   
panda          20 concurrent connections, 2GB Storage                 paid   
hippo          300 concurrent connections, 100 GB Storage             paid   
elephant       300 concurrent connections, 1000 GB Storage, 500Mbps   paid 

使用するサービスを作成しましょう。

$ cf create-service elephantsql turtle dev-pg
Creating service instance dev-pg in org maki-org / space development as メールアドレス...
OK

サービスはアプリとか異なり月額制です。アプリを作成すると即月額分課金されるのプランを間違えないように注意してください。

次にアプリにサービスをバインドします。

$ cf bind-service hello-pws2 dev-pg
Binding service dev-pg to app hello-pws2 in org maki-org / space development as メールアドレス...
OK
TIP: Use 'cf restage' to ensure your env variable changes take effect

使用しているサービス一覧はcf servicesで確認できます。

$ cf services
Getting services in org maki-org / space development as メールアドレス...
OK

name     service       plan     bound apps   last operation   
dev-pg   elephantsql   turtle   hello-pws2   create succeeded

アプリがサービスへアクセスするための

elephantsqlの場合、環境変数DATABASE_URLpostgres://ahjtcdvn:-2C8oL3NGvyIbcgB5OJEG4eayBD2bZqI@pellefant-01.db.elephantsql.com:5432/ahjtcdvnというような文字列が設定されます。

アプリに環境変数を埋め込み直すにはcf restage(コンテナの再作成)またはcf restart(アプリのみ再起動)を実行する必要があります。

通常はcf restart hello-pws2で良いです。ダウンタイムが発生するので、ここではBlue/Greenデプロイメントのことは忘れています。

そろそろ疲れてきたので、アプリ側の設定は割愛しますが、環境変数の文字列を元にDataSourceBeanを作成することになります。 Herokuのドキュメントを参照してください。

特にSpring Bootアプリの場合はCloud Foundryにデプロイすると自動でcloudプロファイルが有効になるので、Cloud Foundry上でのみ有効にしたい設定は@Profile("cloud")を指定するか、application-cloud.propertiesに定義しておくと良いでしょう。

Java EE 7アプリをデプロイしよう

最後にJava EEアドベントカレンダーなので、Java EEアプリもデプロイしちゃいます。

Cloud Foundryのアプリはbuildpackでビルドされるといいました。登録されているbuildpackはcf buildpacksで確認できます。

$ cf buildpacks
Getting buildpacks...

buildpack              position   enabled   locked   filename   
staticfile_buildpack   1          true      false    staticfile_buildpack-cached-v1.2.2.zip   
java_buildpack         2          true      false    java-buildpack-v3.3.1.zip   
ruby_buildpack         3          true      false    ruby_buildpack-cached-v1.6.8.zip   
nodejs_buildpack       4          true      false    nodejs_buildpack-cached-v1.5.2.zip   
go_buildpack           5          true      false    go_buildpack-cached-v1.6.3.zip   
python_buildpack       6          true      false    python_buildpack-cached-v1.5.1.zip   
php_buildpack          7          true      false    php_buildpack-cached-v4.2.1.zip   
liberty_buildpack      8          true      false    liberty_buildpack.zip   
binary_buildpack       9          true      false    binary_buildpack-cached-v1.0.1.zip  

PWSではWebSphere Liberty Profileのbuildpackが初めから組み込まれているので、 Java EE 7のアプリを簡単にデプロイできます。詳しくはこちらをご確認ください。

Spring Bootとほぼ同じJAX-RS版アプリをGitHubにプッシュしたのでcloneしてビルドしてください。

$ git clone https://github.com/making/hello-pws-javaee
$ cd hello-pws-javaee
$ mvn package

これをPWSにデプロイします。本来はserver.xmlというLibety Profileの設定ファイルを用意するとLibety Profile用のビルドパックが自動で選択されるのですが、今回はそれを作らず明示的にビルドパックを指定します。

$ cf push hello-pws-javaee -p target/hello-pws-javaee-1.0-SNAPSHOT -m 256M  -b https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git --no-start

ここでは--no-startをつけてアプリケーションが起動しないようにしておきます。

Liberty Profileを使う場合はIBM JVMのライセンスコードとLiberty Profileのライセンスコードを環境変数で渡す必要があり、アプリケーション起動の前に環境変数を設定する必要があるからです。

IBM Liberty-Licenseを読んでD/N: <ライセンス番号>を探してください。見つけたら

$ cf set-env hello-pws-javaee IBM_LIBERTY_LICENSE <ライセンス番号>

を実行してください。 同様にIBM JVM-Licenseを読んでD/N: <ライセンス番号>を探してください。見つけたら

$ cf set-env hello-pws-javaee IBM_JVM_LICENSE <ライセンス番号>

を実行してください。 環境変数の設定が完了したら、cf startで起動します。

$ cf start hello-pws-javaee
Starting app hello-pws-javaee in org maki-org / space development as メールアドレス...
Creating container
Successfully created container
Downloading app package...
Downloaded app package (2K)
Downloaded buildpacks
Staging...
-----> Liberty Buildpack Version: f489cee | https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git#f489cee
-----> Avoid Trouble: Specify a minimum of 512M as the Memory Limit for your apps when using IBM JDK.
-----> Downloading IBM 1.8.0_sr1fp10 JRE from https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/jre/1.8.0/linux/ibm-java-jre-8.0-1.10-x86_64-archive.bin ... (11.3s)
         Expanding JRE to .java ... (20.3s)
-----> Downloading from https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/wlp/8.5.5.7/wlp-webProfile7-8.5.5.7.zip ... (7.0s)
         Installing archive ... (0.7s)
-----> Warning: Liberty feature set is not specified. Using the default feature set: ["beanValidation-1.1", "cdi-1.2", "ejbLite-3.2", "el-3.0", "jaxrs-2.0", "jdbc-4.1", "jndi-1.0", "jpa-2.1", "jsf-2.2", "jsonp-1.0", "jsp-2.3", "managedBeans-1.0", "servlet-3.1", "websocket-1.1"]. For the best results, explicitly set the features via the JBP_CONFIG_LIBERTY environment variable or deploy the application as a server directory or packaged server with a custom server.xml file.
-----> Liberty buildpack is done creating the droplet
Exit status 0
Staging complete
Uploading droplet, build artifacts cache...
Uploading build artifacts cache...
Uploading droplet...
Uploaded build artifacts cache (172.2M)
Uploaded droplet (167.5M)
Uploading complete

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

App started


OK

App hello-pws-javaee was started using this command `.liberty/create_vars.rb wlp/usr/servers/defaultServer/runtime-vars.xml && WLP_SKIP_MAXPERMSIZE=true JAVA_HOME="$PWD/.java" WLP_USER_DIR="$PWD/wlp/usr" .liberty/bin/server run defaultServer`

Showing health and status for app hello-pws-javaee in org maki-org / space development as メールアドレス...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: hello-pws-javaee.cfapps.io
package uploaded: Sat Dec 5 09:54:17 UTC 2015
stack: cflinuxfs2
buildpack: https://github.com/cloudfoundry/ibm-websphere-liberty-buildpack.git

     state     since                    cpu    memory         disk          details   
#0   running   2015-12-05 06:57:24 PM   0.0%   688K of 256M   27.8M of 1G      

アクセスしてみましょう。

$ curl http://hello-pws-javaee.cfapps.io/app/hello
Hello from 10.10.115.89:64684

できました。スケールアウトも同様。

$ cf scale hello-pws-javaee -i 4
Scaling app hello-pws-javaee in org maki-org / space development as メールアドレス...
OK
$ for i in `seq 1 20`; do curl http://hello-pws-javaee.cfapps.io/app/hello; echo; done
Hello from 10.10.114.39:64622
Hello from 10.10.115.89:64684
Hello from 10.10.115.65:60483
Hello from 10.10.115.65:60483
Hello from 10.10.115.89:64684
Hello from 10.10.115.89:64684
Hello from 10.10.115.65:60483
Hello from 10.10.115.65:60483
Hello from 10.10.114.75:60232
Hello from 10.10.114.75:60232
Hello from 10.10.115.89:64684
Hello from 10.10.115.65:60483
Hello from 10.10.114.75:60232
Hello from 10.10.114.39:64622
Hello from 10.10.114.75:60232
Hello from 10.10.115.89:64684
Hello from 10.10.115.89:64684
Hello from 10.10.115.89:64684
Hello from 10.10.115.65:60483
Hello from 10.10.114.75:60232

できました。


本記事でCloud FoundryのPaaSプラットホームとしての素晴らしさを少し体験できたかと思います。本記事の内容は基本的にはPWS以外でも利用できます。IBM Bluemixも無料期間があるので、是非にアプリをデプロイしてみてください。


✒️️ Edit  ⏰ History  🗑 Delete