Amazon ECS を使った PaaS、Barcelona を作った話
Tweet先日、Tokyo Rubyist Meetup で、 弊社Degicaで開発した Amazon ECS を利用した PaaS、Barcelona の発表をしましたので、本記事でも紹介したいと思います。
Barcelona は AWS 上にアプリケーションプラットフォームを構築する PaaS です。 現在の Degica のWebサービスはほぼすべて Barcelona 上で稼働しています。
本記事では、Barcelona を開発するに至った経緯と、仕組みの概要を説明します。
乱立するインフラ
約2年前、僕が Degica に入社した頃の話です。
Degica では多くのWebサービスを運用していますが、これらのサービスの基盤となるインフラは (ほとんどのサービスがAWSを利用していること以外) まったく統一されていませんでした。あるサービスは AWS OpsWorks を利用、別のサービスはEC2, nginx, HAProxy, Consul 等を用いたクラスタ上で動作、また別の小さなサービスはHerokuを用いていた、という具合です。
それぞれのインフラを個別に見ると、いくつか問題を抱えてはいましたが、数年に渡りWebサービスを支えてきた安定した環境でした。したがって個々のインフラに大きな問題があったわけではありません。 問題だったのはDegica社内に全く異なる複数のインフラが混在していたことです。 Degica開発チームは10人に満たない小さなチームなので、すべてのインフラを別々に管理することは運用コスト上の大きな問題でした。 加えて、新しいサービスの開発を開始するという話も複数ありました。2年後の現在、結果としてWebサービスの数は当時の2倍以上に増えています。
Degica の特徴として、少ない開発者で多数のWebサービスを運営していることがあります。 これらに今後増加するであろうWebサービスを加えると、当時の状況では将来的に安定的な運用ができなくなるであろうことは容易に予測できました。
Barcelona
で、作ったのが Barcelona と呼ばれる Ruby on Rails で書かれた PaaS (Platform as a Service) です。 (名前の由来は、開発を開始したとき僕がバルセロナにいたことです)
Barcelona はWebアプリケーションが動作するために必要なすべてのAWSリソースを管理します。 また、ECS (EC2 Container Service) を使用してアプリケーションを管理します。
すでに GitHub 上で公開しているので誰でも利用できます。
特徴その1:AWSネットワークリソース群の抽象レイヤー
Webアプリケーションが動作可能なネットワークをAWS上に構築するのは大変です。VPC, Subnet, Security Group, Network ACL, NAT gatewayなど大量のリソースを正しく設定しなければなりません。 動作可能な設定にすることも大変ですが、それがセキュリティ上正しい設定なのか判断するには相当なネットワークとAWSに関する知識が必要です。
Barcelona はこれらのAWSリソース群の CloudFormation テンプレートを持っており、ネットワーク関連のリソース群を “District” と呼んでいます。 インフラを作成する上でやらなければならないのはこの “District” を作成することだけです。
また、SSHの鍵管理や権限管理も頭を悩ますところですが、これも Barcelona により管理されます。
特徴その2:ECSによるコンテナベースのアプリケーション管理
アプリケーション管理には AWS の docker ソリューションであるECS (EC2 Container Service) を採用しました。 ECSは柔軟で素晴らしいサービスですが、設定があまり容易ではありません。 WebアプリケーションのECSでの運用に限定すると、多くの場合大体似通った設定になります。BarcelonaがECSの設定を肩代わりすることで開発者の負担を軽減しています。
また、定期実行タスク、秘密情報管理、対話的コマンド実行 (heroku run
みたいなやつ) 等、ECS 単体では提供されない機能を Barcelona は提供します。
特徴その3:いつでもBarcelonaから逃げられる
Barcelona を開発する上で最も重要視したのはこの点です。Barcelona の主たる役割はあくまでAWSリソースの作成と設定です。 なので、Barcelona をシャットダウンしても Barcelona により作成されたクラスタは何事もなく動作を継続します。 Barcelona を使うのが嫌になったら、Barcelona が作成した CloudFormation テンプレート、S3バケット、ECS Task Definition を別の方法で管理すればよいです。
AWSの進化は速いので、Barcelona の開発が追いつかなくなるケースは将来的に大いにありえます。 Barcelona を使っているから AWS の進化に追従することを諦めなければならない、というのは最も避けるべき事態のひとつです。
特徴その4:他のAWSサービスの活用
Barcelona は、Barcelona が管理しないAWSサービスの活用を制限するものではありません。 例えば、RDS, ElastiCacheといったDBサービスを起動したり、Barcelona が CloudWatch Logs に出力するログを Lambda 経由で ElasticSearch に転送したりといった、AWS 機能の活用を Barcelona の管理外で実施することにはなんの問題もありません。 Barcelona をWebサービスが動作する環境の一部と捉えることでインフラ開発者は大きな自由を得ることができます。
何を解決したのか
Barcelona を Degica のインフラ管理の中心に据えることで、前述のインフラ乱立問題が解決しました。 Degica の基礎的なインフラはすべて Barcelona により構築・管理されるので、インフラ担当者の作業の大部分が Barcelona の開発に集約されます。 また、アプリケーション開発者は Barcelona の使い方を覚えれば、その知識はすべてのWebサービスに対して適用可能です。
Getting Started
以下の内容は Tokyo Rubyist Meetup で発表したデモの内容の補足です。雰囲気をつかむにはデモ動画を見たほうがいいかもしれません。 また、GitHub 上にマニュアルがありますので、より詳細な情報を知りたい方はそちらを参照してください。
クライアントのインストール
Barcelona の操作はすべてコマンドラインクライアントで実施します。まずは以下のページからクライアントをダウンロード、unzip して PATH
の通ったディレクトリに配置してください。
https://github.com/degica/barcelona-cli/releases
Bootstrap
Barcelona を使うためには、Barcelona API Service がデプロイされている必要があります。 以下の Bootstrap スクリプトを実行すると、AWS ECS 上で Barcelona が起動します。 実際に AWS のリソースを作成するのでお金がかかることに注意してください。ミニマム構成で月約一万円くらいかかります。
docker run --rm -it quay.io/degica/barcelona bin/bootstrap
ログイン
Barcelona にログインします。ユーザーは GitHub Organization または Team で認証されます。デフォルトでは bootstrap 実行時に入力したOrganizationに所属する GitHub ユーザーのみログイン可能です。クライアントの指示に従って GitHub Tokenを入力してください。
$ bcn login <Barcelona domain name>
District の作成
District はすべてのアプリケーションで共有されるAWSリソース群です。VPC, Subnet, Security Group, ECS Cluster, S3 bucket, 踏み台EC2インスタンス、などなどで構成されます。
Bootstrap を実行すると default
という名前の District が自動で作成されるため新たな District の作成は今回は不要ですが、以下のコマンドを実行すると新しい District を作成できます。
$ bcn district create --region=ap-northeast-1 <district name>
以降は bootstrap により作成された default
district を使用します。
Endpoint の作成
Endpoint はHTTP/HTTPSリクエストを受け、後述のServiceに転送します。
Endpointは ALB (Application Load Balancer), Route53 Record, ACM (Amazon Certificate Manager) 証明書で構成されます。
以下のコマンドで default
district 内に demo-endpoint
という名前の Endpoint を作成します。
$ bcn endpoint create --district=default demo-endpoint
barcelona.yml
Barcelona 上で動作するアプリケーションの設定はすべて barcelona.yml
というファイルに記述します。
このファイルはアプリケーションのレポジトリにチェックインされることを意図しています。
以下の barcelona.yml
はデモで使用したものからの引用です。
environments:
production:
name: sinatra-demo
image_name: k2nr/sinatra-barcelona
services:
- name: web
service_type: web
cpu: 32
memory: 128
command: bundle exec ruby main.rb
listeners:
- endpoint: demo-endpoint
health_check_path: /
素直に読み下せると思いますが、この例は以下のことを示しています。
- このアプリケーションは
production
という環境をもつ(必要であればstaging
のような別の環境を持つこともできます。) k2nr/sinatra-barcelona
をこのアプリケーションの Docker イメージとして使用する- このアプリケーションは
web
というサービスをもつweb
は HTTP リクエストを受けるためにdemo-endpoint
という名前の endpoint と紐付いている
アプリケーションのデプロイ
ここまででアプリケーションを作成する準備が整いました。あとはアプリケーションを Barcelona 経由で作成するだけです。
新しいアプリケーションを作成するには barcelona.yml
が存在するディレクトリで以下のコマンドを実行します。
$ bcn create --district=default -e production
新しいバージョンをデプロイするには以下のように bcn deploy
コマンドに docker image tag を指定します。
$ bcn deploy -e production --tag v2
まとめ
インフラメンテナンスの容易性、アプリケーション開発者に使いやすいツール、高セキュリティ、AWS サービスを利用した拡張性を同時に実現するのは難易度の高いチャレンジでしたが、Barcelona により一定の成果が得られました。 もちろんアプリケーションプラットフォームに求めるものは各社様々ですし、Barcelona の開発もまだまだ初期段階なので、Barcelona を導入すれば御社もハッピーなどと喧伝するつもりは毛頭ありませんが、Barcelona が解決した多数の問題のうちの一部くらいは、その手法が参考になることもあるかと思います。
ぜひソースコードを読んでみてください。 プルリクエストお待ちしています。