こんにちは、技術戦略部 SREグループのカンタンです。
Mobility Technologies(MoT)では様々なサービスを支えるためにKubernetesを幅広く利用しています。マルチクラウド構成でIstioサービスメッシュやHelmパッケージマネージャなどを使ってAmazon EKSとGKEクラスターを運用しています。
本記事ではKubernetes、Istio、Helmのとても古いバージョンで動いていたクラスターの大幅アップデートストーリー、乗り越えた壁、ダウンタイムを発生させないためのコツなどを紹介させていただきます。内容がそれなりにあるため複数の記事に分けて説明させていただきます。
MoTではAmazon EKSが東京リージョンに対応した翌月の2019年1月からEKSクラスターの本番運用を行なっています。Kubernetesの運用はその半年前にAzure AKSクラスターで始めて、現在EKSと加えてGKEクラスターの本番運用もしています。様々なクラウドサービスを利用し比較的長い期間ビジネスニーズと組織に合わせてやり方を調整しながら運用してきて、それなりの経験を積んできたと思います。
本記事ではMoTの中で歴史が一番長いEKSクラスターの大幅アップデートの話をさせていただきたいと思います。3年以上前に作ったクラスターで、当時Kubernetes 1.10バージョンで動いていました。最初からHelmパッケージマネージャを使ってKubernetes Cluster AutoscalerやKubernetes Metrics Serverなど基本ツールを簡単にクラスターにインストールしていました。元々Azure AKSで動いていた環境をEKSに移行したという背景もあって、AWS CLB + NGINX Ingress Controllerでロードバランシングを実現していました。その後、gRPC通信のロードバランシングを可能にすることと可観測性向上のためIstioサービスメッシュも導入しました。
クラスター構成は以下のように、k8s 1.10、Helm 2.1、Istio 1.2 (k8s 1.13で途中で導入)、NGINX Ingress 0.28など当時最新でしたが今からするととても古いバージョンを利用していました。
セルフマネージドノードのEC2インスタンスを使っていたことと冗長化不可能なレガシーアプリケーションもクラスターで動いていたため、Kubernetesバージョンアップデートの手順が複雑で、ステップ数も多くかなり大変でした。Kubernetes Cluster AutoscalerとAWS CLBの相性があまり良くなく、ノードスケールインの際に502エラーが発生するバグがあって、NGINX Ingress Controllerのバージョンアップデートも大変でした。その影響で、Kubernetesとその周りのツールのバージョンアップデートがあまりできず、EKSのk8sバージョンサポート終了までに触らないようにして、いつも締切直前に対応するという、理想とは全く言えない状態でした。
安全にサービスを提供し続けるため、SREグループでKubernetesと全てのツールを最新バージョンまでアップデートし、それから定期的にアップデートできるように様々な取り組みを実施し体制を整えました。その中でHelmメジャーバージョン2の廃止、Istioコントロールプレーンのアーキテクチャ変更、Kubernetes v1.16のAPI廃止とv1.22のAPI廃止など、様々な壁にぶつかりました。更にKubernetes v.1.22アップデートのためにNGINX Ingress Controllerのアップデートが必要で、そのアップデートのためにHelm v3が必要など、依存関係があってさらに複雑な状態でした。課題を一つずつタスク化してSREグループで一丸となって対応しました。
アップデートを以下のように複数の段階に分けました
これからはこの大幅アップデートで学んだことと小さな注意点とコツを共有させていただきます。内容がそれなりにあるため、以下の記事に分けて説明させていただきます。ご参考になれば幸いです!
最終的に現在の2022年5月でEKSがサポートしているKubernetesバージョンの中の最新のv1.21、最新のIstio v1.13、Helm 3.8、NGINX Ingress Controller 4.0まで無事にアップデートできました。途中でクラスターの安定性を向上させるためAWS CLBからAWS ALBに切り替えたり、アップデートの手間を下げるためEKSマネージドノードに移行したり、運用コストを下げるためにスポットインスタンスを導入したりして様々な取り込みを実施しました。最新の構成図が以下のようで、改善の余地がまだあるものの比較的に最新の技術を使った安定している環境になっています。バージョンアップデートの締切ギリギリまでにしか対応できなかった頃から比べると、dockerからcontainerdへの移行やk8s 1.22へのアップデート準備など、余裕をもって先に動けるようになりました!
最新バージョンのKubernetesクラスターを新規構築してサービスメッシュなど魅力的な技術をたくさんセットアップすること自体は難しくないですが、長年運用しているクラスターをダウンタイムなく継続的にアップデートすることは難しいと思います。
この大幅アップデートを振り替えてみると、やはり利用しているツールと技術の定期的なアップデートがとても大事だと思います。放置してしまうとコントロールできないタイミングでアップデートする必要が出てきて慌てて対応してミスしたり、アップデート作業が圧倒的に複雑になったりしています。
途中で構成を変更したり利用しているツールを調整したりしましたが、アップデートを通してMoTの運用方法で以下の点が良かったと思います
古いクラスターをモダンなアーキテクチャにアップデートができてとてもよかったですが、数年後同様な大幅アップデートがもう一度必要にならないように継続的なアップデートをきちんと実施していきたいと思います。
NGINX Ingress Controllerを廃止してIstio Ingress Gatewayに統合してアーキテクチャをシンプルにしたり、Argo CDを使ってGitOpsを導入したりすることなど、やりたいことがまだたくさんあります。
MoTでは大幅な変更を恐れずにモダンな技術を使って新しいサービスをどんどん増やしています。これからもプロダクトを支えているKubernetesクラスターを進化していきたいと思います!
興味のある方は 採用ページ も見ていただけると嬉しいです。
Twitter @mot_techtalk のフォローもよろしくお願いします!