見出し画像

EKSバージョンアップのさらなる安全化を目指す

この記事はPioneer Advent Calendar 2022の17日目の記事です。

4ヶ月に一度訪れるEKS(Kubernetes)のバージョンアップ。非常に厄介で大変な作業です。今回はそんな厄介な作業をできるだけ安全にできるように頑張った話を紹介します。

自己紹介

鈴木 光秀(すずき みつひで)

パイオニア株式会社 SaaS Technology Center(以下、STC) SaaSテクノロジー統括グループ サービス開発部 SREチーム

2018年新卒入社

車載器の組み込みソフト開発を3年程度経験した後、 現在はPiomatix(パイオマティクス)NP1、新規事業などのSRE業務を担当しています。

背景

パイオニアの一部のAWSワークロードではAmazon Elastic Kubernetes Service(以下、EKS)を採用しています。EKSはKubernetes(以下、k8s)というコンテナオーケストレーションシステムの一部をマネージドで提供してくれるサービスです。

しかし、k8sは約4ヶ月に1度の早さでバージョンアップがあり、これはEKSも同様で各バージョンのサポート期間は約1年となっています。さらに厄介なことにこのバージョンアップは1つずつしかバージョンを上げることができません。そのため高頻度でバージョンアップを強いられることになります。

‟面倒くさいから来年にやろうぜ〜! 後回し後回し!”という甘い考えは通じません。(泣)

そこでパイオニアではこの状況を少しでも改善するため、より安全な構成に改良することにしました。

どうやって安全にした?

まず我々の以前のバージョンアップ手順を簡単に説明します。

  1. アプリ開発チームに次バージョンに対応できるようマニフェストファイルの修正をしてもらう

  2. 各種アドオンやツールのバージョンアップ(in-place方式)

  3. コントロールプレーンのバージョンアップ(in-place方式)

  4. データブレーンのバージョンアップ(Blue/Greenデプロイ方式)

といった感じです。これを開発 > 検証 > 本番とバージョンアップしていきます。

ではこのバージョンアップ手順での問題点は何か?パイオニアでは下記の点を問題点として挙げました。

  • 同じクラスターを続けてバージョンアップしていくため、ロールバックする(前バージョンに戻す)ことができない

  • Blue/Greenデプロイ方式ではバージョンアップ後に検証期間を設けることができない

これらを解決するにはカナリアリリース方式を導入するのが良いと考え、EKS周辺のネットワーク構成を変更することにしました。

まずは今までのEKS構成をご覧ください。

この構成については、過去に発表した記事でも語られていますので、ぜひご覧ください。

そしてこちらが変更後の構成です。

以前よりもちょっと複雑な見た目になりましたが、大きく変わったのは下記の3点です。

  • NLBをALBに変更

  • NGINX Ingress Controllerを廃止

  • AWS Load Balancer ControllerとTargetGroupBindingを導入

順番に説明していきます。

  • NLBをALBに変更

これはカナリアリリース方式にするためです。ALBではNLBにはない重み付けでのルーティングが可能です。そのためALBを採用することで、クラスターを2つ用意し、カナリアリリース方式でバージョンアップが可能になります。

  • NGINX Ingress Controllerを廃止

  • AWS Load Balancer ControllerとTargetGroupBindingを追加

この2点の変更を説明するにはバージョンアップ以外の話も絡んできます。実は我々はバージョンアップ時だけではなく他にも解決したい悩みがありました。それはLoad Balancerのライフサイクルについてです。

パイオニアではAWSリソースを主にTerraformというIaCツールを使用して管理しています。対してk8sリソースはmanifestファイルと呼ばれるyaml形式での管理になります。

しかし、今までの構成だとNLBはk8sリソースとして扱われ、Terraformでの管理はできません。そのせいで何度か大変な目にあいました。それを解決してくれたのがこのAWS Load Balancer ControllerとTargetGroupBindingです。

詳しい内容については分かりやすく説明しているこちらの記事が参考になると思います。この記事は導入の際にも参考にさせていただきました。ありがとうございます!

そしてバージョンアップの手順としてはこうなります。

  1. アプリ開発チームに次バージョンに対応できるようマニフェストファイルの修正をしてもらう

  2. バージョンアップ済みの各種アドオンやツール、コントロールプレーン、データブレーンが入った新しいクラスターを作成する

  3. ALBの向き先を徐々に新しいクラスターに向ける

以上の変更とバージョンアップ手順により、今まで抱えていた悩みを解決することに成功しました。また、ここでは手順をかなり簡略化して書いており分かりづらいのですが、実際の作業手順は以前よりも作業が簡単になりました。

  • ロールバック可能

  • バージョンアップ後に検証期間を設けられる

  • 新しいクラスターを用意していく方式のため、バージョンを1つずつ上げる必要がなくなる

  • バージョンアップ作業時間の短縮化

など、いいこと尽くめです。

これで安心してバージョンアップできます!(フラグ)

苦労した点

先ほど安心してバージョンアップできます!と書きましたが、実はこの構成に変更してから苦労した点が結構ありました。。。今回はそのうちの1つをお話します。

この構成を検討するにあたって、情報はそれなりにありましたし、移行が超面倒なだけで、そこまで難しいものではありませんでした。むしろ移行後が非常に苦労しました。

結論から言うと500系のエラーが多発しました。。。

詳しく語るとこれまた1つ以上の記事が出来上がってしまいそうなので簡単に説明しますが、keep aliveタイムアウトの値が適切でなかったことと、Target Groupからの登録解除時に適切な終了時間が設定されていなかったことで起きたようです。

これはALBに変更したことと、各サービスにTarget Groupが紐づくようになったため顕在化したエラーでした。

最後に

EKSバージョンアップの方法は多岐にわたりますが、その方法の1つとして今回の手法を紹介しました。苦労した点もありましたが、個人的には以前より安全にバージョンアップできるようになったし、別観点での悩みごとも解決できたので満足しています。

さて弊社では、SRE、およびRustでバックエンド開発をしたいエンジニアを募集中です。もし興味を持ってくれた方がいらっしゃいましたら、採用ページをご覧ください。

Pioneer Advent Calendar 2022 の18日目は、中元祥吾さんの「「ふ~ん」で終わらせない!エンジニアがデータ分析で抑えたいポイント」です。

是非お楽しみに!