「人事労務freee」のEC2→EKS移行で、大変だったことと良かったこと

freee Tech Night で司会をしていますのぶじゃすです。4月23日に配信した「freee Tech Night Online #10 〜人事労務freee、EKS移行」の様子をご紹介します。人事労務freeeのアプリケーションエンジニアhanakeとSREのnekottyoの二人に、移行の経緯、プロセス、導入後のメリットとデメリットについて語ってもらいました。

登壇者の写真
登壇者の写真

  • hanake: 写真左上

    • 人事労務freeeのアプリケーション開発担当。
    • 前職でdockerの使用経験あり。インフラの知識を持ちながら、スクラムマスターとしてプロジェクトをリード。
    • 今回は、アプリケーションエンジニア側からEKS移行にチャレンジした。
  • nekottyo (@nekottyo): 写真右上

    • 人事労務freee担当のSRE。AWS、EKS周りの管理がミッション。
    • Datadogでの監視も担当し、安定稼働のための開発を担っている。
  • のぶじゃす (@noblejasper): 写真右下

    • ラジオパーソナリティ、2017年に中途入社
    • mixi、ソーシャルゲーム企業でソフトウェアエンジニアを経験し freee に。入社後はエンジニア→エンジニア採用担当→エンジニアと DevBranding を担当。
    • しゃべりたがり。声が大きい。

EKS移行の目的は、障害からの復旧を早めることと、属人的な運用から脱却すること

ご存じない人もいると思いますので、EKSについて簡単に説明してもらえますか。

hanake: はい。EKS (Amazon Elastic Kubernetes Service) は、AWSが提供するKubernetesのマネージドサービスです。主にコントロールプレイでの管理を行うことで、高い可用性を担保できます。Kubernetesの知識を持っていれば、EKSで一般的なWebサービスの本番運用は可能だと思います。

なぜ、人事労務freeeをEC2からEKSに移行したのですか?

hanake: 2つの理由があります。「障害からの回復時間」を早めたかったのが1つ目の理由です。従来は大量のnodeがLoad Blancerにひもづいている状態で、そのうちいくつかのnodeが落ちないことがあって、障害からの回復のためのデプロイに時間を要していました。KubernetesをEKSで運用すれば、明確なpod shutdownのルールが存在しているので、正しく落ちないなどの変な挙動をするnodeの影響を無くすことができると考えました。

2つ目の理由は、「属人化されたインフラ運用」を仕組み化したかったからです。特定の人物しか理解していない運用箇所があったので、EKSで管理をすることで仕組み化することを目指しました。AWSのマネジメントコンソールを活用して、問題が生じた場合は誰でも特定できるように変えたのです。具体的にはTerraformとHelm Chartで管理するように、nekottyoが整備してくれました。nekottyo、ありがとうございます!(笑)

既存のEC2環境のAPMデータをもとに、EKSの負荷試験を行った

移行準備での困難を淡々と語るnekottyoさん
移行準備での困難を淡々と語るnekottyoさん

EKSへの移行は、誰が発案されたのでしょうか?

hanake: アプリケーション側が発端ですね。何人かのエンジニアで集まって、「もっとイケてるインフラにしよう」と話し合って、SRE側を巻きこんだことからプロジェクトがスタートしました。

移行準備で特に大変だったことを教えてください。

nekottyo: EKSに移行するためにコンテナを準備して、dockerファイルを整理してリハーサルしたのですが、そのときはうまく動きませんでした。アプリケーションを動かすための環境変数を入れていなかったり、プリコンパイルされたJavaScriptやCSSが読めなくて、文字だけのhtmlが表示されたり。

やっと動くようになったら、今度はパフォーマンスの問題が発生しました。人事労務freeeでの移行プロジェクトは、新規にEKSを導入するのではなく、EC2から移行する作業でした。EC2 環境と同じ性能を出すことが求められるのですが、プロジェクトの初期においては、私たちに知見が足りなかったんだと思います。

既存のEC2環境のAPMデータをもとに、EKS環境のレイテンシなどの平均・最大を取得しながら負荷試験を行うことで、何とか同じパフォーマンスが出せるようになりました。色んなボトルネックが見つかり、リソースの再設定や、Kubernetesのパラメータの調整を行うことで改善を重ねましたね。

最も大きなボトルネックになったのは何ですか?

nekottyo: これ!という大きなものは無くて、細かい不具合が幾つか出ていた感じです。メトリックスを取ったり、アプリケーションの動きをAPMで追うことで特定していきました。1つを改善しても他のボトルネックが現れることも多く、問題を見つけては直す、の繰り返しでした。

DNSレベルでリクエストをEC2とEKSで分散。問題なく1日で移行作業を完了した

ヤバかったエピソードを笑顔で語るhanakeさん
ヤバかったエピソードを笑顔で語るhanakeさん

導入作業で最も大変だったことは何ですか?

hanake: 決まった時間・間隔で何らかのタスクを進める「CronJob」という機能があります。その中に「suspend」というパラメーターがあって、CronJobが動かない「true」のstatusでデプロイを進めていたのですが、何かのタイミングで「false」に切り替わったのです。夜中の12時に行うべきバッチが走ってしまった、というエピソードがあります(笑)。

それはヤバいですね!!

hanake: 検証環境だから問題は無かったのですが、ビックリしましたね。「startingDeadlineSeconds」を設定すれば回避できるのですが、当時はその知見がありませんでした。Kubernetesの「ハマりポイント」の一つに、順調にハマったという感じです(笑)。

nekottyo: 調べれば分かることなのですが、初めてだったので仕方が無いですね。

実際の導入作業自体はどうでしたか?

hanake: 割と順調に進んだと思います。すごく慎重に作業しましたので。route53 の weighted recordという機能を用いて、DNSレベルでリクエストをEC2とEKSで分散しました。最初は1%をEKSに流して、99%をEC2に流す仕組みをつくって、そこから徐々に、5%→10%→50%→100%と上げていったのです。何か起こったら作業を止めるフローを確立していたので、ドキドキはしましたが、1日で問題なく移行が完了。ユーザー側から見ると、何一つ挙動は変わらないので、クレームなども一切ありませんでした。

デプロイが圧倒的に安定するように。監視の一元管理を可能にした

それはすごいですね!移行の結果として、当初の課題は達成できましたか?

hanake: 解決できた部分は多かったですね。1つ目の課題「nodeがうまく落ちなくて、障害対策に時間が掛かる」については、podを落としてrolling updateをすることで解決しました。Kubernetesでは詳しい設定を行えば、スムーズに処理を行えます。変なnodeがあっても落とせる仕組みがあるので、デプロイは圧倒的に安定しましたね。

2つ目の課題「属人化されたインフラ運用」については、ほぼ全ての運用をTerraformとHelmfileで管理することで、誰がコードを見ても分かるようになりました。

nekottyo: 今回移行したのは「人事労務freee」ですが、ウチの会社はそれ以外にもEC2でサービスを運用しています。今後、移行が発生したときにスムーズに進められるようにHelm Chartを整備しています。アプリケーション開発側でこれらのツールを活用してもらうことで、異なるサービス間でも品質が統一される仕組みをつくれました。

実運用のフェーズに入って改めて感じた、EKSのメリットは何ですか?

hanake: やはり障害の回復が早くなったことでしょうか。スケールイン、スケールアウトの速度が全然違います。以前はnodeの立ち上がりに5-10分掛かっていたのですが、Kubernetesではpodでの管理になって、かなりスケールが速くなりました。1-2分くらいです。たとえば、給与計算は処理のタイミングが集中して多くのpodを要求する状態になるのですが、一気にさばけるようになりました。

nekottyo: 監視ツールも併せて移行することで、運用を強化できました。EC2のときは、Kibana、Mackerelといった複数のSaaSを使用していたのですが、EKS移行に併せてDatadogにまとめました。以前はオペレーションも煩雑で、学習コストも掛かっていたのですが、概ね解消できましたね。現在は、ログもメトリックスもAPMの状況も、ダッシュボードを見れば全て把握できます。不具合があればアラートが上がる仕組みも導入することで、障害対応も効率化できました。

EKS導入のデメリットは学習コストと、デプロイ時のコンフリクト

逆にEKS導入のデメリットはありますか?

hanake: アプリケーション側としては、現状では学習コストが高いです。Kubernetesは抽象化が進んでいるので、何か作業をする際にも、ある程度の知識が必要になります。

たとえば、アプリケーションはコンテナで動いているのですが、Kubernetesではコンテナはpodという単位で管理されていて、podが載っているnodeはAWS管理なんですよ。ですので、nodeのスケーリングなのか、podのスケーリングなのか、判断する知識が必要になります。どこで何を管轄しているのかを把握できないと、扱うのは難しいかもしれません。

nekottyo: これまでは、新しいサービスはEKS側でつくって、デプロイは内製のGitOpsのスクリプトを用いるという形でした。運用手法としては、変更をしたいPRにコメントを打って、そのコメントにフックしてデプロイを促す仕組みを取っていました。

ただ、人事労務freeeは、関わるエンジニアも多く、プロダクトの規模も大きいのが特徴で、この仕組みがうまく機能しませんでした。同一リソースに対して複数PRからデプロイをすると、 PR単位で内容がコンフリクトする問題が起こったり、管理対象が多いので1デプロイあたりの時間が掛かるようになったのです。

そこで、Argo CDというOSSの活用を検証しています。別のプロダクトでは、Argo CDで運用がスムーズになったので。

hanake: Argo CDを入れると、めちゃくちゃ楽ですね!

最後に、EKSの導入を検討している方に向けて、教訓もしくはアドバイスをお願いします!

hanake: まずは、導入や移行の目的を明確にするのが大切だと思います。準備に手間も掛かりますし、導入作業も大変です。コンテナでスケーリングするアプリをつくりたいなら、ECSという選択肢もあります。なぜEKSなのか?どういったメリットを生み出したいのか?意識すると良いと思います。

nekottyo: hanakeさんに同感です。1クラスタで小さいプロダクトを運用したいケースならKubernetesを使う必要は無いと思います。スケールメリットを受けたい、ログ周りをキレイにしたいなどユースケースを想定して、ECSだと手間が掛かるのでしたら、Kubernetesへの移行を考えるのが良いのではないでしょうか。

イベントの本編はここまでです。この後は「アフタートーク」でより深い技術談議が繰り広げられました。

▶freee Tech Night 次回は5月28日に

「freee Tech Night Online #11 脆弱なサービスを守れ!hardening研修」を開催!

freee Tech Night 次回告知アイキャッチ画像
freee社内で実施したセキュリティ研修を公開!

freee-tech-night.connpass.com

▶今回のイベントのアーカイブ(録画)

youtu.be