こんにちは、SREチームの肥沼です。さて、ハウテレビジョンでは2021年8月に運用基盤を刷新して新しい構成で本番稼働を始めています。特にKubernetesの導入やTerraformの本格利用、Datadogによる可観測性の向上などさまざまな取り組みを行ってきたので今回のブログではそれらの取り組みを一気に紹介させていただきます。
まずはじめに
本題に入る前に、弊社SREチームを簡単に紹介させていただきます。 SREチームは私の入社以前からありましたが、私が入社後、メンバーが一新されて新生SREとして再編成を行いました。私を含めてメンバーは3人で、以下のミッションを掲げて活動しております。
- 継続的な改善の土壌づくり
- 新しいサービスやツールを使った効率化、その民主化など
- 事業継続性の維持とユーザーへの価値提供の最大化
- コストコントロールや信頼性の維持、向上など
また、弊社は主な事業として、大学生向けキャリアプラットフォームの「外資就活ドットコム」と若手プロフェッショナルを対象としたキャリアプラットフォームの「Liiga」を運営しております。SREチームの活動は、「外資就活ドットコム」「Liiga」の双方にまたがっておりますが、今回の取り組みでは運営の歴史が長く、複雑になってしまった「外資就活ドットコム」を対象としました。
今回取り組んだ課題
OSやミドルウェア・設定の変更が難しい、手間がかかる
これまではVMを使った運用をしており、EC2インスタンスに対して以前からChefを利用して構成管理を行っていました。ところが、いつからかChefでの定義と実態に差分が生じるようになっていました。理由としては、IaCの文化が開発部に根付かず、EC2に直接SSHして設定を変更することが当たり前となっていたためです。そのため、ミドルウェアの変更をするにも心理的負担が非常に大きいことが問題でした。
複数サービスを使った監視やモニタリング
Mackerel、CloudWatch、PagerDutyなど複数のサービスを利用している状態で、何がどういう意図で設定・通知されているのか整理する必要がありました。
可視化が足りず調査に時間がかかる
MackerelやCloudWatchで管理が行き届いていないダッシュボードがあったり、形骸化してしまったものが多数存在し、肝心の障害対応の際に生かせていませんでした。
リソースコントロール、スケーリングの柔軟性を得たい
VMの運用を行なっておりましたが、リソースの余剰が目立っていました。アクセスが集中する際のスケーリングもEC2のAMIや設定を準備したりと手順が多く簡単にできませんでした。
深刻な属人化やドキュメンテーションが不足
属人的な知識や操作が多く存在し、新規メンバーの活躍の場が少なくなってしまったり、新しいことに挑戦しにくい状態でした。
Kubernetesの導入
導入理由
やはり巷ではKubernetesを導入すべき・でない、などいろいろ言われており、チームでも議論が交わされてきました。例えばECSのほうがいいんじゃないか?などはよくある議論だと思います。弊社では、いくつかの理由で最終的にはKubernetesを導入することに決定しています。
理由としては大きく以下があります。
- コンテナの振る舞いをマニフェストで記述したうえGitで管理できる
- マニフェストで定義した振る舞いをシンプルに展開できる、リソースコントロールを柔軟にできる、スケーリングが容易にできる
- 強力なエコシステムの恩恵を受けることができる
- 特定のベンダーに依存せず、オープンなものに依存することで拡張性を得ることができる
まず、マニフェストがないとコンテナのデプロイはできないためIaCの実践を強制されます。これまでIaCが根付かなかった反省をこれで解消することができると考えました。
また、外資就活ドットコムは、デプロイライフサイクルの異なる複数のコンポーネントから成り立っています。そのため、マニフェストを柔軟に記述し、管理できることや、リソースやスケーリングの設定をアプリケーションの定義に近いところで定義できることは大きなメリットでした。
何より、クラウドプロバイダにべったりするというよりかは、ベンダーによらないオープンな技術を使っていくことで進化の速さを享受できたり、そもそもエンジニアのモチベーションにもつながってきます。モチベーション大事です。
環境ごとのクラスター構成
本番環境稼働・検証環境・開発環境でKubernetesクラスターを分けています。 これにより検証環境では、本番環境と同等な状態でのアプリケーションの動作確認と負荷試験の結果を受けたキャパシティプランニングができるようになっています。また、開発環境はnamespaceで論理的に区切ることで、アプリケーションの機能開発に対する環境構築を柔軟に行えるようにしています。
namespaceで本番環境・検証環境・開発環境を分離する方法も検討しましたが、クラスタ自体が分離されているほうがテストをしやすく、本番環境だけの特別な操作という心理的な負担を減らすことができます。
マニフェストの管理はシンプルに
kustomizeを利用することで環境差分を吸収して、1つのリポジトリで全マニフェストを管理する方法をとっています。 Helmはより柔軟にパラメータの指定ができますが、学習コストが高くマニフェスト管理への障壁になる点を考慮し導入を見送りました。
CI/CD
CIでは、もともと利用していたCircleCIを利用して、コンテナイメージのビルドまでを担っています。
CDにはArgoCDを利用しています。まずは、シンプルに始めたかったので多機能よりもシンプルさを重視しました。 またArgoCDによってマニフェストの変更によってクラスタへの展開が行われるため、デプロイはマニフェストに対してコンテナイメージのタグのコミットだけすればよい、という単純な仕組みとなるようにしています。
全体の流れとした以下の図のようになっています。
Terraformの本格利用
実はTerraform自体は一部で利用していました。 しかし、Terraformでの定義と実際のAWSリソースに乖離があったり、ディレクトリ構成も今後保守していくのは骨が折れる状態でした。 これらの理由からTerraformについても、このタイミングでモジュールの設計方針など決めながら新しく構築していくことにしました。
どんなことをやったのか
改めて以下のような方針で取り組みました。
- Terraformを利用してインフラを1から構築すること
- インフラは基本的にコードで管理すること
- コード化することで変更に対してのレビューができる、必要とさせる
都度ドキュメントを書いて説明するのではなく、インフラの変更はコードの変更を介してレビューされ、歴史が刻まれていく状態になることを重視しました。こうすることで、これまで問題となっていた属人化やドキュメンテーションの課題に対処できます。
また、Terraformを使うにしても、AWSのタグの付け方やリソースの命名規則、モジュールの設計など多くの議論がありました。 モジュールの設計としては、AWSのリソース変更のただのラッパーではなくそのリソースを作るときのSREチームにとってスタンダードな構成を基本として設計しました。
例えば、RDSなどを追加したいときにはそのサブネットやタグのセット、セキュリティグループなど一通りそろえられるような設計としました。こうすることで、あるリソースを構築するときに何が必要なのかがセットになるため、一度モジュールのレビューをしてしまえばあとは構築時にはパラメータに対するレビューだけで済むなどのメリットを受けられます。
Datadogの導入
複数のサービスや自前の監視サーバーを全面的に廃止して、Datadogを導入して監視・モニタリングを統一しました。 使うものを減らし統一することで、目的に早くたどりつけるような状態にしていきたいと考えていました。
どんなことをやったのか
まずは、Kubernetes基盤への切り替えリハーサル用の環境で導入してトライアルを実施しました。ダッシュボードからLogs、メトリクス、あるいはアラートから横断的に一気通貫で、1つのサービスでできることは大変効率がよく、導入決定にいたりました。
また、SREチームだけが監視やモニタリングに向き合うのではなく、以下のようなことを考えていました。
- SREチーム主導でDatadogの開発組織への平準化を率先
- 問題があったときに、他チームとDatadogを見ながらコミュニケーションを取れるようにしていくこと
こうすることで、機能開発に加えて、改善もしやすい土壌を整える狙いがありました。
さいごに
インフラの再構築からKubernetesやDatadogの導入にいたるまで、多くの議論や意志決定があり、途中、苦しいこともありましたが、なんとか刷新することができました。今回は一部の紹介となりましたが、個々にクローズアップした内容など、今後もアウトプットしこうと思います。
ところで、今回紹介した課題はほんの一部にしかすぎません。一緒に取り組んでくれるエンジニアの方、募集しております!