ハウテレビジョンブログ

『外資就活ドットコム』『Liiga』『Mond』を開発している株式会社ハウテレビジョンのブログです。

通常6倍の料金に怯えて急いでEKSバージョンアップした話

自己紹介

外資就活プロダクトエンジニアリングチームに所属している田です。

今日はEKSバージョンアップの取り込みについて執筆しようと思います。

背景

2023年10月4日にAWSはEKSバージョンの拡張サポートを発表しました。

これにより、Kubernetes(以下k8s)のマイナーバージョンに対して追加の12ヶ月のサポートが提供されることになりました。

この発表では、拡張サポートを利用する際の具体的な金額は明らかにされていませんでしたが、通常のサポート料金よりも高くなる可能性が示唆されました。

2024年1月16日には、通常の料金の6倍になることが決まりましたが、弊社はまだVer.1.23を使用しており、急いでバージョンアップすることにしました。

i

着手にあたっての課題として、当時EKSの構築をしたメンバーは全員退職されていたため、 知見少ないとは言え、なんとかなると思って筆者がアップグレードに着手することにしました。

はじめにやったこと

1.「EKSアップデートベストプラクティスガイド」を読むこと

リンク: Best Practices for Cluster Upgrades

EKSやK8sの使用方法は組織によって異なるため、一貫した手順が存在しないようです。

私自身、専門知識を持っているわけではないので、とりあえず公式の見解に基づいて対応するのが良いと考えています。

2.アップグレード対象バージョンのリリース内容を確認する

Ver.1.24の場合は以下の通りですが、他のバージョンについても対象のサイトで確認できるはずです。

k8s

EKS

最近(2024/02)ですとAmazon EKSではアップグレードインサイトが導入されて、修正しなければいけないような箇所だけを確認したければ、 EKSのクラスター -> Upgrade insightsタブから変更の一覧を確認できます。 x 公式ドキュメント

3.アドオンの互換性確認、アップグレード

EKSがアップグレードされる際には、アドオンもアップグレードする必要があるかもしれません。 リリースノートにはアドオンの互換性に関する情報が記載されていますが、私はこの記事を見つけて参考にしました。

4.非推奨、削除されたAPIを特定し対策する

下記のツールを使用し、非推奨・削除されたAPIを特定する。

Kube-no-trouble

ドキュメント

  • インストール
% brew install kubent

マニフェストのディレクトリ内で実行する場合、一部のバッチ設定に依存するため、同じ動作が保証されるわけではありません。

  • 特定のファイルをスキャンする場合
% cd manifest
% git pull
% kubent -f ./auth/overlays/chuck_flap/deployment-patch.yaml --helm3=false -c=false
11:44AM INF >>> Kube No Trouble `kubent` <<<
11:44AM INF version 0.7.0 (git sha xxxxxx610xxxxxxxxxxxx)
11:44AM INF Initializing collectors and retrieving data
11:44AM INF Retrieved 1 resources from collector name=File
11:44AM INF Loaded ruleset name=custom.rego.tmpl
11:44AM INF Loaded ruleset name=deprecated-1-16.rego
11:44AM INF Loaded ruleset name=deprecated-1-22.rego
11:44AM INF Loaded ruleset name=deprecated-1-25.rego
11:44AM INF Loaded ruleset name=deprecated-1-26.rego
11:44AM INF Loaded ruleset name=deprecated-future.rego
  • 全体スキャンしたい場合
% FILES=($(find . -type f -name '*.yaml')); kubent ${FILES[@]/#/-f} --helm3=false -c=false -t 1.24
12:01PM INF >>> Kube No Trouble `kubent` <<<
12:01PM INF version 0.7.0 (git sha xxxxxx610xxxxxxxxxxxx)
12:01PM INF Initializing collectors and retrieving data
12:01PM INF Target K8s version is 1.24.0
12:01PM WRN failed to parse file ./shared/ingress/overlays/staging/argocd-patch.yaml: error unmarshaling JSON: json: cannot unmarshal array into Go value of type map[string]interface {}
...
12:01PM INF Retrieved 703 resources from collector name=File
12:01PM INF Loaded ruleset name=custom.rego.tmpl
12:01PM INF Loaded ruleset name=deprecated-1-16.rego
12:01PM INF Loaded ruleset name=deprecated-1-22.rego
12:01PM INF Loaded ruleset name=deprecated-1-25.rego
12:01PM INF Loaded ruleset name=deprecated-1-26.rego
12:01PM INF Loaded ruleset name=deprecated-future.rego

Pluto

ドキュメント

  • インストール
brew install pluto
  • 使い方
% cd manifest
% git pull
% pluto detect-files --target-versions k8s=v1.24.0
There were no resources found with known deprecated apiVersions.

何も検出されずちゃんと動いているのか不安な場合は、 あえて検出するようにmanifestを一時的に変更してからもう一度スキャンを試してみましょう。

例えばVer1.25では、Pod security policyの使用は廃止されました、仮にそれをmanifestに追加してみますと、下記のようになります。

manifest % FILES=($(find . -type f -name '*.yaml')); kubent ${FILES[@]/#/-f} --helm3=false -c=false -t 1.25
2:45PM INF >>> Kube No Trouble `kubent` <<<
....
2:46PM INF Loaded ruleset name=deprecated-future.rego
__________________________________________________________________________________________
>>> Deprecated APIs removed in 1.25 <<<
------------------------------------------------------------------------------------------
KIND                NAMESPACE     NAME             API_VERSION      REPLACE_WITH (SINCE)
PodSecurityPolicy   <undefined>   eks.privileged   policy/v1beta1   <removed> (1.21.0)

5.Control plane・Data planeのアップグレード

調査していたところ、大まかには同じですが、2つの提案がありました。

案1

  • Control plane
    • AWSにおまかせ
  • Data plane
    • 既存からアップデート
  • 説明
    • Control plane の操作としては、アップグレードを開始するだけです。
    • Data plane 現在の Node Group で Node を Rolling update します。
  • メリット
    • 最もポピュラーで基本的な方法らしいです。
    • マネジメントコンソール上でアップグレード作業をシームレスに実行でき、最後に Terraform を修正する必要があります。
  • デメリット
    • Rolling updateに時間がかかり作業時間が長くなる(Node・Podの数が多ければ多いほど時間がかかる)

案2

  • Control plane
    • AWSにおまかせ
  • Data plane
    • 代替を用意して置き換え
  • 説明

    • Control plane の操作としては、アップグレードを開始するだけです。
    • Data plane では、アップグレード済の新しい Node Group を用意し、現在の Node Group からアップグレード済みの新しい Node Group に Pod を移行させます。
  • メリット

    • 1よりアップグレード中の時間が短縮されます。
  • デメリット
    • アップグレード作業中にterraformのapplyを挟まなければならず、terraform主体のアップグレード作業となる。別のNodeGroupを用意するため、余分なコストが発生します。

個人的には、案1が使いやすく、採用しているとのことです。

終わり

1つのクラスタのアップデートは通常、2時間以内に完了すると感じました。

特に、ノードグループのアップデートには時間がかかるようです。したがって、アップグレード前には社内コミュニケーションツールで告知し、また監視ツールをミュートに設定しておくことがお勧めです。