2013.04.19 g*ワークショップz apr2013-grails+cloud_foundry1. G*ワークショップZ - Apr 2013
Takeshi Morikawa(日本Cloud Foundryグループ 会員)
Yu Sudo (日本Grails/Groovyユーザーグループ 運営委員)
2. 自己紹介
名前
森川 健 (Takeshi Morikawa)
所属
NTTソフトウェア
技術開発センター OSS基盤技術部門 クラウド推進室 エンジニア
日本Cloud Foundryグループ(CFGRJP)会員
以前の業務
入社以来、無線VoIPソリューションの開発担当
モバイル端末向けの画面をGrailsを使って開発(view+controllerメイン)
OJTの方から「Ruby良いよ!」と聞いていた為、興味があった
現在
Grailsの経験
Cloud Foundryの中でRailsやRubyが使われている
…という事で昨年の4月よりCloud Foundry担当となりました
3. 自己紹介
名前
須藤 悠 (Yu Sudo)
所属
NTTソフトウェア
技術開発センター 生産技術部門 Grails推進室 “Grails Advocate”
日本Grails/Groovyユーザーグループ(JGGUG)運営委員
経歴
JavaでのWeb系試作システム開発
C++での通信ノード系大規模システム開発
GrailsでのWeb系試作システム開発
Grails開発支援、 Grails研修、Grails! Grails! Grails!
Grailsを用いたファイルアップローダ作成
http://www.ntts.co.jp/publish/column/tec/java_02/
5. 日本Cloud Foundryグループ(CFGRJP)
URL
http://www.cloudfoundry.gr.jp/
活動内容(設立趣意書より※)
本会は日本国内でのCloud Foundryの利用促進のため、以下
のような取り組みを実施してまいります。
Cloud Foundryに関するセミナー・勉強会の開催
Cloud Foundryに関する日本語による情報提供
コード改善のための各国コミュニティとの連携支援
ユーザ同士の交流促進 等
※ 日本Cloud Foundryグループ 設立趣意 http://www.cloudfoundry.gr.jp/prospectus
6. はじめる前に…
ハンズオンの準備はできていますか?
JDK ( 6 でも動きますが 7 が望ましい)
Grails (Mac/Linuxの方は GVM で!)
○ JavaやGrailsが使う環境変数もお忘れなく!
CloudFoundry.com のアカウント
○ https://my.cloudfoundry.com/signup
○ Promo code ないと待たされます
○ preshavedyak ってまだ使えるのかな…
準備がまだの人は、話を聞きながらやって
おいてください
8. PaaSとは
Platform as a Serviceの略です
IaaSの場合
仮想マシンの領域を借りて自分でOSを入れてDB入れる
等、サーバを自由に構築するものです。
つまりアプリを動かし、サービスを提供するには色々な
設定をしなくてはなりません。※
PaaSの場合
Webアプリケーションを稼働させるための基盤です。
DBやWebサーバの設定、運用をPaaSサービス事業者に
任せ、アプリ開発に専念出来ます。
※最近ではOps Worksのような仕組みができて構築が簡単になりPaaS領域を侵食しつつありますが
9. Cloud Foundryとは
オープンソースのPaaS基盤です
Githubでソースコードが公開されています
○ https://github.com/cloudfoundry
はじまり
SpringSourceがEC2上にJavaやGrails等の環境を構築できるように
したものだった(Ops Works等と似たようなアプローチだったようです)
現在は
様々なフレームワークに対応
IaaSに依存しない作り(物理マシン上でも構築可能)
○ Ubuntu 10.04 Server 64-bit 推奨
○ それ以外の場合はカスタムが必要
内部で使われている言語は主にRuby
現在、主なメンテナンスについてはVMware社からPivotal Initiative
に移っています
11. 利用可能なフレームワークとサービス
フレームワーク&言語
Spring
Grails
Scala, Play!
Node.js
Ruby, Rails, Sinatra
サービス(DB等)
MySQL
PostgreSQL
Redis
MongoDB
RabbitMQ
12. Cloud Foundryのコンポーネント(一部のみ紹介)
dea (droplet execution agent)
実際にユーザのWebアプリが動作するコンポーネント
Webアプリが実際に起動するポートは毎回異なる
stager
アプリ開発者がCloud Foundryにアプリをpush※した際
に、dea上で動作する形にファイルをまとめる
health manager
dea上で動作するアプリが設定された数のインスタンス
が起動しているか等をチェックするコンポーネント
※pushとはアプリケーションをClouf Foundry上にデプロイする事を指します
13. Cloud Foundryのコンポーネント(一部のみ紹介)
cloud controller
Cloud Foundry上のアプリケーション情報の管理
○ どのアプリを何個インスタンスを起動するか
○ 各アプリに紐づけた(bindされる)DBの接続情報
現在のバージョンではRailsによって実装されている
次世代バージョンではSinatraになる
14. Cloud Foundryのコンポーネント(一部のみ紹介)
router
NW機器のルータではありません!
アプリケーションやPaaSの利用者からhttpリクエスト
があった際にルーティングを行うコンポーネント
dea上で動作するユーザのWebアプリケーションの
ポートは起動や再起動で毎回変わりますが、router
を通して適切なdeaへのアクセスが可能となる
○ 例: http://hogehoge.cf.com/ にアクセスすると?
ある時は
- http://192.168.1.2:30381/
またある時は
- http://192.168.1.3:40181/
15. Cloud Foundryのコンポーネント(一部のみ紹介)
service-gateway / service-node
アプリケーションに紐づいた(bindされた)DB
等が動作するコンポーネント
その他に認証系コンポーネント等が存在し
ますが、今回は説明を省略します
uaa (user account & authentication)
acm (access control manager)
16. NATSについて
NATSとは?
EventMachineを使ったpub/subのメッセージング
システム(非同期I/O)
All-in-One構成(1つのVM上にすべてのコンポーネ
ント)を動作させる場合も1VM1コンポーネント
のマルチノード構成の場合もこの仕組みによって
連携を実現
17. Cloud Foundryのコンポーネントの特徴的な動作の例
ユーザ(開発者)がアプリをpushし
2インスタンス起動という要求を出す
2インスタンス 2インスタンス起動で
起動して! deaに聞いてみます!
く
http or https http or https ら
るー う
ど
こ
たー ん
と
ろー
らー
18. Cloud Foundryのコンポーネントの特徴的な動作の例
cloud controllerがnats server経由でdeaに確認
deaさんいます
か?
く
ら natsメッセージ な
う っ
ど つ
こ さー
ん
ばー
と
ろー 2インスタンス
起動できるdea
らー さんいます?
ポイント:cloud controllerはdeaがアプリを起動する余裕が
あるかだけでなく、今現在deaが何台いるのか知らない
19. Cloud Foundryのコンポーネントの特徴的な動作の例
1インスタンス
各deaが応答 なら!
natsメッセージ dea1
deaさん
いますか?
リソースがもう
ないです。。。
な dea2
っ
つ
さー
ばー
2インスタンス まだまだ
起動できるdea いけます!
さんいます? dea999
ポイント:dea2はリソースがないので応答しません。
この際に要求が1インスタンスだった場合は先に応答し
たdea1が選択されます。
20. Cloud Foundryのコンポーネントの特徴的な動作の例
cloud controllerがnats server経由でdea1とdea999に通知
dea1さん!アプ
リAをメモリ
128MBで起動し
てください
く
ら natsメッセージ な
う っ
ど つ
dea999さん! こ さー
アプリAをメモ ん
ばー
リ128MBで起動 と
してください ろー
らー
ポイント:起動に必要なファイルの受け渡し方法等を
通知
21. Cloud Foundryのコンポーネントの特徴的な動作の例
各deaが通知を元にファイルを取得し起動 起動しました!
dea1さん!アプリ natsメッセージ dea1
Aをメモリ128MBで
起動してください
な dea2
っ
つ
さー
ばー
dea999さん!アプリ
Aをメモリ128MBで dea999
起動してください 起動しました!
ポイント:ファイルを起動
23. パブリックなPaaSを利用
1. cloudfoundry.com(beta)(無料)
https://www.cloudfoundry.com/
2. その他のCloud Foundryを使ったPaaSサービス
日本の場合(例)
○ NTT CommunicationsのCloudn(2013年4月末まで無料)
http://www.ntt.com/cloudn/data/paas.html
国外の場合(例)
○ appfog等
http://get.appfog.com/CloudFoundryCoreCompatible
○ その他のPaaSサービスも以下のページで一覧できる
https://core.cloudfoundry.org/listings
24. 自前のPaaSを構築
1. Micro Cloud Foundryを使ってローカル環境の
仮想マシン上に構築
https://micro.cloudfoundry.com/
cloudfoundry.comのアカウントがあれば入手可能
2. github上のソースを使ってAll-in-One環境構築
https://github.com/cloudfoundry/vcap
3. github上のソースを使ってマルチノード構築
25. Cloud Foundryに接続する方法-1
vmcコマンドを使う
http://rubygems.org/gems/vmc
特徴
○ Rubyのgemでvmcというクライアントを使う方法
○ Grails開発者は別途Ruby/gemのインストールが必要
○ 現在比較的安定しているバージョンは0.3.18
gem install –v 0.3.18でインストール可能
0.3.23 でもよいが proxy 環境で泣く
○ Windowsの場合、Rubyとvmcを一緒にインストールし
てくれるインストーラがあります(手軽でおすすめ!)
インストーラのバイナリ(0.3.23ベース)
- http://cloudfoundry.gr.jp/downloads/vmc_installer/vmc_install
er_0.3.23-r1.9.3.exe
インストーラのソース
- https://github.com/nttlabs/vmc_installer
26. Cloud Foundryに接続する方法-2
Eclipse PluginやSTS/GGTSの拡張を使う
http://docs.cloudfoundry.com/tools/STS/configurin
g-STS.html
特徴
○ Rubyやgem、vmcを入れなくても使える
vcap-java-clientをラップしている
https://github.com/cloudfoundry/vcap-java-client
○ 基本的にGUI操作
○ マシンスペックに余裕があり、GUI環境が良い場合
はおすすめ
27. Cloud Foundryに接続する方法-3
Grailsのcloud-foundryプラグインを使う
http://grails.org/plugin/cloud-foundry
特徴
○ Rubyやgem、vmcを入れなくても使える
vcap-java-clientをラップしている
https://github.com/cloudfoundry/vcap-java-client
○ CUI操作
○ Grails開発環境であれば導入しやすい
今回のハンズオンではこちらを利用します
29. 本資料の作成環境
OS
Ubuntu 10.04.4 LTS (Lucid Lynx) 32bit server版
NW
proxyなし
Java
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) Client VM (build 23.6-b04, mixed mode)
Grails
Grails version: 2.1.1
30. アプリの作成
$ grails create-app morika
| Created Grails Application at /home/vagrant/morika
$
上記のアプリケーションの Cloud Foundry.com での
URLは morika.cloudfoundry.com となる
1つのCloud Foundry内で重複が許されないので注意
が必要です※
※ grails-app/conf/Config.groovy に
grails.plugin.cloudfoundry.appname=アプリ名を記述するか
アプリのpush(デプロイ)時に --appname=アプリ名 オプションで変更することも可能
31. Cloud Foundryの接続情報の設定
$HOME/.grails/settings.groovyの編集
$ vi /home/vagrant/.grails/settings.groovy
事前に登録したcloudfoundry.comのusernameとpasswordを設定します
grails.plugin.cloudfoundry.username = 'morikawa.takeshi@hogehoge.com'
grails.plugin.cloudfoundry.password = ‘hogehoge'
grails.plugin.cloudfoundry.target = 'http://api.cloudfoundry.com'
※ cloudfoundry.target は cloudfoundry.com の場合は記述しなくても問題ありませんが
その他のCloud Foundryサービスを利用する際は記述が必要です
32. Cloud Foundryプラグイン設定
ディレクトリ移動(create-appしたアプリのディレクトリに入る)
$ cd morika/
BuildConfig.groovyの編集
$ vi grails-app/conf/BuildConfig.groovy
修正1
mavenLocal()
mavenCentral()
mavenRepo "http://maven.springframework.org/milestone/"
修正2
plugins {
compile ":cloud-foundry:1.2.3"
runtime ":hibernate:$grailsVersion"
runtime ":jquery:1.8.0"
runtime ":resources:1.1.6"
refreshDependenciesの実行
$ grails refresh-dependencies
| Dependencies refreshed.
33. プラグインの確認
DependencyReportの確認
$ grails dependency-report
| Dependency report output to [/home/vagrant/morika/target/dependency-report/index.html]
$ w3m target/dependency-report/index.html
cloud-foundry by org.grails.plugins 1.2.3
--- cloud-support by 1.0.11
org.grails.plugins
--- cloudfoundry-client-lib by 0.7.5
org.grails.plugins
--- cloudfoundry-caldecott-lib by 0.1.1
org.grails.plugins
34. ドメインの作成
create-domain-classの実行
$ grails create-domain-class org.example.Music
| Created file grails-app/domain/org/example/Music.groovy
| Created file test/unit/org/example/MusicTests.groovy
Music.groovyの中身を編集
$ vi grails-app/domain/org/example/Music.groovy
package org.example
class Music {
String title
Integer bpm
byte[] jacket
static mapping = {
jacket( type:'materialized_blob')
}
static constraints = {
title( blank: false )
}
}
35. コントローラ等の作成
$ grails generate-all org.example.Music
| Finished generation for domain class org.example.Music
MusicController.groovyの中身に image アクションを追加
$ vi grails-app/controllers/org/example/MusicController.groovy
package org.example
import org.springframework.dao.DataIntegrityViolationException
class MusicController {
static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
def image(Long id) {
def music = Music.get( id )
if( music ){
response.outputStream << music.jacket
}else{
response.sendError(404)
}
}
def index() {
redirect(action: "list", params: params)
}
def list(Integer max) {
36. ビューの修正
list.gsp の中身に image アクションの呼び出しを追加
$ vi grails-app/views/music/list.gsp
<g:each in="${musicInstanceList}" status="i" var="musicInstance">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td><g:link action="show" id="${musicInstance.id}">${fieldValue(bean: musicInstance, field: "title")}</g:link></td>
<td>${fieldValue(bean: musicInstance, field: "jacket")}</td>
<td>${fieldValue(bean: musicInstance, field: "bpm")}</td>
</tr>
<td><g:if test="${musicInstance.jacket}">
<img src="<g:createLink controller='music' action='image'
id='${musicInstance.id}' />" />
</g:if></td>
37. アプリのデプロイ
migrationsディレクトリを作成(ディレクトリがない場合)
$ ls grails-app/
conf controllers domain i18n services taglib utils views
$ mkdir -p grails-app/migrations
$ ls grails-app/
conf domain migrations taglib views
controllers i18n services utils
アプリのpush
$ grails prod cf-push
| Environment set to production.....
Building war file
| Done creating WAR target/cf-temp-1365927930647.war
>
Application Deployed URL: 'morika.cloudfoundry.com'? y
>
Would you like to create and bind a mysql service?[y,n] n
>
Would you like to create and bind a postgresql service?[y,n] y
Service 'postgresql-12d5711' provisioned.
| Creating application morika at morika.cloudfoundry.com with 512MB and
| Creating application morika at morika.cloudfoundry.com with 512MB and
| Application 'morika' started at http://morika.cloudfoundry.com
39. アプリのアップデート
top画面のviewの中身を編集
$ vi grails-app/views/index.gsp
<div id="controller-list" role="navigation">
<h2>Available Controllers:</h2>
<ul>
<g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
<li class="controller"><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
</g:each>
</ul>
</div>
<div>${System.getenv('VMC_SERVICES').replaceAll(",","<br />")}</div>
cf-updateで更新を実施
$ grails prod cf-update
| Environment set to production.....
Building war file
| Done creating WAR target/cf-temp-1365930233412.war
| Application 'morika' started at http://morika.cloudfoundry.com
41. インスタンス数変更
変更前
$ grails cf-show-instances
| Environment set to development.....
+-------+---------+--------------------+
| Index | State | Start Time |
+-------+---------+--------------------+
| 0 | RUNNING | 04/14/2013 11:06AM |
+-------+---------+--------------------+
cf-update-instances インスタンス数で変更
$ grails cf-update-instances 2
| Environment set to development.....
Scaled 'morika' up to 2 instances.
$ grails cf-show-instances
| Environment set to development.....
+-------+---------+--------------------+
| Index | State | Start Time |
+-------+---------+--------------------+
| 0 | RUNNING | 04/14/2013 11:06AM |
+-------+---------+--------------------+
| 1 | RUNNING | 04/14/2013 11:14AM |
+-------+---------+--------------------+
42. メモリ割り当て変更
変更前
$ grails cf-stats
| Environment set to development.....
+----------+-------------+----------------+--------------+---------------+
| Instance | CPU (Cores) | Memory (limit) | Disk (limit) | Uptime |
+----------+-------------+----------------+--------------+---------------+
| 0 | 4.5% (4) | 373.7M (512M) | 41.1M (2G) | 0d:0h:12m:23s |
| 1 | 10.1% (4) | 380.4M (512M) | 41.0M (2G) | 0d:0h:4m:1s |
+----------+-------------+----------------+--------------+---------------+
cf-update-memory 割り当てメモリ量 を変更
$ grails cf-update-memory 1G
| Environment set to development.....
Updated memory reservation to '1.0G'.
| Application 'morika' started at http://morika.cloudfoundry.com
$ grails cf-stats
| Environment set to development.....
+----------+-------------+----------------+--------------+-------------+
| Instance | CPU (Cores) | Memory (limit) | Disk (limit) | Uptime |
+----------+-------------+----------------+--------------+-------------+
| 0 | 24.9% (4) | 364.3M (1G) | 41.1M (2G) | 0d:0h:2m:2s |
| 1 | 20.6% (4) | 380.9M (1G) | 41.0M (2G) | 0d:0h:2m:2s |
+----------+-------------+----------------+--------------+-------------+
43. ログの確認
logの確認
$ grails cf-logs
| Environment set to development.....
==== logs/stderr.log ====
Apr 14, 2013 9:23:23 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-29372
Apr 14, 2013 9:23:23 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 710 ms
Apr 14, 2013 9:23:23 AM org.apache.catalina.realm.JAASRealm setContainer
INFO: Set JAAS app name Catalina
Apr 14, 2013 9:23:23 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Apr 14, 2013 9:23:23 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.35
Apr 14, 2013 9:23:23 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Apr 14, 2013 9:23:37 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-29372
Apr 14, 2013 9:23:37 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 14194 ms
44. アプリケーションの起動/停止/再起動
停止
$ grails prod cf-stop
| Application 'morika' stopped.
起動
$ grails prod cf-start
| Application 'morika' started at http://morika.cloudfoundry.com
再起動
$ grails prod cf-restart
| Application 'morika' started at http://morika.cloudfoundry.com
45. リモートのファイル確認
Cloud Foundry側のファイルを確認するには以下の通り
ls相当のコマンド
$ grails cf-list-files /
| Environment set to development.....
logs/ -
tomcat/ -
logファイルを確認してみる
$ grails cf-get-file logs/stderr.log
| Environment set to development.....
Apr 14, 2013 10:05:36 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-49626
Apr 14, 2013 10:05:36 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 604 ms
46. アプリケーションの削除
1アプリケーションのみ削除
$ grails cf-delete-app
| Environment set to development.....
> Application 'morika' uses 'postgresql-12d5711' service, would you like to delete it?[y,n] y
Application 'morika' deleted.
Service 'postgresql-12d5711' deleted.
全アプリの削除
$ grails cf-delete-all-apps
47. その他 cf-* コマンド
その他 cf-* コマンドに関しては、Grails cloud-foundryプラグ
インのリファレンスページも参照してみてください
http://grails-plugins.github.io/grails-cloud-
foundry/docs/manual/index.html
cf-add-user cf-env
cf-apps cf-env-add
cf-bind-service cf-env-del
cf-change-password cf-frameworks
cf-clone-services cf-get-file
cf-crashes cf-help
cf-crashlogs cf-info
cf-create-service cf-list-files
cf-delete-all-apps cf-logs
cf-delete-app cf-map
cf-delete-service :
cf-delete-user 41コマンド用意されている
48. あらかじめ用意したDBのデータを
Cloud FoundryのDBに入れるには?
Grails cloud-foundryプラグインの場合
cf-tunnel
vmcの場合
vmc tunnel (Caldecott)
Eclipse/STS/GGTSの拡張の場合
動作自体は未確認
○ http://blog.cloudfoundry.com/2013/03/14/cloud
-foundry-integration-for-eclipse-can-now-
launch-external-command-line-applications-
using-service-tunnels/
50. 関連資料
Grails Application Development with Cloud Foundry
http://docs.cloudfoundry.com/frameworks/java/spring/grail
s.html
Grails Cloud Foundry Plugin - Reference
http://grails-plugins.github.io/grails-cloud-
foundry/docs/manual/guide/index.html
G*Magazine 第3号 Grails Plugin 探訪
~第4回 Cloud Foundry プラグイン~
http://grails.jp/g_mag_jp/file/gmagazine_3.pdf
G*Magazine http://grails.jp/g_mag_jp/
Cloud Foundryリポジトリの歩き方
http://www.slideshare.net/skurumat/cfcrjp-09-introduction-
to-cloudfoundry-repositories