🧐

より安全なEKS cluster update方法を模索する

2022/01/02に公開

これは何?

EKS cluster updateを行う機会があったので、対応するために必要そうなことをまとめました(EKSを採用するのであれば予め調査しておきましょう)。
是非とも皆さんの知見も教えてください!

cluster updateのために何をすべきか?

扱っているサービスの性質を理解する

cluster updateのHowについては調べるとある程度出てきますが、それ以上に重要なことは自分達が扱っているシステムがどのような前提条件や特徴を持っているかを理解することだと思います。
扱うシステムによってどのような対応をとる必要があるかは変わってくるため、まずは(すでに理解しているかもしれませんが)今一度自分達の運用しているサービスがどのような条件や前提のもとに動いているのかを整理しましょう。

例えば以下のような事項を整理する必要があると思います。

  • SLA/SLOはどのように設定しているか?
    • clusterが落ちた場合の影響度はどの程度であるか?またどれくらいまでであればclusterを落とせるか?
    • cluster updateのために停止メンテは入れられるか?
  • cluster update時に注意するべきリソースはあるか?
    • CronJobやArgoWorkflowなどの定期実行処理を取り扱っているか?など
    • 単純なDeploymentであればそれほど考慮する事項はありませんが、いわゆるバッチ系の処理ではcluster update時にデータの欠損/重複などの可能性が出てきます
  • k8s上に載せている永続化データは存在するか?
    • k8sを落とすと消失してしまう業務上必要なデーtは存在するか?

cluster update差分を理解する

最低限、EKSとk8sの公式ドキュメントを追っておくことは必要だと思います(なんて言ったって、公式なので)。特にk8sのリリースノートには結構な差分が載っているため、主にDeprecatedになるものや破壊的な変更に対して確認するのが良さそうだと思います。

資料 確認箇所
(AWS公式)EKS doc 全部
k8s release note ・What's New (Major Themes)
・No, really, you MUST read this before you upgrade
・Deprecation
(AWS公式)クラスターの更新 (clusterのin-place方式を採用する場合)全部

cluster update戦略を知る

ひとくちにcluster updateと言っても対応方法にはいくつかの方法があり、どの方法を選んでも理論上は全て無停止でのEKS updateが可能ですが、どこまで安全側に倒すかはシステムの性質や掛けられる工数などによって判断するのが良いと思います。
*他にも方法があると思いますので、ご存知の方は是非ともコメントください!

# 方法 メリット デメリット 安全度(選択肢内での相対) 対応コスト(選択肢内での相対)
1 完全in-place方式(既存のリソースをupdateする) ・対応が最も簡単(IaCなどしている場合には設定値を変更してapplyするだけ) ・一気にアップデートするためサービスへの影響が不安
・バージョンを1つずつしか上げられない
低 ~ 中
2 control planeはin-place方式(既存のリソースをupdateする),worker nodeはmigration方式(新リソースに差し替える) ・塩梅が良い ・affinityなどを使ってPodのNode退避などの設定が必要
・バージョンを1つずつしか上げられない
3 完全migration方式(新リソースに差し替える) ・より安全にcluster updateが実施可能 ・毎回実施するには対応が重め

1. 完全in-place方式

cluster, worker node共にin-placeでcluster updateを実施します。IaC化している場合にはEKS cluster, Worker Node(Managed Node Group)のAMI, eks add-onを変更してapplyするだけで対応が終わるので、対応のお手軽さ度合いで言うとこれがダントツだと思います。
一方でサービスに対する影響度合いが大きいため(理論上は無停止でEKS updateできますが、相対的な影響は大きい)、ある程度勇気の必要な方式でもあります。
リソースを切り戻せないためupdate対応漏れなどがあると即座に障害発生につながりますし、in-replaceする際に下準備の必要があるリソースなどがある場合には不向きかと思います。

EKS control plane update時の挙動

EKS control plane update時の挙動についてはこちらが参考になります。
https://aws.github.io/aws-eks-best-practices/reliability/docs/controlplane/#handling-cluster-upgrades

記事によると、in-place updateではdowntime無しにupdateが可能なようです。

EKS performs in-place cluster upgrades for both Kubernetes and EKS platform versions. This simplifies cluster operations and lets you take advantage of the latest Kubernetes features and apply security patches, without any downtime.

以下の資料にも zero downtime と記載がある上で普通にcontrol planeのupdateを実施している(worker node上のPodは別途退避している)ので、control planeのupdateによるdowntimeは発生しないような仕様のようです(今度手元でも検証しようと思います)。

https://www.youtube.com/watch?v=Yh4BFtIKuT8

EKS Worker Node update時の挙動

Managed Node Group update時の挙動についてはこちらが参考になります。
https://docs.aws.amazon.com/eks/latest/userguide/managed-node-update-behavior.html

こちらによるとローリングアップデート方式でworker nodeを更新するため、安全に移行ができるようになっています。
*Worker Node自体は安全にアップデートされますが、Worker Node上で稼働するPodについてはPodのDisruption Budgetを設定していないと旧versionのWorker Nodeがdrainされる際にサービスの停止時間が発生する可能性があります。

さすがクラウドインフラ、至れり尽くせりですね。

利用に適しているケース

以下の場合に利用するのが効果的かなと思います

  1. ある程度のdowntimeが許容できる場合
  2. 停止メンテナンスを実施できる場合
  3. 他の2つの方法を取るにはあまりにも工数がかかってしまう場合

およその手順

細かい点は扱っているサービスにより変わってくると思いますが、大枠としては AWS公式が出している手順の通りに実施します。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/update-cluster.html

  1. cluster updateのための前提条件のクリア
  2. clusterをアップデート
  3. Managed Node Groupをアップデート
  4. VPC CNI, CoreDNS, kube-proxyなどのadd-onをアップデート

2. clusterはin-place方式,worker nodeはmigration方式

clusterは 1.完全in-place方式 と同じように既存のものをアップデートし、worker nodeは新versionのManaged Node Groupを作成して旧versionのMNGからPodを引っ越したのちに旧versionのを削除します。
Podの退避も面倒を見るため、1.と比較してPodの移行をより安全に実施できる方式なため、1.完全in-place方式3.完全migration方式 のちょうど中間的なポジションだと思います。

利用に適しているケース

以下の場合に利用するのが効果的かなと思います

  1. 工数を抑えつつdowntimeを抑えたい場合
  2. migration方式では工数がかかりすぎてしまう場合

およその手順

こちらも細かい点は扱っているサービスにより変わってくると思いますが、大枠としては以下のように実施します。

  1. cluster updateのための前提条件のクリア
  2. clusterをアップデート
  3. 新versionのManaged Node Groupを作成
  4. 旧versionのManaged Node Groupから新versionのものにPodを引越し
  5. 旧versionのManaged Node Groupを停止
  6. VPC CNI, CoreDNS, kube-proxyなどのadd-onをアップデート

3. 完全migration方式

「クラウドインフラリソースはペットではなく家畜のように扱え」という言葉が古事記にも載っているように、EKS clusterも新しいものを作成した上で入れ替えよう、という考えです。
3つの方式の中で最も安全にcluster version upが行える一方で、毎回これをやるにはなかなか準備が大変だったりもします(IaC化していても、やはり値の変更だけで対応が終わるとも限りません..)。

利用に適しているケース

以下の場合に利用するのが効果的かなと思います

  1. downtimeが許されない場合
  2. それほど工数をかけずに複数clusterの構築/増築ができる場合

およその手順

こちらも細かい点は扱っているサービスにより変わってくると思いますが、大枠としては以下のように実施します。

  1. 新clusterを起動
  2. 外部アクセスを新clusterに流す
  3. 新clusterが正常動作することを確認する
  4. 旧clusterを削除する

その他考慮すべき事項

扱っているシステムの特性によってさまざまあると思いますが、共通して気にするとことしては以下が挙げられるかと思います。

Graceful Shutdown

実際にcluster updateを行うにはworker nodeやPodを安全にシャットダウンする必要があるため、それらの仕様についても理解が必要です。
以下の記事が大変参考になりました。

https://zenn.dev/hhiroshell/articles/kubernetes-graceful-shutdown

https://kubernetes.io/docs/concepts/architecture/nodes/#graceful-node-shutdown

https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/

雑感

  • EKSを用意すること自体もボチボチ大変ですが、運用はもっと大変だなぁと思いました(コナミ)

参考

https://tech.recruit-mp.co.jp/infrastructure/post-21469/

https://logmi.jp/tech/articles/323033

https://logmi.jp/tech/articles/323044

https://tech.enigmo.co.jp/entry/2020/12/13/100000

https://speakerdeck.com/potsbo/k8s-kubernetes-8-factors

https://tech.smartcamp.co.jp/entry/eks-4-version-update

https://dev.classmethod.jp/articles/aws_summit_online_2021_zozo_technologies/

Discussion