Hatena Engineer Seminar #19 カクヨム編 の資料です。 https://hatena.connpass.com/event/241412/
カクヨムはAWSのはてなのサービスで共有のアカウントで、EC2を活用して運用されてきました。これを段階的にカクヨム固有のアカウントに切り出し、マネージドサービスやコンテナ技術を活用するように変更して運用性を高めました。その動機や具体的な手順をお話します。
Hatena Engineer Seminar #19id:AWSアカウントとIaaSの段階的移行カクヨムの10年を見据えた技術 インフラ編2022.03.30koudenpa
View Slide
● koudenpa○ コウデン○ 太田浩一● https://twitter.com/koudenpa● https://koudenpa.hatenablog.com/● Webアプリケーションエンジニア● SI企業、Webサービス企業などを経て2018年秋にはてなへ入社以後カクヨムを担当id: koudenpa
目次● 背景・概要● 段階的移行を追う● 移行ネタ集● まとめ
背景・概要
移行前構成● 『はてな』アカウント● IaaS(EC2)
移行後構成● 『カクヨム』アカウント● マネージドサービス● コンテナ(ECS Fargate)● 『はてな』少し残ってる
なにをしたかったか● 継続的な開発運用● その準備として● 継続的に運用できるインフラへの刷新
やったこと・関心ごと● AWSアカウント切り離し● IaaSからの脱却○ マネージド化○ コンテナ化
カクヨムの特性● 典型的なWebアプリケーション● アクセス数は増加傾向○ 超高トラフィックではない○ (Twitterなどではない)● 一般的に良いとされる手法に倣えばよい
モデルケース● 魔法のiらんど○ Hatena Engineer Seminar #14 〜魔法のiらんど編〜○ https://developer.hatenastaff.com/entry/2020/09/04/093000● チームの担当サービス○ カクヨム○ 魔法のiらんど● コードベース○ カクヨムと魔法のiらんどは同じ■ バックエンドの処理のみ○ 概ね同様の構成で動作するはず
移行後構成の理由● モデルケースはあれども● それぞれ理由はある○ 魔法のiらんどでそうした理由でもある
AWSアカウント切り離し● 前○ はてな全体の共有アカウント・ネットワーク● 後○ カクヨム専用のアカウント・ネットワーク● 理由○ アカウント管理のベストプラクティスに乗る■ https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_best-practices.html○ 様々な要素の独立■ AWSのレート制限■ 誤操作のリスク
マネージド化● 前○ IaaS(EC2)をChef管理● 後○ AWSの管理● 理由○ 管理負荷の低減○ サービスを運用しやすく
コンテナ化● 前○ IaaS(EC2)をChef管理● 後○ コンテナ環境(ECS Fargate)● 理由○ 一般的なコンテナ運用の利点を得る○ 開発から本番まで同様の環境○ 構成を変更しやすく
現行機能を維持● 何はなくとも大目的を達成することを優先○ AWSアカウント切り離し○ マネージド化○ コンテナ化● 最適化を欲張らない○ 簡単なものはやる■ 今後最適化する準備まで、など
段階的移行● カクヨムは成長中○ 未来を見据えた機能追加や状況に応じた改善を止めない● インフラ要素を1つずつ移行○ ビッグバンで一気にではない○ サービス影響のリスク・準備のコスト低減○ 機能開発と並行
段階● 永続化層○ MySQL○ Redis○ Elasticsearch● アプリケーション○ Webアプリケーション○ Jobワーカー○ Batchサーバー● ミドルウェア○ Nginx, Varnish
移行時の対応● メンテナンス有り○ 10分~以上のサービスダウンやロールバック考慮○ 悲観的に見た作業時間をアナウンス○ リバースプロキシやCDNでメンテナンスページを応答● メンテナンス無し○ ~数分程度のサービスダウン○ ユーザーには一定時間内にサービスにつながらない時間がある旨をアナウンス○ ユーザー影響はダウンしてる時間のみになる● 移行以外でも同様○ マネージドサービスのバージョンアップグレードなど
段階的移行を追う
移行前
01 ネットワーク間接続
01 ネットワーク間接続● 移行前○ AWSやオンプレミスで構成されたネットワーク■ カクヨムはAWSのみ● 移行後○ カクヨム専用のアカウント・VPC● AWS Transit Gateway(TGW)で相互接続○ 段階的移行の準備○ 1部のリソースだけ移動を可能に
02 MySQL移行
02 MySQL移行● RDS MySQL● 移行前からレプリケーション● 移行実施時は接続先の切り替え○ メンテナンス有(安全寄せ)
03 Redis移行
03 Redis移行● ElastiCache Redis● 移行前からレプリケーション● 移行実施時は接続先の切り替え○ メンテナンス有(安全寄せ)
04 Elasticsearch移行
04 Elasticsearch移行● OpenSearch Service○ Amazon Elasticsearch Service の後継● 移行前後にダブルライト● 移行実施時は参照を切り替え○ メンテナンスなし
05 Webアプリ移行
05 Webアプリ移行● ECS Fargate● ローカルマシンをコンテナで動かす● 本番同様の開発環境を構成して動作確認● 本番構築● 移行はNginxのルーティングを切り替え○ メンテナンスなし
06 Nginx移行
06 Nginx移行● CloudFront、ECS Fagate● 開発環境を構成して検証・動作確認● 併せて本番環境も構成● 移行はDNSを切り替え○ メンテナンスなし○ 切り替えミスで一部ユーザーに影響🙇
07 SSRサーバ追加
07 SSRサーバ追加● ECS Fargete● React導入の一環としてNext.jsのSSRサーバを追加● 開発環境を構成して検証・動作確認● 併せて本番環境も構成● 適切な時期にリリース○ メンテナンスなし
08 Worker/Batch移行
08 Worker/Batch移行● ECS Fargate● EC2上でのDocker run● 開発環境を構成して検証・動作確認● 併せて本番環境も構成● Jobワーカーは並行稼働の後に旧環境停止● Batchは旧環境停止後に新環境稼働● ユーザーには見えない出来事○ メンテナンスなし
09 ネットワーク間接続解除
09 ネットワーク間接続削除● 削除!
前
後
移行ネタ集
おしながき● やらなかったこと・残課題○ 『はてな』に残っているリソース○ CDN活用・キャッシュ最適化○ Batchの実行環境● SSRサーバへのルーティング● TGWトラフィック● CI/CD変遷● 他
『はてな』に残っているリソース● 『はてな』少し残ってる● グローバルに一意な名前● 移行パスはある○ がちょっと面倒● ほとんど変更しない● ので差し当たって残
CDN活用・キャッシュ最適化● CDNの活用は準備まで○ CloudFrontとACMでの証明書管理○ 今後『層』の追加なしにカイゼンできるように● Nginx, Varnish○ 責務整理・最適化まで手が回らなかった
Batchの実行環境● モデルケース同様の構成● EC2上のCronで docker run○ 既存のスケジュールを使う○ コンテナは使う● アカウント切り離しとコンテナ化に注力した結果● 今後クラウドネイティブ化していきたい部分
SSRサーバへのルーティング
SSRサーバへのルーティング● SSRは『追加』● 本番確認、内部の人間だけでしたい● あるURLをReactでレンダリングするか判断したい● そこで「X-Accel」○ https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/
X-Accel● Nginxの機能● Upstreamからの応答ヘッダを見て内部リダイレクト● バックエンドのアプリケーションで判断○ 一般ユーザーにはHTMLをレンダリングして応答○ 管理者ユーザーには X-Accel でSSR結果を応答● こっそりSSRを確認できた
X-Accel なしHTML応答1321. NginxからWebアプリへ2. WebアプリはHTML応答3. 素直に応答
X-Accel してSSR結果応答143251. NginxからWebアプリへ2. WebアプリはX-Accel応答3. X-AccelならSSRサーバへ4. SSR!5. 最終的な応答
TGWトラフィック● ネットワークを超えるトラフィックがどの程度か?● リソースを移行するごとに減● なくなった段階でTGWを削除、お役御免
TGWトラフィック
TGWトラフィックWebアプリケーションの移行Nginxの移行Worker/Batchの移行PV増の様子???永続化層(MySQL)の移行永続化層(MySQL)レプリケーション中
CI/CD変遷● インフラの移行と並行して見直し
おわかりいただけただろうか?
CI/CD変遷● 前○ JenkinsでのCI○ 手作業でのCD● 後○ GitHub ActionsでのCI○ AWS CodePipelineでのCD● いずれも『主に』
Jenkins● 主にCIに活用● チームで管理しきれていなかった● マネージド化の一環● 地道にジョブを置き換え○ GitHub Actionsのワークフローへ
手作業でのCD● Capistranoをローカルマシンで実行● デリバリー対象の変化○ ソースコード -> コンテナイメージ● デリバリー先の変化○ EC2 -> ECS Fargate● AWSへはAWSで○ CodePipelines(+CodeBuild, CodeDeploy)
他● 気になる点があれば○ 質疑応答■ この後○ 懇親会■ セミナー後○ はてなへ入社■ https://hatenacorp.jp/recruit/engineer
まとめ
ポイント● AWSアカウント切り離し○ ネットワーク間接続はAWSのTGW経由● ビックバンでなく1要素ずつ○ マネージド化○ コンテナ化● 機能開発と並行○ 機能リリース○ React化向けのSSRサーバ追加● それぞれ達成
得たもの● マネージド化○ 運用しやすく● コンテナ化○ 変更しやすく
10年を見据えて● 運用しやすく● 変更しやすく● 今後に対応しやすくなったカクヨムにご期待ください
つづく