Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The story of migrating production env to Amazon EKS

AnD00
June 27, 2021

The story of migrating production env to Amazon EKS

2021-06-27
Drecom SRE Sunday
https://drecom.connpass.com/event/213139/

AnD00

June 27, 2021
Tweet

More Decks by AnD00

Other Decks in Technology

Transcript

  1. 自己紹介 名前: 安藤 尚之(あんどう なおゆき) 年齢: 30歳 学歴: 多摩美術大学 造形表現学部

    映像演劇学科 卒業 エンジニア / enza歴: 4年くらい 概要:  2020年1月 ドリコムに中途入社。  enza部に所属して、コード書いたりスクラムマスターやったりしてます。  高校3年生くらいから10年近く演劇に人生を捧げてきたのに、突然エンジニア  になってみた系エンジニア。
  2. 抱えていた課題点 • スケールイン・アウト等のオペレーションコストがかかる ◦ 手順や注意点が多く、属人化しやすい(触ってた人が辞めたらアウト) ◦ 触れる人がなかなか増えない ◦ 作業が面倒くさい •

    言語やライブラリのアップデートが大変 ◦ マシンイメージ作り直してインスタンスを全部取り替えたり ◦ プロビジョニングツール流さないといけなかったり ◦ つまり面倒くさい
  3. 課題に対する解決策 1. Railsアプリをコンテナ化する a. Rubyのバージョンアップやライブラリの追加をするときは Dockerfileを更新するだけで済む 2. Kubernetes上で動かす a. インフラがPod

    / ReplicaSet / Deployment / Service等のリソースに抽象化される b. インフラ構成をマニフェストファイルで一元的に管理できる c. コード化されるため誰でも読めるし書ける( Infrastructure as Code)
  4. 先にまとめちゃう Amazon EKSへの移行について、もちろん解決したい課題があったことは事実ですが、なによりも「技術 的に挑戦したい」という意欲が根底にあったと感じています。 コンテナオーケストレーションサービスの選択肢としては、 Amazon ECSもありましたが「AWS内に閉じた 技術知識になってしまう」という点から Amazon EKSを選択しました。

    Kubernetesであれば、Google Cloudなど他の場面でも活用できます。 Kubernetesは学習コストが高いという巷の話は確かに間違いなく、正直いまだによく分かっていない部 分が多いです。 しかし「Kubernetesに触れる」ということは既にスタンダードになっている世の中なので、運用環境移行に 挑んだことは良いアクションだったと思っています。
  5. Railsアプリをコンテナ化する 1. Dockerfileを書く a. Alpine LinuxベースのRubyコンテナを使う b. Multi-stage buildsを使う 2.

    コンフィグを整理する a. Capistranoでのデプロイ前提のコードを廃止 b. KubernetesのConfigMap / SecretとRailsのCustom-configurationを使う
  6. 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. イメージのビルド・プッシュ / マイグレーション / デプロイ
  7. 運用環境の切り替えにおける課題点 • 機会損失を避けるにはどうすればいいか ◦ 複数のタイトルを提供しているゲームプラットフォームであり、もしメンテナンスを実施する場合は全 タイトル止める必要がある ◦ 安全第一ではあるが、方法があるなら避けたい • 障害の影響は最小限に抑えるにはどうすればいいか

    ◦ 事前に別環境で検証を行なっているとは言え、障害が起きないとは断言できない ◦ メンテナンス時間内の検証だけで、問題を発見できるとは限らない ◦ 障害は起きる前提で、被害を小さくする方法が欲しい
  8. 運用環境の切り替え方法 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は使用できない
  9. 移行した結果について • メリット ◦ スケールイン・アウト等のオペレーションが簡単になった ▪ 手順の共有もシンプルに ◦ 言語やライブラリのアップデートが簡単になった ▪

    反映もコードをデプロイするだけ ◦ Kubernetesの技術を扱うことは財産になる • デメリット ◦ Kubernetesの運用・学習コストが高い ▪ 前提となる知識をつけるまでに時間がかかる ◦ インフラ専門のメンバーがいないとキツイ ▪ 改善に日々取り組まないと切り替えただけで終わる ▪ 想定外のことが起きた時にチンプンカンプン ◦ ログ収集が辛い ▪ さまざまな罠がある
  10. 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
  11. Firehoseのクォータの制限に引っかかる [課題] • クォータの制限に引っかかってしまい、リトライを待っている間にバッファチャンクが Flushされてしまっていた [対応] • AWSサポートケースを作成して依頼 ◦ Service

    Quotasコンソールから変更できるのは、 Delivery streamsのみ ◦ Rate of Put requestの上限をあげてもらうには、サポートケースじゃないとだめ [反省点] • Firehoseのログやメトリクスをちゃんと追っておけばもっと早く気付けた
  12. 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を有効化したら何事もなかったかのように解決 [反省点] • 公式ドキュメントを読み込むって大切
  13. CloudWatchの料金が大変なことになる [課題] • Cluster内のすべてのPodのログとKubeletのログをCloudWatch Logsに送信して しまって、料金が大変なことになった ◦ 収集する対象のログの設定を見直し損ねていた [対応] •

    収集すべきログを絞って設定することで、翌月から料金が正常な値に戻った [反省点] • コストの監視が疎かだったことを後悔し、定期的なチェックを行うように ◦ 組織的な諸事情でAWS Cost Explorerなどが使えず...
  14. ワーカーノードの安全な停止 • ノードを停止する場合は、Drain機能を使う必要がある ◦ 手順としては以下の通り ▪ DrainでPodを退避させる ▪ オートスケーリンググループの最小台数を更新する ▪

    ノードをデタッチして停止する ◦ Pod側はPreStopフックを使用して、Gracefulに終了するように調整 • 運用環境のノード数だと、コマンドで地道にやるのは辛いのでスクリプト化して運用 している
  15. 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脆弱性等の攻撃に対するセキュリティが強化されているので、アップデートするのが吉
  16. 今後やっていくこと • Fluent BitからFluentdへの移行 ◦ 負荷試験を行い性能を比較した結果、 Fluentdでも十分捌ける上、動作が安定している • DNSの名前解決の問題について調査・対応 ◦

    まだ問題は顕在化していないが準備しておくに越したことはない ◦ GREEさんの記事がとても参考になる ▪ https://labs.gree.jp/blog/2020/01/20271/ • Progressive Deliveryの導入 ◦ Spinnaker + Kayentaでカナリーリリースの仕組みを構築中 • GitOpsの導入 ◦ ベストプラクティスと言われては気にせざるを得ない • オートスケールを活用する方法の模索 ◦ 現状はイベントに合わせて、事前にノードの台数を調整 ◦ もっと良い運用方法がありそう
  17. まとめ(再掲) Amazon EKSへの移行について、もちろん解決したい課題があったことは事実ですが、なによりも「技術 的に挑戦したい」という意欲が根底にあったと感じています。 コンテナオーケストレーションサービスの選択肢としては、 Amazon ECSもありましたが「AWS内に閉じた 技術知識になってしまう」という点から Amazon EKSを選択しました。

    Kubernetesであれば、Google Cloudなど他の場面でも活用できます。 Kubernetesは学習コストが高いという巷の話は確かに間違いなく、正直いまだによく分かっていない部 分が多いです。 しかし「Kubernetesに触れる」ということは既にスタンダードになっている世の中なので、運用環境移行に 挑んだことは良いアクションだったと思っています。