cloud foundryは何故動くのか

Post on 24-May-2015

4.119 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

第18回 Cloud Foundry輪読会で発表した資料です

TRANSCRIPT

Cloud Foundryは、なぜ動くのか

@jacopen Kazuto KusamaNTT Communications !Cloudn PaaSの開発・運用をやっています

最近

質問

はじめに

今回の発表、元々は !• Cloud Foundryのアーキテクチャ概要に軽く触れる • V2で変わったところを中心に、少し深く追ってみる

!

という予定でした

Open Cloud Summit Japan とかで喋りました

が、概要説明だけで100スライド近くになったので、今回は深追いするのは諦めました。 !

なので、かなり入門者向けの内容になっています。 !

深追いはまた次回!

Cloud FoundryにSinatraアプリをデプロイ

$ lsGemfile README.md dora.rb instances.rb logging_service.rb spec stress_testers.rbGemfile.lock config.ru get_instance_cookie_jars.sh log_utils.rb scripts stress vendor!

https://github.com/cloudfoundry/cf-acceptance-tests/tree/master/assets/dora

[23:08] jacopen@cape ~/Project/dora ✘╹◡╹✘ (master) cf push doraCreating app dora in org jacopen / space jacopen-space as admin...OK!Creating route dora.107.22.72.200.xip.io...OK!Binding dora.107.22.72.200.xip.io to dora...OK!Uploading dora...Uploading from: /Users/jacopen/Project/dora1.2M, 36 filesOK!Starting app dora in org jacopen / space jacopen-space as admin...OK(中略)1 of 1 instances running!App started!Showing health and status for app dora in org jacopen / space jacopen-space as admin...OK!requested state: startedinstances: 1/1usage: 256M x 1 instancesurls: dora.107.22.72.200.xip.io! state since cpu memory disk#0 running 2014-04-21 11:09:25 PM 0.0% 72.2M of 256M 0 of 1G

ok![23:09] jacopen@cape ~/Project/dora ✘╹◡╹✘ (master) cf appsGetting apps in org jacopen / space jacopen-space as admin...OK!name requested state instances memory disk urlsdora started 1/1 256M 1G dora.107.22.72.200.xip.io

cf push

この間、CF内では何が行われていたのか?

CFというブラックボックスの謎を解こう

アジェンダ

Cloud Foundryの仕組みを理解するための3章立て !• Cloud Foundryを外から叩いて、中身を推測する • Cloud Foundryの各コンポーネントの役割を知る • Cloud Foundryのコンポーネント間通信を知る

今回やらないこと!

• WardenコンテナやBuildpackなどの解説

• MySQLやPostgresなどのService系の解説

• loggregatorなどの、周辺サービスの解説

では始めましょう

Cloud Foundryを

外から叩いて 中身を推測しよう1

CF_TRACE=true[23:49] jacopen@cape ~/Project/dora ✘╹◡╹✘ export CF_TRACE=true[23:49] jacopen@cape ~/Project/dora ✘╹◡╹✘ cf push dora!REQUEST:GET /v2/spaces/dbf6ed0a-3108-45d8-9c78-a512d5071358/apps?q=name%3Adora&inline-relations-depth=1 HTTP/1.1Host: api.107.22.72.200.xip.ioAccept: application/jsonAuthorization: [PRIVATE DATA HIDDEN]Content-Type: application/jsonUser-Agent: go-cli 6.0.0-90db382 / darwin!!!RESPONSE:HTTP/1.1 200 OKContent-Length: 107Content-Type: application/json;charset=utf-8Date: Mon, 21 Apr 2014 14:49:13 GMTServer: nginxX-Content-Type-Options: nosniffX-Vcap-Request-Id: 18dcd4aefdd000506e49c4b5cf739aaa::65195823-dac9-410a-855a-4ef5ba249198!{ "total_results": 0, "total_pages": 0, "prev_url": null, "next_url": null, "resources": [! ]}Creating app dora in org jacopen / space jacopen-space as admin...

調査の鍵 CF_TRACE=true

CF_TRACE=trueにすると、cf コマンドが

裏で行っているリクエストを見ることができる。

cf pushを覗いてみよう

GET /v2/spaces/dbf6ed0a-3108-45d8-9c78-a512d5071358/apps?q=name%3Adora&inline-relations-depth=1 HTTP/1.1HTTP/1.1 200 OK!POST /v2/apps?async=true HTTP/1.1{"name":"dora","space_guid":"dbf6ed0a-3108-45d8-9c78-a512d5071358"}HTTP/1.1 201 Created!GET /v2/shared_domains HTTP/1.1HTTP/1.1 200 OK!GET /v2/domains?inline-relations-depth=1&q=name%3A107.22.72.200.xip.io HTTP/1.1HTTP/1.1 200 OK!GET /v2/routes?inline-relations-depth=1&q=host%3Adora%3Bdomain_guid%3A524ba14d-4d3f-495f-a2c7-a5ed25a70e81 HTTP/1.1HTTP/1.1 200 OK!POST /v2/routes?async=true&inline-relations-depth=1 HTTP/1.1{"host":"dora","domain_guid":"524ba14d-4d3f-495f-a2c7-a5ed25a70e81","space_guid":"dbf6ed0a-3108-45d8-9c78-a512d5071358"}HTTP/1.1 201 Created!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/routes/ed912294-be29-4013-8b1c-735851acee24 HTTP/1.1HTTP/1.1 201 Created!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/bits?async=true HTTP/1.1Content-Type: multipart/form-data;HTTP/1.1 201 Created!GET /v2/jobs/6dd46fe7-40b0-41d1-94aa-dd2ee80fd3b2 HTTP/1.1HTTP/1.1 200 OK(queued)!GET /v2/jobs/6dd46fe7-40b0-41d1-94aa-dd2ee80fd3b2 HTTP/1.1HTTP/1.1 200 OK(finished)!CONNECTING TO WEBSOCKET: wss://loggregator.107.22.72.200.xip.io:443/tail/?app=0e948568-aa90-47e9-a128-9ff3cc680600!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600?async=true&inline-relations-depth=1 HTTP/1.1{"state":"STARTED"}!GET /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/instances HTTP/1.1HTTP/1.1 400 Bad Request{"code":170002,"description":"App has not finished staging","error_code":"CF-NotStaged"}!GET /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/instances HTTP/1.1

api.107.22.72.200.xip.io と何かやりとりしてる

分かったこと

cf push

Cloud Foundryは、APIを提供している

APIを提供してくれる何か

cf push

cf pushは、APIをいろいろ叩いてデプロイする

APIを提供してくれる何か

GET xxxx

PUT xxxx

POST xxxx

GET xxxx

アプリを動かす何か

アクセス先を調べよう

API

api.107.22.72.200.xip.io

Application

dora.107.22.72.200.xip.io

あれ?

APIも、Appも、同じIPアドレス

$ nslookup api.107.22.72.200.xip.ioServer: 192.168.11.1Address: 192.168.11.1#53!Non-authoritative answer:api.107.22.72.200.xip.io canonical name = api.1jkk1uz.xip.io.Name: api.1jkk1uz.xip.ioAddress: 107.22.72.200!$ nslookup dora.107.22.72.200.xip.ioServer: 192.168.11.1Address: 192.168.11.1#53!Non-authoritative answer:dora.107.22.72.200.xip.io canonical name = dora.1jkk1uz.xip.io.Name: dora.1jkk1uz.xip.ioAddress: 107.22.72.200

cf push

アドレスを元にアクセスを分配する何者かが居る

APIを提供してくれる何か

アクセスを分ける 何かブラウザ

アプリを動かす何か

cf scale

$ cf scale -i 3 -m 256M doraScaling app dora in org jacopen / space jacopen-space as admin...OK

cf scaleコマンドで、稼働する「インスタンス数」「メモリサイズ」などを変更できる

cf push

アドレスを元にアクセスを分配する何者かが居る

APIを提供してくれる何か

アクセスを分ける 何かブラウザ

アプリが死ぬとどうなる?

dora/sigterm/KILL

sigterm/KILLで、自分自身のプロセスを終了

ポートが変わった

アプリの死活監視をしている何かが居る

APIを提供してくれる何か

アクセスを分ける 何か

死活 監視

結果

外から見えるCloud Foundry

APIを提供してくれる何か

アクセスを分ける 何か

アプリを動かす何か

死活 監視

Cloud Foundryの中身(の一部)

Cloud Controller

Router

DEA HealthManager

Cloud Foundryにおける

コンポーネントの 役割を知ろう2

コンポーネント=?

Cloud Controller

Router

DEA HealthManager

コンポーネント=アプリケーション

Cloud Controller (Ruby)

Router (Golang)

DEA (Ruby)

HealthManager (Golang)

全コンポーネントを1VMに集約できる

Cloud Controller (Ruby)

Router (Golang)

DEA (Ruby)

HealthManager (Golang)

VM

(一般的に)実運用では、 コンポーネントごとにVMを分ける

Cloud Controller (Ruby)

Router (Golang)

DEA (Ruby)

HealthManager (Golang)

VM

VM

VM VM

それぞれのコンポーネントを見ていこう

Router

Cloud Controller

Router

DEA HealthManager

Routerとは

URLによって、適切なコンポーネントにアクセスを振り分けるL7ロードバランサー(のようなもの)

ネットワーク機器の「ルーター」とは違う点に注意。

実体は、Ubuntu上で動く、Goで書かれたアプリケーション。(Gorouterという)

Cloud Controller

Router

DEA HealthManager

api.107.22.72.200.xip.io

dora.107.22.72.200.xip.io

Cloud Controller

Router

DEA HealthManager

api.107.22.72.200.xip.io

dora.107.22.72.200.xip.io

なぜRouterはリクエストの振り先を知っているのか?

Cloud Controller

Router

DEA HealthManager

router.register

各コンポーネントが、router.registerというメッセージをRouterに送る

api.107.22.72.200.xip.ioは10.244.0.138:9022に送って

dora.107.22.72.200.xip.ioは10.244.0.26:61032に送って

Cloud Controller

Router

DEA HealthManager

router.register

Routerは、収集した情報を元にアクセスを分配する

dora.107.22.72.200.xip.io => 10.244.0.26:61032 api.107.22.72.200.xip.io => 10.244.0.138:9022

api.107.22.72.200.xip.io

dora.107.22.72.200.xip.io

Cloud Controller

Router

DEA HealthManager

router.register

同一URLに複数の振り先でも大丈夫

dora.107.22.72.200.xip.io => 10.244.0.26:61032 dora.107.22.72.200.xip.io => 10.244.0.27:58719 api.107.22.72.200.xip.io => 10.244.0.138:9022 api.107.22.72.200.xip.io => 10.244.0.139:9022

api.107.22.72.200.xip.io

dora.107.22.72.200.xip.io

Cloud Controller

DEA

Cloud Controller

Cloud Controller

Router

DEA HealthManager

Cloud Controllerとは APIを提供するコンポーネント。

!

• cfコマンド等からアプリケーションの受け取り

• DEAに対してアプリの起動・停止の指示

• Service(データベース等)の作成の指示

!

などなど、Cloud Foundry全体に対しての

コントロールを行う。

POST /v2/apps?async=true HTTP/1.1{"name":"dora","space_guid":"dbf6ed0a-3108-45d8-9c78-a512d5071358"}HTTP/1.1 201 Created!GET /v2/shared_domains HTTP/1.1HTTP/1.1 200 OK!GET /v2/domains?inline-relations-depth=1&q=name%3A107.22.72.200.xip.io HTTP/1.1HTTP/1.1 200 OK!GET /v2/routes?inline-relations-depth=1&q=host%3Adora%3Bdomain_guid%3A524ba14d-4d3f-495f-a2c7-a5ed25a70e81 HTTP/1.1HTTP/1.1 200 OK!POST /v2/routes?async=true&inline-relations-depth=1 HTTP/1.1{"host":"dora","domain_guid":"524ba14d-4d3f-495f-a2c7-a5ed25a70e81","space_guid":"dbf6ed0a-3108-45d8-9c78-a512d5071358"}HTTP/1.1 201 Created!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/routes/ed912294-be29-4013-8b1c-735851acee24 HTTP/1.1HTTP/1.1 201 Created!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/bits?async=true HTTP/1.1Content-Type: multipart/form-data;HTTP/1.1 201 Created!GET /v2/jobs/6dd46fe7-40b0-41d1-94aa-dd2ee80fd3b2 HTTP/1.1HTTP/1.1 200 OK(queued)!GET /v2/jobs/6dd46fe7-40b0-41d1-94aa-dd2ee80fd3b2 HTTP/1.1HTTP/1.1 200 OK(finished)!CONNECTING TO WEBSOCKET: wss://loggregator.107.22.72.200.xip.io:443/tail/?app=0e948568-aa90-47e9-a128-9ff3cc680600!PUT /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600?async=true&inline-relations-depth=1 HTTP/1.1{"state":"STARTED"}!GET /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/instances HTTP/1.1HTTP/1.1 400 Bad Request{"code":170002,"description":"App has not finished staging","error_code":"CF-NotStaged"}!GET /v2/apps/0e948568-aa90-47e9-a128-9ff3cc680600/instances HTTP/1.1

⇐appの作成⇐domainの取得

⇐routesの確認⇐routesの作成⇐appとroutesの紐付け⇐ソースのアップロード

⇐appを起動

DEA

Cloud Controller

Router

DEA HealthManager

DEAとは ユーザーアプリを動かすためのコンポーネント。

Droplet Execution Agentの略。

!

CF v2では、ユーザーアプリのStaging作業(Rubyのbundle installなど)も担当する。

!

DEAはWardenというLinuxコンテナを使い、ユーザーアプリを動かす(が、今回は触れない)

Clientからのソース受け取り

Cloud Controller

Router

DEA HealthManager

cf push

Gemfile lib/ bin/ config.ru app.rb

Staging依頼 (staging.start)

Cloud Controller

Router

DEA HealthManager

cf push

Gemfile lib/ bin/ config.ru app.rb

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

Golden Packageの保存

Cloud Controller

Router

DEA HealthManager

cf push

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

Start依頼 (dea.start)

Cloud Controller

Router

DEA HealthManager

cf push

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

Start依頼 (dea.start)

Cloud Controller

Router

DEA HealthManager

cf push

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

Cloud Controller

Router

DEA HealthManager

cf scale -i 3

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

DEA

Start依頼 (dea.start)

Cloud Controller

Router

DEA HealthManager

cf scale -i 3

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

DEA

Start依頼 (dea.start)

Cloud Controller

Router

DEA HealthManager

cf scale -i 3

Gemfile Gemfile.lock vendor/ lib/ bin/ config.ru

DEA

Health Manager

Cloud Controller

Router

DEA HealthManager

DEA

Health Managerとは !

ユーザーアプリが、「あるべき姿」になっているかどうか、監視を行うコンポーネント。 !

最新版は、Goで書かれた「hm9000」

インスタンスの突然死

Cloud Controller

Router

DEA HealthManager

DEA

droplet.exited

Cloud Controller

Router

DEA HealthManager

DEA

hm9000.start

Cloud Controller

Router

DEA HealthManager

DEA

dea.start

Cloud Controller

Router

DEA HealthManager

DEA

dea.start

Cloud Controller

Router

DEA HealthManager

DEA

何故かインスタンスが多い場合

Cloud Controller

Router

DEA HealthManager

DEA

dea.heartbeat

Cloud Controller

Router

DEA HealthManager

DEA3インスタンスのはずなのに、4つ来た・・・

hm9000.stop

Cloud Controller

Router

DEA HealthManager

DEA

dea.stop

Cloud Controller

Router

DEA HealthManager

DEA

dea.stop

Cloud Controller

Router

DEA HealthManager

DEA

それぞれの関係、分かりましたか?

Cloud Controller

Router

DEA HealthManager

内部通信

外部からのアクセス

Cloud Foundryにおける

コンポーネント間 通信を知ろう3

さっきのこの図

Cloud Controller

Router

DEA HealthManager

内部通信

外部からのアクセス

Cloud Controller

Router

DEA HealthManager

NATS

NATSとは !

Publish-Subscribeモデルの軽量メッセージングシステム

!

Cloud Foundryの生みの親、Derek Collison氏が開発。

Cloud Foundry登場時から存在する、アーキテクチャの

キモになるシステム。 !

元々はRubyで、EventMachineを使って実装されていた。

現在はGoで実装された、gnatsdになっている

Publish-Subscribeモデル

Publisher Subscriber

NATS

Subject: foo.bar

Subject: foo.bar

Publish-Subscribeモデル

Publisher Subscriber

NATS

Subject: foo.bar{“message”: “hogefuga”}

{“message”: “hogefuga”}

{“message”: “hogefuga”}

Publish-Subscribeモデル

Publisher Subscriber

NATS

Cloud Controller

DEA

Router

Subject: router.register {“host":"10.244.0.138","port":9022,"uris":

["api.107.22.72.200.xip.io"]}

Subject: router.register {“host":"10.244.0.111","port":37902,"uris":

["dora.107.22.72.200.xip.io"]}

全Subscriberが同じメッセージを受け取れる

NATS

Cloud Controller

DEA

Router

Subject: router.register {“host":"10.244.0.138","port":9022,"uris":

["api.107.22.72.200.xip.io"]}

Subject: router.register {“host":"10.244.0.111","port":37902,"uris":

["dora.107.22.72.200.xip.io"]}

Router

Router

Publisher Subscriber

もしNATSが無かったら・・・

NATSあり 直接通信

1.Routerを起動

2.Routerはrouter.registerをsubscribe

1.新Routerを管理DBに登録

2.Routerを起動

3.DEA, CCは管理DBを参照し、Routerリストを取得

4.各Routerに対してメッセージ送信

Cloud Controller

Router

DEA HealthManager

NATSRouter

Router

Cloud Controller

DEA

DEA

DEA

Cloud Controller

Cloud Controller

Cloud Foundryのアーキテクチャ !

• NATSを中心とした、疎結合なコンポーネント間連携

• スケールしやすい! • 自律分散型システム

• 管理する情報は必要最低限 • セルフヒーリング

• 要は勝手に治る

• SPoF(単一障害点)は排除

• ただし最近までのNATSを除く

Cloud Foundry V1と 変わってない?

CF v1 と v2 の違い

• 大まかなアーキテクチャは変わっていない

• DEAがDEAngになり、WardenというLinuxコンテナでアプリを動かすように

• いろんなコンポーネントがGoに書き換えられた

• HerokuのBuildpackが使えるように

• APIの互換性は一切無し!

次回はもうちょっと踏み込んだ内容をやるよ

top related