Cloud Foundry の各コンポーネントについて説明してみる
Cloud Foundry (CF) は Platform as a Service を提供するシステムで、その上で動かすアプリケーション (App) は 12 factor を従うのが良いとされる。
モノリシックなシステムをスケーラブルに、そして疎結合にして開発をしやすくするために、 CF や k8s のようなコンテナ管理システム上で、マイクロサービスアプリケーションを作成するのが 2010年代後半のトレンドであるが、CF 自体もマイクロサービスな作りになっている(ちなみに k8s もだ)
CF とは?
CF は OSS の Platform as a Service であり、簡単に好きなアプリケーションをコンテナ上にデプロイできる。
Cloud Foundry Components | Cloud Foundry Docs
下記に CF の各コンポーネントの説明を記載する。
コンポーネントの一覧は、cloudfoundry/cf-deployment: The canonical open source deployment manifest for Cloud Foundry の中身に従う。
2019/05/20 現在の最新のデプロイメントだと、cloudfoundry/cf-deployment at 9b90a84cf1a40684f83fdb67ba81fd00c18286ce
- gorouter
- tcp router
- MySQL
- uaa
- diego cell
- rep
- runc
- route emitter
- cloud controller
- routing api
- diego database
- bbs
- locket
- route registrar
- silk-controller
- diego brain
- auctioneer
- cc uploader
- ssh proxy
- NATS
- clock global
- log
- loggregator agent
- forwarder agent
- log cache
- reverse log proxy (RLP)
- syslog adaptor
全体図
CF はさまざまなコンポーネントとそれで動作するプロセスにより作られたマイクロサービスだ。
SPOF を作らないための工夫が随所に行われており、
- active/standby の database に様々なコンポーネントのステートフルな情報を集約する。これにより、多くのコンポーネントをステートレスにしている
- routing 情報は NATS という pub/sub を通じて連携しあうことで、お互いを疎結合 & 非同期にする
- bbs のようなコントロールプレーンには、Leader election を行わせる
- bosh dns という仕組みで Service discovery をする
などマイクロサービスには必要な要素技術が満載だ。全体図は go-zen-chu/cf-components に作成した。
routing, compute, database, log と様々なデータが行き来するため、矢印の色分けをしてもかなりカオスだ。
gorouter
CF の入り口となるコンポーネント。大きくは2つのルーティングを行う。
- ユーザのアプリケーションへのルーティング (map route されたアプリケーションに対して、ルーティングを行う)
- CF 内部のコンポーネントに対してルーティングを行う
gorouter は後述の NATS から http の routing 情報を受け取っている。
tcp router
TCP App の入り口となるコンポーネント。TCP VIP は tcp router と紐付けられている。 routing api から tls app の routing 情報を取得している。
TCP レイヤーの処理を行うだけなので、例えば HTTP のヘッダーを見たり、ヘッダーを書き換えたりすることがない。 その分、gorouter よりも 20倍パフォーマンスが良いらしい。
MySQL
CF の中で最も重要なデータストア。クラスタ化されており、active が落ちると、standby が代わりに master となる。
基本的に CF のコンポーネントはステートレス(いつ再起動しても大丈夫)なように作られているが、代わりに MySQL が多くのコンポーネントの状態を記録している。
障害の起因になることも多く、MySQL のデータベースが壊れると、CF のクラスタを作り直す必要がでてくる。
MySQL の中のデータベースを確認すると、
- ccdb
- diego
- network policy
- uaa
- locket
- routing api
などなど、CF の各コンポーネントの情報がストアされている。
少し前の CF では、galera MySQL を利用していたが、2018年ごろに percona mysql (pxc-mysql) へ変わった。どちらもクラスタ化でき、active, standby がある。
uaa (user authentication authorization)
CF の認証認可をするコンポーネント。
ユーザのログインだったり、各コンポーネントの認証(後述の traffic controller へ接続するときの認証など)が行われる。 実際の認証のクレデンシャルは、MySQL の方に格納されている。
通常、login.system…. という url でログインが可能だが、あの url の先は uaa だ。
uaa 越しに様々な認証方法が提供されており、OpenIDConnect, SAML など認証手段を切り替えることができる。
diego cell
App のコンテナが動作する VM。
App のコンテナが動作するため、ふんだんにリソースを利用する。コンテナを動作させるための CPU, MEM, ディスク (テンポラリ用途)を提供している。
rep
diego cell がちゃんと動いていて、新しく app を受け入れられる準備ができていることを rep (representative)というプロセスが bbs に接続して表明する。
つまり、rep が死んでいると、その diego cell は生きていないとみなされ、新しい app が VM 上でデプロイされなかったり、app の actual state が desired state とは異なると判断され、別の diego cell に再配置されたりする。
また自分の cell で動いている app の死活状態を確認している。そして、actual state を更新する。
代表だけあって、重要なプロセス。
runc
runc は CF とは全く独立したコンテナを実行するためのプロセス。CF では garden-runc と呼ばれたりする。
ちなみに docker でも内部的に runc が利用されている。Linux カーネルの機能を利用しているため、Windows や mac などでは動作しない。
route emitter
定期的に app の route, ip, port のメタデータを NATS あるいは routing api に送るコンポーネント。
BBS から router emitter はどこの diego cell に配置されているのか、どのような app が自分の cell に配置しているのかを取得する。
cloud controller (CC)
CF CLI で app の作成や削除、space, org の作成、route の map など行うが、それらのすべてのユーザコマンドを解釈して実行の橋渡しをするコンポーネント。
cloud controller が機能していないと、cf command の結果が返ってこないため、重要なコンポーネントだ。
例えば、cf logs コマンドは CC から RLP へリクエストが送られ、app のログを収集する。 また、cf routes コマンドは、CC から MySQL, routing api へ routing 情報を取得している。 (FYI: ここっぽい)
cf push の場合は CC から blobstore や bbs などへアクセスするなど、コマンド実行ために色々なコンポーネントを CC から叩くことになる。
routing api
今後構成が変わりうるが、routing api も cloud controller vm に配置されている。
現在は TCP App の routing を担当しているが、http routing についても routing api に機能を移すということが考えられているよう。
diego
diego は CF v2 から DEA -> diego へ大きなアーキテクチャ変更が 2015 年になされた。
diego とは self healing な container 管理システム。CC を通じてユーザから要求されたコンテナ状態 (desired state) を保つようにする。
- Diego Components and Architecture | Cloud Foundry Docs
- cloudfoundry/diego-design-notes: Diego Architectural Design Musings and Explications
実は diego で動かすアプリケーションの種類には 2 つあり、
- Long Running Process (LRP)
- Task
LRP はクラッシュしない限り動き続けるアプリケーションで、Task は一度実行が完了すれば消えるアプリケーションだ。
例えば、アプリケーションをビルドしたり、あるいは DB マイグレーションなどのバッチ処理は Task で実行できる。
diego と CF については設計上独立するように作られており、diego を k8s で置き換える Erini Project というのが 2019 年では注目されていたりする。 diego は例えば Concourse でも内部的に利用されていたりする。
bbs
Bulletin Board System (BBS) で掲示板を意味する。
diego において、現在の app の数や route の情報はすべて bbs に張り出される。それをもとに auctioneer がどこの diego cell に app をデプロイするか決めたり、route emitter が app の route 情報を取りに来たりする。
新しい container が必要になったら、bbs から auctioneer に頼んで作成する。 これは、diego cell の rep からリソース使用状況を確認して、一番適切な vm へ container を作ってもらう必要があるためだ。
container を削除するときは、直接 rep 越しに app container の削除を依頼する。
auctioneer
diego cell の rep が行った立候補のなかで、どの cell が最もリソースが空いているかを確認し、bbs に張り出される app のコンテナのデプロイ先を決定する(オークション)
cc uploader
diego の LRP, Task の droplet を CC の blobstore へアップロードできるように仲介するコンポーネント。 (CC と diego は独立して作られているため、実際の橋渡し約が必要になる)
ssh proxy
コンテナへの ssh を実現するためのプロキシ。
cf ssh を行うと、cf cli を実行するクライアント端末と ssh proxy 経由して diego cell の app で ssh を行うことができる。
開発環境ではコンテナへの ssh を有効にしている。user vip で 2222 ポートを解放しているのは、この proxy へアクセスできるようにするため。
NATS
NATS - Open Source Messaging System | Secure, Native Cloud Application Development のとおり、OSS の Message Queue。
CF は SPOF が作られないアーキテクチャになっている。そのため、NATS のような MQ に様々な情報をもたせて、各コンポーネントは producer, consumer としてその情報をやり取りする。
NATS には gorouter が利用する app の routing 情報、uaa や MySQL proxy など各コンポーネントの routing 情報が publish され、gorouter はそれを consume することで、CF 内の各コンポーネントへ routing できる。 (この仕組は bosh DNS によって代替されたりする)
NATS Network Communications | Pivotal Docs
schedular
cloud controller clock など定期的に実行する処理が動作するコンポーネント。
log
loggregator agent
各コンポーネントからログやメトリクスを取得し、doppler へ送信するプロセス。
App のコンテナからログやメトリクスを取得するのも metron agent の役割であり、ログを集める sidecar プロセスということができる。
loggregator agent に置き換えられる予定。
log cache
TBD
traffic controller
ログの出口となるコンポーネント。
firehose nozzle は traffic controller へ websocket で接続して、ログやメトリクスを取得する。
reverse log proxy
TBD
syslog adaptor
TBD