spikatalk _ vol.1 _ Mobile top.png
spikatalk _ vol.2 _ desktop top.png

#spikatalk

vol.2 開発チーム

#spikatalk vol.2
開発チーム

株式会社スピカの開発チームとしてネイルブックを支えてきた南雲さん。
今回は、サービスを止めずインフラをコンテナ化した頑張りについて伺いました。

はじめに

ネイルブックというサービスは10年以上の歴史があり、これまでAmazon Web Services(AWS)のEC2インスタンスで動いていましたが、今年コンテナ化という大きな変更が行われました。
サービス中の古いインフラを変更するにあたっては大変な苦労があったと思います。
今回は、コンテナ化に携わられた南雲さんにお話を伺いました。

編集部注:技術用語が多く出てきますが、補足説明は割愛させていただきます。

1.JPG

ー なぜコンテナ化しようと思ったのでしょうか?

いくつか理由はありますが、半分は時流に乗り遅れないようにと考えたからです。残りの半分は業務の効率化や属人化している部分をなくしたいと思ったからです。
コンテナに置き換える前は、EC2インスタンスのAMIを作って、インフラをリリースするたびに本番で稼働させているサーバーを置き換えていました。
自分しかその対応ができず属人化していたため、手作業で1〜2時間かけてリリース後の動作確認などを行っていました。このような手間を省くために、コンテナ化しようと決めました。

サービス無停止や運用フローに変更がない移行を計画していたので、準備に多くの時間をかけました。

ー 移行計画を立てるにあたって考慮したことはありますか?

調査を始めた際に、インフラのコンテナ化について情報がいくつかあったので参考にしました。ただ、既存インフラの置き換えより新規インフラ構築の話が多く、EC2インスタンスからコンテナへの移行に関する情報が少なかったです。

コンテナ実行基盤のデファクトスタンダードとなるとKubernetes(k8s)があり、ECSとどちらを採用するかは迷いました。最終的にECSにすることにしましたが、一時期はk8sの知識を収集していた事もありました。

ー KubernetesではなくECSにした理由を教えてください。

時流に乗り遅れないという目的を達成する観点ではどちらでもよかったのですが、調査をした当時、AWSのFargateではKubernetesを動かせないことがわかりました。AWS Fargateを使うとインフラの管理が楽になるので、これを使うことを前提で考えていたため、ECSで方針を固めました。

 

また、コンテナ化の目的の1つが属人化の排除だったことも考慮しています。Kubernetesは学習コストが高く、他のメンバーが関わってきたときのことを考えるとECSの方が良いと判断しました。


AWS Fargateはインフラの変更するときに保守しなくて良いため、ぜひ導入したかった技術です。

ー どのような移行計画を立てましたか?

大前提として、既存のデプロイや運用フローを一切変えることなく移行したいと考えていました。

サービス無停止でのインフラ移行は必須要件ではありませんでしたが、夜中に営業されているサロン様でもご利用いただけるよう、可能な限り無停止で実施したいという思いがありました。

 

また、EC2インスタンスで運用していたときはインスタンス内に状態やリソースを保持していましたが、コンテナ化するとそういうわけにはいきません。そのため、コンテナ化を行う前の準備として状態やリソースがインスタンスに依存しない構成に変更していきました。


一つ変更例をあげると、当時JavaScriptやCSSは、EC2インスタンス上で稼働しているnginxから配信していましたが、EC2インスタンスからではなくCDNから配信する方式に変更しています。

ー コンテナ化が完了するまでにどのくらい期間がかかりましたか?

1年ぐらいかかりました。

調査や事前準備、既存処理の変更など、実際に移行を開始する前に完了しておくべき作業が6割で、残りは実際にEC2インスタンスからコンテナ化への置き換え作業です。

サービス無停止や運用フローに変更がない移行を計画していたので、準備に多くの時間をかけました。

ー 事前準備で大変だったことはありますか?

アプリケーションのログの取り扱いです。

ネイルブックではアプリケーションのログを収集して閲覧可能にしているのですが、EC2では各種サーバー上に出力されたログをfluentdでログ集約サーバーに転送し、ログ集約サーバーからAmazon S3の所定のパスにログをアップロードする構成にしていました。

 

一方、コンテナ化したらログはKinesis Firehose経由で転送する構成にしようと思っていました。

 

ところで、ログの検索にはAWS Athenaを利用しており、パーティションを効かせるためにS3にはログの発生時刻を元に所定のパス配下にログをアップロードする必要があります。

 

既存の仕組みではパスがJSTベースで作成されていたのですが、Kinesis FirehoseはUTCベースでパスが作成されるため9時間分ずれたパスにログが転送される事になり、ログの検索が正しく機能しなくなることが判明しました。

 

そこで、

 

・既存のログのs3へのアップロード処理でJSTベースのパスとUTCベースのパスの両方に転送するようにする
・過去分のログのパスを全部UTCベースのパスに移動
・JSTベースのパスへの転送を停止

 

という対応を取り、既存の仕組みに影響がでない形でログの移行を行いました。

 

KinesisのFirehoseは導入してよかったです。
既存の仕組みでは、ログ処理サーバが単一障害点になっていましたが、Firehoseを導入して解消しました。
また、ログ処理に最大5分かかっていたところを最大1分で完了するようになり、リアルタイムに近いログを閲覧できるようになりました。

ー ネイルブックの新しいシステムで単一障害点はありますか?

ログ処理サーバの単一障害点が解消されたため、本体の運用に影響を与える部分での単一障害点はなくなりました。 

2.JPG

ー サービス無停止でインフラ移行できた秘訣を教えてください。

先ほどログのところで説明したような、新旧インフラの並行稼働状態を作った上で新しい方のインフラに処理を寄せていくという手法を多用しました。
両インフラで動いている状態にして、安定したら切り替えるということを繰り返しました。

例えば移行時期は現行インフラのEC2インスタンと新インフラのAmazon ECS(コンテナ)の両方にデプロイするようにしていました。

 

Amazon Route 53には加重ルーティング機能があり、たとえばnailbook.jpへのアクセスの内、1%だけ新インフラにトラフィックを向けるというようなことができるので、これを利用して検証を繰り返し、少しずつ流量を新インフラに向けていく方法を採用しました。

ー その他にデプロイで工夫したことはありますか?

コンテナ化により既存の運用を変更しないという目的を達成するにあたり、以前行っていたデプロイ処理の改修が功を奏しました。

 

入社当時、デプロイにはFabricというPythonのツールを利用していました。
但し、Fabricはデプロイ先のサーバーに侵入して行う作業を記述するスタイルのツールのため、デプロイ先のサーバーの構成変更がFabricのデプロイスクリプトの修正を要求するケースがありました。

 

そこでCTOと相談して、デプロイスクリプトとデプロイ先を疎結合にする改修を行いました。

 

具体的には、デプロイ時にはリリースするアセットを識別するIDのようなものだけをやりとりするようにし、それを元にデプロイ先がどのようにデプロイを行うかについては関知しないように修正しました。

 

このようにデプロイ時のインターフェースだけを取り決めておいたので、デプロイ先にECSを追加する事になってもデプロイ処理のメインフローには全く手を入れる必要はありませんでした。


ビルド処理にも工夫をしていました。ここでいうビルド処理とは「webpackのバンドルを作る」「静的アセットをCDNに反映する」といった一連の処理のことを指しています。

 

コンテナはイミュータブルにしたいという考えがあり、リリースに対応するバージョンのアプリのコードやビルドの成果物の一部はコンテナに埋め込む方針にしました。そのようにして作成したコンテナのイメージをECRにプッシュする必要があるのですが、既存のデプロイスクリプトを改修してこれらの処理を行うのは筋が悪いと考えたので、この辺りの処理をAWS CodeBuildに移行させました。

 

これはこれで幾つかハマるポイントがあったのですが、なんとか移行できました。

以前行っていたデプロイ処理の改修が功を奏しました
3.JPG

ー 移行で失敗したことはありますか?

全てのコンテナをFargate上で動かしたかったのですが、一部のコンテナをFargate上で実行すると安定した運用ができないケースが発生してしまった事です。

そのため、Fargate上で安定運用が難しいものについては、EC2インスタンスをコンテナ実行基盤として採用しています。

 

原因は、AWS Fargateの制約でネットワークの同時接続数が大きく増やせなかったためです。AWSにも相談してみましたが、Fargateのタスク数で調整するしかないとのことでした。
 

インフラを移行して、ユーザ体験の改善に貢献できました。

その対応をしてしまうとCPUやメモリなどのリソースが余ってしまい、コンテナ化の良さが活かせないため、暫定的に現在のような構成にしています。

 

AWSが公式に提供しているECS実行基盤用途のAMIをベースにしており、インスタンス自体に複雑なプロビジョニングを行う必要はないので、運用の手間はそれほどかかりませんが、AWS Fargeteで同時接続数の上限があげられるようになったら、すぐにFargateにしたいと考えています。

ー コンテナ化をやりとげた感想を教えてください。

やってよかったと思います。

インフラを移行して、ユーザ体験の改善に貢献できました。
以前の環境で発生していた、デプロイ中にユーザがレスポンスを待つ状況が改善されたので、ユーザ体験が良くなっています。

ー その他コンテナ化を行ってよかったことはありますか?

リソースを細かくコントロールできるようになりました。
ネイルブックでは非同期タスクをCeleryで処理しているのですが、一時的に非同期処理を多く回したいときなどにリソースを柔軟に変更できます。

 

また、コンテナが落ちた場合、自動的に検知して新しくコンテナが立ち上がるようになっているため、耐障害性も上がりました。

ー 今後の課題があれば教えてください。

トラフィックの状況に応じてリソース調整を柔軟にできるような基盤が整ったので、今後はコスト最適化に取り組んでいきたいと考えています。

4.JPG

ー 最後にCTOから見た南雲さんの頑張り、評価などを聞かせてください。

サービスを止めずに移行するのはとても難しいですが、それをやりきったことが素晴らしいです。

「状態に依存しない」構成を実現するにあたり、バックエンドのコードを書き換える必要がありましたが、南雲さん自身で対応してくれて、フルスタックな活動をしてくれたことにも感謝しています。

ー 求職者へのメッセージがあればお願いします。

インフラだけにとどまらずプログラミングにも取り組め、フルスタックエンジニアとして成長していくことができる環境です。幅広くマルチに活躍していきたいと考えているエンジニアの方がいましたら、ぜひご応募お待ちしています。

コンテナ化について、このインタビューでは詳細をお伝えしきれなかったので、オフィスで語り合いたいですね!