はじめに
ふざけたタイトルで始めましたが、とあるシステムを移植する際に発生した問題、結局どうしたかについて書いていきます。最初に感想を話すと、「知見がなさすぎる、ツライ」です(もっと勉強しないとなぁ…)。
さて、事の発端は現行のNextCrowd4U(N4U)に以下のような状況が発生していることです。
- N4Uに依存している訳ではないが、N4Uの環境に共存しているシステムが存在している
- 現状は問題ないが、今後の機能実装の際に本番環境のリソースを圧迫する可能性がある
以上の理由から当該システムをN4Uから切り離すこと、また当然ながら研究費は限られていますからできる限り低コストで移行する必要がありました。
すぐにできそうかなと思っていたのですが、結果何もわからず1か月くらい格闘することになったので書いていこうと思います。
図が大雑把なのはご愛敬と思いながら読んでいただけると幸いです。
前提条件
切り離しの際にいくつかの前提条件がありましたんので最初にまとめておきます。
- Goで実装されたAPI
- システムの内部処理で外部API(Google Search API)を使用している
- Search APIのリソース削減のため、Memcachedを使用している
- 検索結果をキャッシュして同一の検索クエリに対してAPIを使用せずに結果を返すようにしている
これに加え、コストをできるだけ低くするという制約が存在しています。
①おれのかんがえた最強の構成
最初に考えたのは以下のような構成です。
ElastiCache(Memcached)と接続するためにLambdaをVPC内に配置しています。
LambdaはGoに対応しているので、Lambdaでシステムを実行し、APIGatewayでAPIを立てるのが一番良いのかなという話です。
しかし、この構成には問題点が存在し破綻しました。
Lambdaが外部サービスと通信できない
一か月ほど格闘した主な理由はこれに気づくのに時間がかかりすぎた事です。
そもそもGoのソースをLambdaで使えるように変えていなかったみたいなゴタゴタがありながらも、デプロイがうまく行かなかった際に主にうまく行かなかった理由は以下の2点でした。
- ElastiCacheとからレスポンスが返ってこない
- Search APIにリクエストを投げることが出来ない
1に関してはアウトバウンドルールの設定が間違っていたことが原因で解決にそこまで時間はかかりませんでした。
問題は2で、セキュリティグループですべての通信を許可するように設定しても通信が上手くいかないところまでは分かっていたのですが、だからこそIAM Roleやソースコード側に原因があると思い込み、先輩に指摘されるまでVPCはじめネットワーク周りの調査を全然してませんでした。
先輩の指摘後、改めて調査すると以下の記事を見つけました。
VPC LambdaはIGWからインターネットに出られないわけではなかったという話 | DevelopersIO
なんと、VPC LambdaはパブリックIPを持たないらしい。。。
自分でも検証してみましたが「な か っ た」。外部と通信できないのはそれはそうという感じですね()
つまり以下の現象が本構成でシステムを実装する際に発生しています。
- ElastiCacheと接続するためにLambdaはVPC内に配置する必要がある
- しかし、VPC LambdaはパブリックIPを持たないため外部と通信できない
これの対応方法として、
- NAT Gatewayを利用する
- Lambdaをあきらめる
という2つの方法が存在します。実際に採用した構成を次節で紹介します。
②実際に採用した構成
最終的に、1のNAT Gatewayを利用するコストと2のECS(Elastic Container Service)やElastic BeanStalkなどを利用するコストを検討した結果、以下の4つの理由から後者の選択肢(ECS Fargate)を選びました
- STGの際に使用したことがある
- 常に使うシステムではないため使わない時は停止しておきたい
- 軽いシステムなので大してvCPUやメモリを消費しない(最小設定で実行可能)
- 2・3の理由からNATを使用するよりコストは抑えられる可能性が高い
ここからはSTG環境で使用したタスク定義ファイルを一部使いまわしながら、サクッと実装することが出来ました。
また、AWSのコストを$200減らすために行ったこと でも紹介した通り、ECRのライフサイクルポリシーの設定やSpotインスタンスの採用を行っています。
出来ました!で終わってしまうのもテックブログとして微妙ですが何はともあれ以上の構成で無事にシステムの移行を行うことで出来ました。
終わりに
今回のタスクをこなす際の感想は最初に書いた通り、AWSやインフラ全般に対する経験や知識量の不足から詰まる事が多かったなという印象です。
純粋な力不足から何もない所で転びがちだったと思うので、知識経験ともに増やしていきたいなと強く思った次第です。