Chapter 02

設計での失敗と成功例

株式会社var(ヴァー)
株式会社var(ヴァー)
2022.12.13に更新

最初、どこから作りはじめたかについて話します。
技術者向けに書いていますので、非エンジニアの方は、飛ばしながら読んで頂ければと思います。

【失敗談】AWSでとりあえず作ってみようからスタート

後にわかりますが、この実装は後に全てなくなります。(笑)

動的にコンテナを起動させるシステムを実装するので、まずは、Dockerに関する調査から始まりました。
Docker はデフォルトでは UNIXソケット を利用して操作を可能にしますが、 TCPソケット も利用できることがわかりました。

よって、コンテナを起動するためのサーバーを立て、そこにコンテナの起動や終了のリクエストを出すことで遠隔からコンテナ操作を可能にすることを考えました。

構成図は以下の通りです。

以下の3つの機能が必要です。

  1. Webアプリケーション = EC2
  2. Dokcerコンテナを起動・停止するAPI(docker-manager) = EC2
  3. Dockerコンテナを動作させるサーバー群 (コンテナサーバー) = EC2

ユーザーからのアクセスを通常のWebアプリケーションで受け、その後コンテナオーケストレーションシステムの下位互換のような API を実装し、API経由で コンテナが立ち上がるサーバー(以後、コンテナサーバー) 上でDockerコンテナを起動する構成を考えました。

docker-manager の役割は、docker-compose コマンドとほぼ同じで、コンテナ起動の設定ファイルを読み込み、それに応じたユーザごとの専用コンテナを作ることです。しかし、docker-compose はAPIとして用意されているわけではないので、自分達で書く必要がありました。

ユーザーは コンテナサーバーGlobal IP を利用して各コンテナにアクセスすることを想定していました。そのため、ユーザごとに踏み台コンテナを作成し、ユーザごとに別々のポートを介してコンテナにアクセスさせようと考えました。

【失敗談】プログラミング言語はなんでもよくない

早速、Pythonを利用してオリジナルの docker-manager を作成しました。

Pythonを利用した理由は、

  • Pythonになれていたという超絶安易な理由
  • Dockerのクライアントライブラリが便利そうという希望的観測

ちなみに当時は、人に誇れるほどのWebやAPIの開発経験はなく、大学の研究のためにPythonで少しプログラムを書いたり、CTFを解くために必要なプログラムをかける程度の能力でした。

そこで、REST API なるものをググって、いい感じに実装をはじめました。(いい感じってなんだよ。)

重量級フレームワークである必要はなかったので、 Flask を選定しました。

【成功談】アーキテクティングって大事。システム構成図とプログラミング言語の変更

2週間ほどである程度動くものができたのですが、完成した後に問題が発生しました。

それは、「なんか遅い」ということです。遅い原因としては、以下の2つだと結論づけました。

  • コンテナサーバーの起動が遅い
  • プログラムが遅い

そもそもコンテナが起動するだけのサーバーに、EC2のようなサーバーが必要なのか?という疑問から、コンテナ起動に特化したOSがないかを調査したところ、GCPにCOS(Container Optimized OS)があることを発見しました。

また、Docker自体がGoで書かれていること、Pythonより早いということからGoの方が相性が良いと判断し、Goに切り替えました。

さらには、APIはサーバーレスに移行しました。

まとめると、以下のようになります。

変更前 変更後
AWS GCP
EC2(Amazon Linux) GCE(Container Optimized OS)
APIサーバー サーバーレスなAPI
Python Flask Go Echo

結果として、体感5秒以上のタイムロスを実現でき、ワンクリック5秒で環境を起動できるようになりました。

この時のサービス全体のアーキテクチャー図はこちらです。後に、このアーキテクチャー図はもう少し変更が入ります。