G*ワークショップZ - Apr 2013
Takeshi Morikawa(日本Cloud Foundryグループ 会員) Yu Sudo (日本Grails/Groovyユーザーグループ 運営委員)
自己紹介 名前
森川 健 (Takeshi Morikawa)
所属 NTTソフトウェア
技術開発センター OSS基盤技術部門 クラウド推進室 エンジニア 日本Cloud Foundryグループ(CFGRJP)会員
以前の業務 入社以来、無線VoIPソリューションの開発担当
モバイル端末向けの画面をGrailsを使って開発(view+controllerメイン)
OJTの方から「Ruby良いよ!」と聞いていた為、興味があった
現在 Grailsの経験
Cloud Foundryの中でRailsやRubyが使われている
…という事で昨年の4月よりCloud Foundry担当となりました
自己紹介 名前
須藤 悠 (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/
本日の内容
日本Cloud Foundryグループについて PaaSについて Cloud Foundryの基礎 ハンズオン
Grails cloud-foundryプラグインで実際にcloudfoundry.comにGrailsアプリをpush
日本Cloud Foundryグループ(CFGRJP)
URL http://www.cloudfoundry.gr.jp/
活動内容(設立趣意書より※)
本会は日本国内でのCloud Foundryの利用促進のため、以下のような取り組みを実施してまいります。 Cloud Foundryに関するセミナー・勉強会の開催 Cloud Foundryに関する日本語による情報提供 コード改善のための各国コミュニティとの連携支援 ユーザ同士の交流促進 等
※ 日本Cloud Foundryグループ 設立趣意 http://www.cloudfoundry.gr.jp/prospectus
はじめる前に…
ハンズオンの準備はできていますか? JDK ( 6 でも動きますが 7 が望ましい) Grails (Mac/Linuxの方は GVM で!) ○ JavaやGrailsが使う環境変数もお忘れなく!
CloudFoundry.com のアカウント ○ https://my.cloudfoundry.com/signup ○ Promo code ないと待たされます ○ preshavedyak ってまだ使えるのかな…
準備がまだの人は、話を聞きながらやっておいてください
PaaSとは Platform as a Serviceの略です
IaaSの場合
仮想マシンの領域を借りて自分でOSを入れてDB入れる等、サーバを自由に構築するものです。
つまりアプリを動かし、サービスを提供するには色々な設定をしなくてはなりません。※
PaaSの場合
Webアプリケーションを稼働させるための基盤です。 DBやWebサーバの設定、運用をPaaSサービス事業者に任せ、アプリ開発に専念出来ます。
※最近ではOps Worksのような仕組みができて構築が簡単になりPaaS領域を侵食しつつありますが
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
に移っています
利用可能なフレームワークとサービス
フレームワーク&言語 Spring Grails Scala, Play! Node.js Ruby, Rails, Sinatra
サービス(DB等) MySQL PostgreSQL Redis MongoDB RabbitMQ
Cloud Foundryのコンポーネント(一部のみ紹介)
dea (droplet execution agent) 実際にユーザのWebアプリが動作するコンポーネント Webアプリが実際に起動するポートは毎回異なる
stager
アプリ開発者がCloud Foundryにアプリをpush※した際に、dea上で動作する形にファイルをまとめる
health manager dea上で動作するアプリが設定された数のインスタンスが起動しているか等をチェックするコンポーネント
※pushとはアプリケーションをClouf Foundry上にデプロイする事を指します
Cloud Foundryのコンポーネント(一部のみ紹介)
cloud controller Cloud Foundry上のアプリケーション情報の管理 ○ どのアプリを何個インスタンスを起動するか ○ 各アプリに紐づけた(bindされる)DBの接続情報
現在のバージョンではRailsによって実装されている 次世代バージョンではSinatraになる
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/
Cloud Foundryのコンポーネント(一部のみ紹介)
service-gateway / service-node アプリケーションに紐づいた(bindされた)DB等が動作するコンポーネント
その他に認証系コンポーネント等が存在しますが、今回は説明を省略します uaa (user account & authentication) acm (access control manager)
NATSについて
NATSとは? EventMachineを使ったpub/subのメッセージングシステム(非同期I/O)
All-in-One構成(1つのVM上にすべてのコンポーネント)を動作させる場合も1VM1コンポーネントのマルチノード構成の場合もこの仕組みによって連携を実現
Cloud Foundryのコンポーネントの特徴的な動作の例
ユーザ(開発者)がアプリをpushし 2インスタンス起動という要求を出す
るーたー
くらうどこんとろーらー
http or https http or https
2インスタンス起動して!
2インスタンス起動で deaに聞いてみます!
Cloud Foundryのコンポーネントの特徴的な動作の例
cloud controllerがnats server経由でdeaに確認
なっつさーばー
natsメッセージ
deaさんいますか?
くらうどこんとろーらー
ポイント:cloud controllerはdeaがアプリを起動する余裕があるかだけでなく、今現在deaが何台いるのか知らない
2インスタンス起動できるdeaさんいます?
Cloud Foundryのコンポーネントの特徴的な動作の例
各deaが応答
なっつさーばー
natsメッセージ deaさん
いますか?
ポイント:dea2はリソースがないので応答しません。この際に要求が1インスタンスだった場合は先に応答したdea1が選択されます。
2インスタンス起動できるdeaさんいます?
dea1
dea2
dea999
1インスタンスなら!
リソースがもうないです。。。
まだまだ いけます!
Cloud Foundryのコンポーネントの特徴的な動作の例
cloud controllerがnats server経由でdea1とdea999に通知
なっつさーばー
natsメッセージ
dea1さん!アプリAをメモリ
128MBで起動してください
くらうどこんとろーらー
ポイント:起動に必要なファイルの受け渡し方法等を通知
dea999さん!アプリAをメモリ128MBで起動してください
Cloud Foundryのコンポーネントの特徴的な動作の例
各deaが通知を元にファイルを取得し起動
なっつさーばー
natsメッセージ
ポイント:ファイルを起動
dea1
dea2
dea999
起動しました!
起動しました!
dea1さん!アプリAをメモリ128MBで起動してください
dea999さん!アプリAをメモリ128MBで起動してください
Cloud Foundryを利用するには? 1. パブリックなPaaSを利用 2. 自前のPaaSを構築 接続する方法
1. vmcコマンドを使う 2. Eclipse PluginやSTS/GGTSの拡張を使う 3. Grailsのcloud-foundryプラグインを使う
パブリックな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
自前のPaaSを構築 1. Micro Cloud Foundryを使ってローカル環境の
仮想マシン上に構築 https://micro.cloudfoundry.com/ cloudfoundry.comのアカウントがあれば入手可能
2. github上のソースを使ってAll-in-One環境構築
https://github.com/cloudfoundry/vcap
3. github上のソースを使ってマルチノード構築
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_installer_0.3.23-r1.9.3.exe
インストーラのソース - https://github.com/nttlabs/vmc_installer
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環境が良い場合はおすすめ
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開発環境であれば導入しやすい
今回のハンズオンではこちらを利用します
本資料の作成環境 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
アプリの作成
上記のアプリケーションの Cloud Foundry.com でのURLは morika.cloudfoundry.com となる
1つのCloud Foundry内で重複が許されないので注意が必要です※
※ grails-app/conf/Config.groovy に grails.plugin.cloudfoundry.appname=アプリ名を記述するか アプリのpush(デプロイ)時に --appname=アプリ名 オプションで変更することも可能
$ grails create-app morika | Created Grails Application at /home/vagrant/morika $
Cloud Foundryの接続情報の設定
$HOME/.grails/settings.groovyの編集
事前に登録したcloudfoundry.comのusernameとpasswordを設定します
※ cloudfoundry.target は cloudfoundry.com の場合は記述しなくても問題ありませんが その他のCloud Foundryサービスを利用する際は記述が必要です
$ vi /home/vagrant/.grails/settings.groovy
grails.plugin.cloudfoundry.username = '[email protected]' grails.plugin.cloudfoundry.password = ‘hogehoge' grails.plugin.cloudfoundry.target = 'http://api.cloudfoundry.com'
mavenLocal() mavenCentral() mavenRepo "http://maven.springframework.org/milestone/"
Cloud Foundryプラグイン設定 ディレクトリ移動(create-appしたアプリのディレクトリに入る)
BuildConfig.groovyの編集
refreshDependenciesの実行
$ cd morika/
$ vi grails-app/conf/BuildConfig.groovy
$ grails refresh-dependencies | Dependencies refreshed.
plugins { compile ":cloud-foundry:1.2.3" runtime ":hibernate:$grailsVersion" runtime ":jquery:1.8.0" runtime ":resources:1.1.6"
修正1
修正2
プラグインの確認 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
ドメインの作成
Music.groovyの中身を編集
$ grails create-domain-class org.example.Music | Created file grails-app/domain/org/example/Music.groovy | Created file test/unit/org/example/MusicTests.groovy
create-domain-classの実行
package org.example class Music { String title Integer bpm byte[] jacket static mapping = { jacket( type:'materialized_blob') } static constraints = { title( blank: false ) } }
$ vi grails-app/domain/org/example/Music.groovy
コントローラ等の作成
MusicController.groovyの中身に image アクションを追加
$ grails generate-all org.example.Music | Finished generation for domain class org.example.Music
$ 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) {
ビューの修正 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>
アプリのデプロイ
$ 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
$ 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
migrationsディレクトリを作成(ディレクトリがない場合)
アプリのpush
アプリへのアクセス 自分のpushしたアプリにアクセス http://morika.cloudfoundry.com/
<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>
アプリのアップデート top画面のviewの中身を編集
cf-updateで更新を実施
$ vi grails-app/views/index.gsp
$ 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
アップデート確認
インスタンス数変更 変更前
cf-update-instances インスタンス数で変更
$ grails cf-show-instances | Environment set to development..... +-------+---------+--------------------+ | Index | State | Start Time | +-------+---------+--------------------+ | 0 | RUNNING | 04/14/2013 11:06AM | +-------+---------+--------------------+
$ 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 | +-------+---------+--------------------+
メモリ割り当て変更 変更前
cf-update-memory 割り当てメモリ量 を変更
$ 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 | +----------+-------------+----------------+--------------+---------------+
$ 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 | +----------+-------------+----------------+--------------+-------------+
ログの確認 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
アプリケーションの起動/停止/再起動 停止
$ 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
リモートのファイル確認 Cloud Foundry側のファイルを確認するには以下の通り
$ grails cf-list-files / | Environment set to development..... logs/ - tomcat/ -
ls相当のコマンド
$ 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
logファイルを確認してみる
アプリケーションの削除 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
その他 cf-* コマンドに関しては、Grails cloud-foundryプラグインのリファレンスページも参照してみてください http://grails-plugins.github.io/grails-cloud-
foundry/docs/manual/index.html
その他 cf-* コマンド
cf-add-user cf-apps cf-bind-service cf-change-password cf-clone-services cf-crashes cf-crashlogs cf-create-service cf-delete-all-apps cf-delete-app cf-delete-service cf-delete-user
cf-env cf-env-add cf-env-del cf-frameworks cf-get-file cf-help cf-info cf-list-files cf-logs cf-map :
41コマンド用意されている
あらかじめ用意した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/
関連資料 Grails Application Development with Cloud Foundry
http://docs.cloudfoundry.com/frameworks/java/spring/grails.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
記載されているシステム名、製品名は 各社および商標権者の登録商標あるいは商標です。 OracleとJavaは、Oracle Corporation およびその子会社、関連会社の 米国およびその他の国における登録商標です。 Copyright(C) 2013 NTT Software Corporation All Rights Reserved.