Slide 1

Slide 1 text

運用環境を Amazon EKS に移行してみた話 enza部 AnD00

Slide 2

Slide 2 text

はじめに

Slide 3

Slide 3 text

自己紹介 名前: 安藤 尚之(あんどう なおゆき) 年齢: 30歳 学歴: 多摩美術大学 造形表現学部 映像演劇学科 卒業 エンジニア / enza歴: 4年くらい 概要:  2020年1月 ドリコムに中途入社。  enza部に所属して、コード書いたりスクラムマスターやったりしてます。  高校3年生くらいから10年近く演劇に人生を捧げてきたのに、突然エンジニア  になってみた系エンジニア。

Slide 4

Slide 4 text

最近、数年ぶりに舞台に立ちました。 I am AnD00. 撮影: 相模原市民文化財団

Slide 5

Slide 5 text

enzaとは 人気作品の新作タイトルが遊べるスマートフォン向けブラウザゲー ムプラットフォーム「enza」大好評配信中! 気の合う仲間同士が輪になってワイワイ楽しめる場所、それがenza (エンザ)です。 現在配信中タイトルの「アイドルマスター シャイニーカラーズ」など、 ぜひお楽しみください! 引用元: https://www.bandainamcoid.com/portal/serviceDetail?sv=110000&backto=%2Fportal%2FserviceDetail%3Fsv% 3D1203

Slide 6

Slide 6 text

話のきっかけ 運用しているenzaというプロダクトの運用環境をAmazon EC2からAmazon EKSに移行 する日が来まして、良い機会なのでまとめてみました。 Kubernetesが普及して久しいですが、「運用中のサービスを移行したいけど結構大変 だな」「他のサービスではどうやって運用しているんだろう」と感じる方も多いのではない かと思います。 そういった方の助けになれば、嬉しい限りです。

Slide 7

Slide 7 text

宜しくお願いしますm(_ _)m

Slide 8

Slide 8 text

Agenda ● なぜAmazon EKSに移行したのか ● どのようにAmazon EKSに移行したのか ● 移行した結果について ● 今後やっていくこと ● まとめ

Slide 9

Slide 9 text

なぜAmazon EKSに移行したのか

Slide 10

Slide 10 text

移行前のシステム

Slide 11

Slide 11 text

抱えていた課題点 ● スケールイン・アウト等のオペレーションコストがかかる ○ 手順や注意点が多く、属人化しやすい(触ってた人が辞めたらアウト) ○ 触れる人がなかなか増えない ○ 作業が面倒くさい ● 言語やライブラリのアップデートが大変 ○ マシンイメージ作り直してインスタンスを全部取り替えたり ○ プロビジョニングツール流さないといけなかったり ○ つまり面倒くさい

Slide 12

Slide 12 text

課題に対する解決策 1. Railsアプリをコンテナ化する a. Rubyのバージョンアップやライブラリの追加をするときは Dockerfileを更新するだけで済む 2. Kubernetes上で動かす a. インフラがPod / ReplicaSet / Deployment / Service等のリソースに抽象化される b. インフラ構成をマニフェストファイルで一元的に管理できる c. コード化されるため誰でも読めるし書ける( Infrastructure as Code)

Slide 13

Slide 13 text

先にまとめちゃう

Slide 14

Slide 14 text

先にまとめちゃう Amazon EKSへの移行について、もちろん解決したい課題があったことは事実ですが、なによりも「技術 的に挑戦したい」という意欲が根底にあったと感じています。 コンテナオーケストレーションサービスの選択肢としては、 Amazon ECSもありましたが「AWS内に閉じた 技術知識になってしまう」という点から Amazon EKSを選択しました。 Kubernetesであれば、Google Cloudなど他の場面でも活用できます。 Kubernetesは学習コストが高いという巷の話は確かに間違いなく、正直いまだによく分かっていない部 分が多いです。 しかし「Kubernetesに触れる」ということは既にスタンダードになっている世の中なので、運用環境移行に 挑んだことは良いアクションだったと思っています。

Slide 15

Slide 15 text

どのようにAmazon EKSに移行した のか

Slide 16

Slide 16 text

移行後のシステム

Slide 17

Slide 17 text

Railsアプリをコンテナ化する 1. Dockerfileを書く a. Alpine LinuxベースのRubyコンテナを使う b. Multi-stage buildsを使う 2. コンフィグを整理する a. Capistranoでのデプロイ前提のコードを廃止 b. KubernetesのConfigMap / SecretとRailsのCustom-configurationを使う

Slide 18

Slide 18 text

Kubernetes上で動かす 1. マニフェストを書く a. Namespace / Deployment / Service / ConfigMap / Secret / HorizontalPodAutoscaler / Job 2. ツールを使ってマニフェストを管理する a. Kustomizeを使う 3. AWSリソースを作成する a. EKS Cluster / Security Group / Application Load Balancer / Simple Storage Service / Elastic Container Registry / Kinesis Data Firehose 4. CI/CDからデプロイする a. イメージのビルド・プッシュ / マイグレーション / デプロイ

Slide 19

Slide 19 text

詳細はTech Inside Drecomの記事にて ● https://tech.drecom.co.jp/migrate-rails-app-to-container/

Slide 20

Slide 20 text

運用環境の切り替え

Slide 21

Slide 21 text

運用環境の切り替えにおける課題点 ● 機会損失を避けるにはどうすればいいか ○ 複数のタイトルを提供しているゲームプラットフォームであり、もしメンテナンスを実施する場合は全 タイトル止める必要がある ○ 安全第一ではあるが、方法があるなら避けたい ● 障害の影響は最小限に抑えるにはどうすればいいか ○ 事前に別環境で検証を行なっているとは言え、障害が起きないとは断言できない ○ メンテナンス時間内の検証だけで、問題を発見できるとは限らない ○ 障害は起きる前提で、被害を小さくする方法が欲しい

Slide 22

Slide 22 text

切り替え前のシステム

Slide 23

Slide 23 text

運用環境の切り替え方法 1. ALBに紐づくターゲットグループを切り替える a. メリット i. 準備もオペレーションも簡単 b. デメリット i. ターゲットグループが切り替わってからターゲットのインスタンスのヘルスチェックを行うため、ダウンタイムが発生してしまう 2. Route53の加重ルーティングポリシーでアクセスを振り分ける a. メリット i. 割合変更のための操作が、 Route53のルーティングポリシーを変更するだけで済む ii. ALB Ingress Controllerがサポートされているので、一般的な EKS Clusterで使いやすい b. デメリット i. アクセスを振り分けるため、 ALB関連のリソースをもう 1セット作成する必要がある ii. 設定反映に時間がかかるため、実際にアクセスが振り分けられるまでにラグが発生する 3. ALBの加重ターゲットグループでアクセスを振り分ける a. メリット i. ALBにターゲットグループを追加するだけなので、 ALB関連のリソースをもう 1セット作成する必要がない ii. DNSでの切り替えではないので、アクセス割合設定の変更が即時反映される b. デメリット i. ALBに設定する内容のため、 ALB Ingress Controllerは使用できない

Slide 24

Slide 24 text

採用した切り替え方法 ● ALBの加重ターゲットグループでアクセスを振り分ける ○ ダウンタイムが発生しないため、メンテナンスを実施する必要がなくなる ○ 任意の割合で振り分けられるので、万が一のときでも被害を抑えられる ○ 何か問題が発生したら、すぐにロールバックできる

Slide 25

Slide 25 text

切り替え時のシステム

Slide 26

Slide 26 text

切り替え後のシステム

Slide 27

Slide 27 text

● https://tech.drecom.co.jp/ec2toeks-without-downtime/ 詳細はTech Inside Drecomの記事にて

Slide 28

Slide 28 text

移行した結果について

Slide 29

Slide 29 text

移行した結果について ● メリット ○ スケールイン・アウト等のオペレーションが簡単になった ■ 手順の共有もシンプルに ○ 言語やライブラリのアップデートが簡単になった ■ 反映もコードをデプロイするだけ ○ Kubernetesの技術を扱うことは財産になる ● デメリット ○ Kubernetesの運用・学習コストが高い ■ 前提となる知識をつけるまでに時間がかかる ○ インフラ専門のメンバーがいないとキツイ ■ 改善に日々取り組まないと切り替えただけで終わる ■ 想定外のことが起きた時にチンプンカンプン ○ ログ収集が辛い ■ さまざまな罠がある

Slide 30

Slide 30 text

ログ収集が辛い

Slide 31

Slide 31 text

ログ収集のシステム

Slide 32

Slide 32 text

辛い思いをした点 ● Fluent Bitの動作が不安定 ● Kinesis Data Firehoseのクォータの制限に引っかかる ● JSONログが途中で強制的に分割される ● CloudWatch Logsの料金が大変なことになる

Slide 33

Slide 33 text

Fluent Bitの動作が不安定 [課題] ● DaemonSetで動かしていたが、周年イベントによるスパイクで捌き切れなくなった [対応] ● Mem_Buf_Limitを増やし、ログ送信時のバッファ上限を増やす ● バッファをメモリバッファからファイルバッファに変更して再起動時の欠損を回避する ● バージョンを更新して、マルチスレッドを有効化する ● Prometheusでメトリクスを監視し、異常を検知したらアラートを送る [反省点] ● 負荷試験でアプリケーションのほうは見ていたが、 Fluent Bitはノーマークだった [更なる辛み] ● ある程度の改善は見られたが、 Error code 135でPodの突然死が多発するように... ○ このあたりのIssueが解決されないと厳しい ■ https://github.com/fluent/fluent-bit/issues/2661 ■ https://github.com/fluent/fluent-bit/issues/3014

Slide 34

Slide 34 text

Firehoseのクォータの制限に引っかかる [課題] ● クォータの制限に引っかかってしまい、リトライを待っている間にバッファチャンクが Flushされてしまっていた [対応] ● AWSサポートケースを作成して依頼 ○ Service Quotasコンソールから変更できるのは、 Delivery streamsのみ ○ Rate of Put requestの上限をあげてもらうには、サポートケースじゃないとだめ [反省点] ● Firehoseのログやメトリクスをちゃんと追っておけばもっと早く気付けた

Slide 35

Slide 35 text

JSONログが途中で強制的に分割される [課題] ● アプリケーションが標準出力に出している分析用のJSONログが、ある一定のサイズを超え ると強制的に分割されてしまう ○ Docker 1.13からLogging Driverの仕様が変わり、16384バイトで分割される ■ https://github.com/moby/moby/issues/32923 ■ https://github.com/kubernetes/kubernetes/issues/52444 [対応] ● Fluent BitにはDocker_Modeという、まさにこのための設定が用意されていた ○ Docker_Modeを有効化したら何事もなかったかのように解決 [反省点] ● 公式ドキュメントを読み込むって大切

Slide 36

Slide 36 text

CloudWatchの料金が大変なことになる [課題] ● Cluster内のすべてのPodのログとKubeletのログをCloudWatch Logsに送信して しまって、料金が大変なことになった ○ 収集する対象のログの設定を見直し損ねていた [対応] ● 収集すべきログを絞って設定することで、翌月から料金が正常な値に戻った [反省点] ● コストの監視が疎かだったことを後悔し、定期的なチェックを行うように ○ 組織的な諸事情でAWS Cost Explorerなどが使えず...

Slide 37

Slide 37 text

その他の主な調整点

Slide 38

Slide 38 text

その他の主な調整点 ● ワーカーノードの安全な停止 ● AWSリソースの内部アクセス

Slide 39

Slide 39 text

ワーカーノードの安全な停止 ● ノードを停止する場合は、Drain機能を使う必要がある ○ 手順としては以下の通り ■ DrainでPodを退避させる ■ オートスケーリンググループの最小台数を更新する ■ ノードをデタッチして停止する ○ Pod側はPreStopフックを使用して、Gracefulに終了するように調整 ● 運用環境のノード数だと、コマンドで地道にやるのは辛いのでスクリプト化して運用 している

Slide 40

Slide 40 text

AWSリソースの内部アクセス ● 移行前の負荷試験でインスタンスメタデータサービスの通信が明らかに遅いことを 発見 ○ EC2 インスタンスメタデータサービス v2(IMDSv2)なるものがAmazon EKSでサポートされるように なっていた ■ https://aws.amazon.com/jp/about-aws/whats-new/2020/08/amazon-eks-supports-e c2-instance-metadata-service-v2/ ○ AWS SDKのバージョンアップを行なったことにより IMDSv2が使われるようになっていたが、ノード側 の設定ができておらず ○ v2に失敗したらv1にフォールバックするようになっており、時間はかかるけど成功するような状態 だった ● InstanceMetadataOptionsのHttpPutResponseHopLimitを2に設定する ○ SSRF脆弱性等の攻撃に対するセキュリティが強化されているので、アップデートするのが吉

Slide 41

Slide 41 text

今後やっていくこと

Slide 42

Slide 42 text

今後やっていくこと ● Fluent BitからFluentdへの移行 ○ 負荷試験を行い性能を比較した結果、 Fluentdでも十分捌ける上、動作が安定している ● DNSの名前解決の問題について調査・対応 ○ まだ問題は顕在化していないが準備しておくに越したことはない ○ GREEさんの記事がとても参考になる ■ https://labs.gree.jp/blog/2020/01/20271/ ● Progressive Deliveryの導入 ○ Spinnaker + Kayentaでカナリーリリースの仕組みを構築中 ● GitOpsの導入 ○ ベストプラクティスと言われては気にせざるを得ない ● オートスケールを活用する方法の模索 ○ 現状はイベントに合わせて、事前にノードの台数を調整 ○ もっと良い運用方法がありそう

Slide 43

Slide 43 text

まとめ(再掲)

Slide 44

Slide 44 text

まとめ(再掲) Amazon EKSへの移行について、もちろん解決したい課題があったことは事実ですが、なによりも「技術 的に挑戦したい」という意欲が根底にあったと感じています。 コンテナオーケストレーションサービスの選択肢としては、 Amazon ECSもありましたが「AWS内に閉じた 技術知識になってしまう」という点から Amazon EKSを選択しました。 Kubernetesであれば、Google Cloudなど他の場面でも活用できます。 Kubernetesは学習コストが高いという巷の話は確かに間違いなく、正直いまだによく分かっていない部 分が多いです。 しかし「Kubernetesに触れる」ということは既にスタンダードになっている世の中なので、運用環境移行に 挑んだことは良いアクションだったと思っています。

Slide 45

Slide 45 text

ご静聴 ありがとうございました!