【レポート】コンテナ移行ってこんなに大変? ~「家族アルバム みてね」を支えるインフラの裏側~ #AWSSummit

こんにちは、岩城です。

2019年6月12日(水)〜2019年6月14日(金)の 3 日間にわたり、 千葉県の幕張メッセにて AWS Summit Tokyo 2019 が開催されています。

こちらで講演されたセッション「コンテナ移行ってこんなに大変? ~「家族アルバム みてね」を支えるインフラの裏側~」を聴講しましたのでレポートします。

概要

ミクシィが提供する家族向け写真・動画共有アプリ「家族アルバム みてね」は、2019年初めに利用者数400万人を突破し、世界中の家族に快適にご利用いただけるよう、アプリケーションやインフラの改善を続けています。サービスのリリース当初からAWS OpsWorksを活用してきましたが、よりスケールしやすく、イミュータブルなコンテナ環境へ移行するためにAmazon EKSを採用し、移行作業を進めてきました。SREチームが中心となって移行を進める際に工夫した点や、様々な苦労、得た知見を共有いたします。

スピーカー

  • 株式会社ミクシィ みてね事業部 開発グループ SRE
    • 清水 勲

※敬称略

レポート

本日お持ち帰りいただきたいこと

  • コンテナ移行によってシステムを一新する際に気をつけたいこと
  • コンテナ移行によって解決されること
  • コンテナ移行の難しいところ、工夫するポイント
  • EKSを選ぶメリット

家族アルバムみてね

  • こどもの写真動画を無料無制限に共有できるアプリ
  • 世界中の家族の”こころのインフラ”をつくる
  • 2015年サービスリリース
  • 国内外の利用者500万人以上が利用
  • Apple Storeレビュー 4.7
  • Google Playストアレビュー 4.7

海外での受賞歴

  • 2019 The Webby Awards受賞
    • インターネットのオスカー賞
  • 2019 National Parenting Product Awards

みてねプレミアム

  • 2019年4月リリース
  • 月額書き間型の有料プラン
  • ブラウザからアップロード
  • 1秒動画の毎月配信
  • 動画アップロードの時間制限を延長(3分→10分)

みてねのアーキテクチャと課題

  • アーキテクチャ
    • ユーザがアプリからAPIを叩く、CloudFront、Ruby on Rails、Aurora、ElastiCache
    • ログはFluentdを使ってKinesis Data Firehoseを経由してS3に保存する
    • デバイスから直接S3にアップロードしている
  • クライアント
    • iOS
    • Android
    • ブラウザ
  • サーバ
    • Ruby on Rails
    • sidekiq
    • whenever(cron)
  • インフラはすべてAWS

利用しているサービス

  • 構成管理にOpsWorksを利用
    • 構築時は目立っていた。とても便利
  • モニタリング
    • New Relicをフル活用
    • CloudWatchを表示するのにGrafana

いままでの環境における課題

  • プロビジョニング、デプロイに時間が掛かりがち
  • Chefのバージョンアップが難しい
  • EC2リソースを使い切るための調整が難しい
  • EC2スポットインスタンスの活用ができていない、コスト削減したい
  • SSHを前提としたオペレーションになりがち

コンテナ環境移行することで解決できる?

  • 簡単に作り直せるか
  • オペレーションコストの削減

コンテナ移行によって解決すること(技術面)

  • OSに依存せずイメージ化によってポータビリティ性を保つ
  • ディスポーザブルなインフラ
    • 高速なデプロイ
    • SSHする機会を減らす
  • 従来のVMよりも効率的なハードウェアリソースの活用
  • さまざまなサービスがコンテナを前提としてきている
    • 元々コンテナイメージを用意していたらすんなり使える環境ができてきている
  • 新技術の習得、トレンドへの追従、エンジニア採用
    • 新技術に興味のあるエンジニアの応募に繋がる

コンテナ移行によって解決すること(ビジネス面)

  • ユーザにより快適に使っていただく
    • オートスケールのスピードが向上する
    • 耐障害性を作り直すのが簡単
  • コスト削減
    • コンピュートリソースの効率化
    • スポットインスタンスの購入
      • スポットインスタンスはコンテナに向いている
  • 新機能開発、不具合修正速度の向上
    • より事業にフォーカスできる
    • デプロイが早い
    • 環境構築しやすい

OpsWorksからコンテナ環境へ

  • OpsWorksはECSと連携できるらしい
  • Chefからの脱却
  • デプロイ速度
  • コスト削減
  • 新しい技術の導入

ECS vs EKS

  • どちらも優れたコンテナサービス
  • ECS
    • Fargateが使える
    • 学習コストが低くシンプル
    • タスク単位のIAMロール
    • AWS独自サービス
  • EKS
    • Fargateはまだ使えない
    • 機能が豊富な反面学習コストが高い
    • 世の中に溢れるK8sのノウハウやツールをそのまま導入できる
    • K8sへの準拠性が認証されている

K8sという選択肢

  • 最も注目されるコンテナ技術の1つ
  • GoogleがOSSとして2014年に公開

EKSの利点

  • マネージドなコントロールプレーン
    • 自前でK8sを構築して運用するのは大変なことが多い
    • 運用に時間を使うよりはアプリを動かすことに注力したい、AWSならそれが可能
  • K8sのエコシステム
    • ノウハウやツールが豊富にある
    • 必要なら独自にツールを開発できる
  • IAMとの連携
  • CloudWatch Container Insights
  • EC2スポットインスタンスとの組み合わせ
  • SIGAWS
  • 以上を踏まえて選択

コンテナ環境全体のデザイン

  • AWSアカウント
    • いままでは1アカウントで運用してきた
      • 本番、ステージング、開発と分けた
    • AWSにおけるマルチアカウント管理の手法とベストプラクティスに沿った
    • マルチアカウントは必須ではないが、複雑なIAMポリシーからの脱却、Terraform利用による構築の効率性向上を求めた
    • 課金の管理をしやすい
    • 問題発生時アカウントを閉じられる
  • EKSクラスター
    • 機能分類(サービスごとに分ける)

コンテナ移行の道筋

  • Chef Cookbookの資産をDockerfileへ
  • Dockerfileを書く
  • CodeBuildでイメージをビルド
  • ECRへプッシュ
  • GitHub→CodeBuild→ECR
    • GitHubにはDockerfileとbuildspec.yml

Ruby on Railsプロジェクトのコンテナ化

  • Rubyのイメージ作成
    • Rubyイメージをベースに必要パッケージやRubyGemsをインストールした
  • ソースコードを入れたイメージの作成
  • ビルドに時間がかかる部分を分離
  • buildkitを利用したビルドの高速化
  • デプロイをより早くするためにコンテナイメージを小さくしていく工夫が必要(依存ライブラリが多いと大変)

ローカル開発環境でイメージの動作検証

  • ローカルでの開発環境の構築
    • すべての開発者に使ってもらう
      • 属人を防ぐため、構成や手順などの理解をチーム内で深める
  • コンテナイメージの動作確認
    • Docker Composeを使って複数イメージとの連携
    • 環境変数の検証
    • ユニットテスト(RSpec)の実行と結果の確認
    • MacOSでのDocker利用はI/O処理が遅い問題があるので注意
    • 最近は良くなってきた

AWSアカウントをマルチアカウントに

  • AWS Organizationsを使う
  • AWSアカウントを新規作成(これをマスターアカウント)
  • マスターアカウントでAWS Organizationsを使い、子アカウントを管理
    • 従来のアカウントをAWS Organizationsに招待
    • 新しく構築するステージング、開発はアカウントをAWS Organizationsから作成
  • サポートプランの適用、RIの共有
    • AWS Organizations配下の全アカウントに適用可能
  • 必要に応じて上限緩和申請
    • AWS Organizationsで管理できるアカウント数の初期値が低い
  • マスターカウントから子アカウントにスイッチロールして使う

Terraformによる適用環境の構築

  • Infrastructure as Codeの実現
  • Terraformを使う
  • GitHub + CodeBuildの連携
    • コード書いてプルリクあげてマージされればリソースが作られる
  • 各AWSアカウントで必要なリソースの作成もTerraformで

EKSクラスターの作成

  • AWS CLIで作成
  • eksctlでも作ることができる
    • CFnとの連携が重視されていてTerraformとの相性が悪そうだった
  • EKSクラスターを作る上でのハマりポイント※要注意
    • 作成するときに使われたIAMエンティティが管理者としてK8s RBAC認証テーブルに追加される
    • そのIAMエンティティだけがkubectlを使用してK8s APIサーバにアクセスできる

EKSワーカーノードの作成

  • Auto Scaling Groupを使う
  • これもTerraform
  • Podのスケジューリングの制約の設定が可能

マニフェストの適用

  • kubectlコマンドの実行環境をどうするか
  • 最初はCloud9を試した
    • ブラウザのショートカットと競合して使いづらい
    • 当時は東京リージョンで使えなかったため、レイテンシの問題があった
  • SSMの利用に変更

いまできていること

  • 複数アカウントによる環境の分離
  • Terraformによる構築コード化、自動化
  • SSMを使ったkubectl実行環境
  • EKSを使った開発環境の構築

現在進行中

  • 本番環境の構築
    • 開発のTerraformを流用できてすぐに構築できる
  • 本番環境の移行
  • デプロイ手順や運用手順の整備
  • チーム内のノウハウ共有、ドキュメント化
  • 障害時のオペレーション
  • EKSクラスタのアップデート手順
    • K8sを利用する上で避けられない
  • できる限り属人化しないようにノウハウの共有、手順化が大事

まとめ

  • なぜコンテナが必要か正しい理解が必要
  • コンテナに関する技術領域は広く、習得は簡単ではない
  • コンテナ移行によって得られたもの
    • ポータビリティの高いディスポーザブルなインフラ
    • 新たな技術ノウハウ
    • 1から構築する手順の再確認ができた、インフラに関する情報の整理ができる
  • コンテナ移行によってこれから期待できること
    • 高速にスケーラブルなインフラ
    • コスト削減
    • 開発速度の向上(事業の成長のスピードアップつながる)
  • Dockerfileの書き方の工夫
    • 世の中にDocckerfileを参考にするのがおすすめ
    • ビルドの時間短縮につながる
  • 複数アカウントの適用
    • AWS Organizationsは便利
    • 管理対象が増えるのでInfrastructure as Codeが前提
  • EKSの進化に追従すること
  • クラスタはアップデードし続ける必要がある
    • 最新から2つ古いバージョンでのクラスター作成できなくなる
    • 検証環境を用意してアップデートの検証を十分に行う