📥

Pull型デプロイツール stretcher - fujiwara-ware advent calendar 2024 day 8

2024/12/08に公開

この記事は fujiwara-ware advent calendar 2024 の8日目です。

本日は、10年前に開発した(でも今でも使われているらしい)ちょっと懐かしいツールを紹介します。

stretcher とは

https://github.com/fujiwara/stretcher

stretcher は、Pull型デプロイツールです。Pull型デプロイツールとは、デプロイ先のサーバーが自分でデプロイメント(の成果物)を取得する方式のことです。

  • Push型デプロイツール = デプロイ元がデプロイメントをデプロイ先(複数)に送る方式
  • Pull型デプロイツール = デプロイ先がデプロイメントをデプロイ元(ネットワークストレージやコンテナレジストリ)から取得する方式

デプロイするサーバーが大量にある場合、Push型デプロイツールはデプロイ元の負荷が増えてしまいます。例えば100台にデプロイする場合、そこから100台にデプロイメント(往々にして数十MB〜数百MBという大きいサイズ)を送信する必要があります。EC2 のようなサーバーを利用している場合、高速にデプロイするためにはネットワーク帯域や CPU がボトルネックにならないように、大きなサイズのインスタンスを使う必要があります。しかしそれでは、デプロイのためだけにコストが増えてしまいます。

Pull型デプロイツールはデプロイ先のサーバーが自分でデプロイメントを取得するため、デプロイ元の負荷が増えません。もちろん取得元ストレージの負荷は増えますが、昨今のクラウド環境では強力なマネージドサービスが提供されているため、それらの負荷はあまり問題になりません。例えば Amazon S3 や Google Cloud Storage などを利用すれば、安価に大量のトラフィックを捌くことができます。

なぜ作ったのか

stretcher を開発したのは 2014 年のことです。個人的な仕事の話ですが、当時運用していたサービスの動画変換のために、大量の EC2 Spot Instance を使っていました。動画変換の需要は時間帯によって非常に大きな波があり、コスト最適化のためには動的にサーバーを増減させる必要があります。

アプリケーションの更新があれば速やかに大量のサーバーにデプロイする必要がありますし、需要に応じて新しいサーバーを起動するたびに、そのサーバーには最新のアプリケーションをデプロイしなくてはいけません。

現代であればこのようなケースは、コンテナを使って解決することが一般的です。しかし当時はまだ、コンテナオーケストレーションサービスを本番で使うのはあまり一般的ではありませんでした。例えば Amazon ECS は 2015 年リリースですし、Kubernetes の v1.0 リリースも 2015 年です。

stretcher はこのような状況下で、大量のサーバーに対してアプリケーションを動的にデプロイするために開発されました。

https://techblog.kayac.com/10_stretcher.html

動作原理

stretcher のやることは単純です。

  1. 起動すると、標準入力からデプロイメント(tar.gz)のURLを受け取ります
  2. そのURLからデプロイメントを取得して展開します
  3. デプロイメントを展開したら、指定されたコマンドを実行します(例えば、サービスの再起動)

原理はものすごく単純なので、実は最初は shell script や Perl で書こうかと思ったぐらいです。しかしそのころから Go を使うようになっていたため、Go で書くことにしました。Go で書いたツールはシングルバイナリで配布できます。デプロイをするために他の何かをインストールする必要がないのは、運用する上で非常に便利です。

Stretcher と Consul

stretcher はデプロイメントの URL を標準入力から受け取ります。どのような手段であってもでデプロイしたいサーバーの stretcher コマンドにデプロイメントの URL を送れば、stretcher はそれを取得してデプロイします。

当時運用していたサービスでは、大量のサーバーを管理するために Hashicorp 社が開発した Consul を使っていました。Consul は Key-Value Store や Service Discovery の機能を持っており、サーバーをクラスタリングして管理するのに便利です。

consul event という仕組みを使うと、クラスタ内のサーバーに一斉にイベントを送信できます。stretcher はこの consul event からの通知で URL を受け取ってデプロイを行うのを想定して開発されました。

Consul 以外での利用

もちろん Consul 以外でも stretcher は利用できます。要するに標準入力から URL を与えてコマンドを実行するだけでよいのです。

実際に自分が運用していた別のサービスでは、ssh で対象サーバー上の stretcher を実行し、その標準入力に URL を与えることでデプロイを行っていました。

デプロイ元から ssh するなら実質 push 型ではないか、と思われるかも知れません。しかし基本を pull 型にしておけば、サーバーの起動時に最新の URL を取得する方法を用意しておくことで自動的なデプロイが可能です。つまり、オートスケール環境でも pull 型デプロイが可能になるのです。

アプリケーション以外での利用

stretcher はアプリケーションのデプロイ以外にも利用できます。

URL から何かを取得してコマンドを実行するわけなので、例えば設定ファイルを取得してサービスの再起動を行う、IaCツールのコードを取得してプロビジョニングを行う、などの用途にも使えます。

実例として、サーバーのプロビジョニングのために Chef のレシピを取得して実行するという使い方があります。次の記事では、stretcher と Chef を組み合わせた利用事例を紹介しています。

https://techblog.kayac.com/lobi-about-deploy.html

利用事例

stretcher は 2014 年に開発され、筆者が勤務している面白法人カヤックが運用している各種サービスで利用されました。Lobi が代表的なサービスです。

その後時代の趨勢がコンテナに移り変わり、2018年からは Amazon ECS で ecspresso を使うようになったため、stretcher は新規で採用されなくなりました。とはいえ2015年にリリースされて2024年まで続いたとあるサービスでは、最後まで stretcher が使われ続けました。

また、最近でもカヤック以外で使われている事例があるようです。

https://techfeed.io/entries/63fc72b421661c2083432bff

リリースから10年が経ちますが、メンテナスは継続しています。利用していた aws-sdk-go(v1)が EoL になったため、2024年6月には aws-sdk-go-v2 に対応した v1.1.0 をリリースしています。

https://github.com/fujiwara/stretcher/releases/tag/v1.1.0

まとめ

Pull型デプロイツール stretcher について紹介しました。10年前に開発したツールですが、今でも使われている事例があるようです。

コンテナ環境のデプロイというのは、要するにPull型デプロイです。起動したコンテナランタイムが自分でコンテナレジストリからイメージを取得して起動するのですから。そういう意味では、今でもスケーラブルにデプロイするための原理は同じなのですね。

それでは、明日もお楽しみに!

関連資料

https://dev.classmethod.jp/articles/push-deployment-with-consul-and-strecher-at-scale/

https://speakerdeck.com/fujiwara3/consultozi-zuo-osswohuo-yong-sita100tai-gui-mo-falsewebsabisuyun-yong

https://speakerdeck.com/fujiwara3/stretcher-1

https://speakerdeck.com/fujiwara3/awsfalseotosukerutonakayokufu-kihe-u

https://speakerdeck.com/fujiwara3/consul-casual-1

Discussion