🙆‍♀️

通常6倍の料金請求されそうで急いでEKSのバージョンアップした話

2024/02/14に公開

前書き

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

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

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

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

i

流石に6倍は高いし、当時EKS構築したメンバーたちも全員会社を辞めていたため、
知見少ないとは言え、なんとかなると思って筆者がアップグレードに着手することにしました。
Amazon EKS extended support for Kubernetes versions pricing

やったこと

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

リンク: Best Practices for Cluster Upgrades

EKS、K8sの使い方は組織によって様々なので、一貫性のある手順は存在しないらしいが、
自分自身ノウハウがあるわけではないため、取り合いず公式の見解を踏まえて良さそうと思いました。

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

1.24の場合は下記のなりますが、その他のバージョンも対象サイトで見つかるはずです。
k8s

EKS

最近(2024年2月)では、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. Control plane
  3. Node Group(Data plane)
  4. Iac(Terraformなど)のコードを修正して、合わせる

ただし、AWSコンソールで行う場合、Control planeを先にアップグレードしないと最新のアドオンが表示されない場合もあるため、その際に先にControl planeをアップグレードしましょう。

実際操作

1.対象EKSを選択し、「今すぐ更新」。
img
2.「更新」。
img2
3. クラスタ一覧に戻れば、ステータス更新中になります、再びアクティブになったら更新完了です。
4.更新したいアドオンのバージョンの更新を選択します。
img3
5.インストールするバージョンを選択し、オプション設定で「上書き」を選び、「変更内容を保存」を押します。
6.アドオンタブに戻れば、ステータスは「更新中」となります、10分くらいでアクディブになるはずです。
7. Data Plane(ノードグループ)のアップグレード、コンピューティングタブを選び、ノードグループから「今すぐ更新」。
8.内容を確認し更新を選択すると更新が開始されます。

  • ノードグループバージョンを更新
    • 既存のノードグループを継続利用し、EKSクラスタのバージョンに合わせてノードグループのAMIが最新のものに更新されます。
  • 起動テンプレートを変更
    • マネジメントコンソールでの更新においてはここは特に指定しなくて良さそうです。
  • 更新戦略
    • 基本的にはローリング更新で良いと思います。
    • 強制更新はPodが一斉に停止するので基本使いません。
      img4

終わり

1つのクラスタの更新は通常、2時間以内で完了すると感じました。特に、ノードグループの更新には時間がかかると感じました。
それと、社内コミュニケーションツールでのアップグレード前に告知することと監視ツールのミュートは、事前に設定しておくことがお勧めです。

Discussion