なになれ

IT系のことを記録していきます

クラスタマイグレーション方式を用いてAmazon EKSの複数マイナーバージョンを一度に更新する

この頃はEKSのバージョン更新を1年に1回くらいを目処に実施しています。今回、EKSのバージョンを1.19から1.22に更新しました。
1.19は2022年6月にサポート終了するので、ギリギリのタイミングでした。。。

複数のマイナーバージョンを一度に更新する場合には、新バージョンのクラスタを事前に作成して、旧バージョンへの向き先を新バージョンに切り替えることで更新を行います。
ここではこのやり方をクラスタマイグレーション方式と呼びます。
EKSでは、1マイナーバージョンずつであればインプレースで更新できます。ただ更新頻度が高いのが作業負荷的に辛いので、このアップデート方法は現在の運用では使っていません。

この記事では、上記の内容を踏まえたEKSのバージョン更新方法とハマりポイントを共有できればと思います。
EKSを運用し始めた方に参考になる内容かと思います。また、これからEKSを採用しようという方でもこんなハマりポイントがあるという事前の情報として役立つかと思います。

要約

内容

クラスタマイグレーション方式について

クラスタマイグレーション方式は、以下のイメージでALBのトラフィックの重み付けを徐々に変えていき、クラスタを切り替える方式です。

トラフィックの重み付けを変えるのはALBの機能を使えばできます。 ALBに関連付くターゲットグループを各クラスタごとに作成し、ターゲットグループへのトラフィックの重みを変更していきます。
下記の内容が参考になります。
aws.amazon.com

移行作業時に気をつけるポイントとして、重複を許容しないリソースがある場合、旧クラスタと新クラスタが並行稼働している状態だとどちらかのクラスタでそのリソースが起動している状態にする必要があります。
クラスタから新クラスタへの移行作業時にそのリソースを移すことで、ただ一つリソースがある状態にします。

クラスタマイグレーションでは、クラスタを新しく作成する必要があります。
本環境ではTerraformのEKSモジュールを使って、クラスタを作成しています。
このモジュールですが、ここ1年の間にリリースされたv18で大きな変更があり、クラスタの作り方に修正が必要でした。

github.com

EKSの更新とは直接関係ないですが、EKSのバージョン更新の機会に周辺ツールのバージョンも更新しておくことになるかと思います。
そのため、このあたりのクラスタ作成方法に変更がないかも気にしていく必要があります。

更新時のハマりポイント

あまりに特有の問題なので再現性はないかもしれませんが、EKSの運用ではこのような運用作業が発生することがあるというくらいの認識を持ってもらえると良いと思います。

Datadog Agentの更新

土台となるKubernetesのバージョンが大きく変わるため、Kubernetes上にインストールするインフラ系のツールを更新します。
インフラ系のツールは例えば、Datadog AgentやCluster Autoscalerなどです。それら全てのKubernetesによるインフラを動作させるために必要なツールのバージョンをその時点での最新版に更新しました。
その作業の中で、Datadog Agentの更新ではいくつか問題がありました。

具体的には、Datadog Agentがクラスタを認識しないという事象が発生しました。
旧バージョンだとクラスタを自動的に認識している動作をしているようでした。この原因はよく分からなかったのですが、最終的にはクラスタ名をAgentのパラメータに直で指定することで解決しました。
下記のコマンドのようにdatadog.clusterNameのパラメータを指定します。

$ helm install datadog-agent -f values.yaml  --set datadog.apiKey=[apikey],datadog.tags=env:production,datadog.clusterName=[clustername],datadog.apm.portEnabled=true datadog/datadog --set targetSystem=linux --namespace=[namespace]

トラブルシューティングの過程で、Datadog Agentに下記コマンドを実行するとAgentの状態が確認できることを知りました。

$ kubectl exec -it <POD_NAME> agent status

このコマンドを使うと、Agentがクラスタを認識しているかなどがわかります。トラブルシューティングに役立ちます。

もう一つの問題として、Kubernetesのメトリクスを収集するのに変更が必要でした。
Datadog AgentではKubernetesのメトリクスを収集するのにkube-state-metricsを使用します。
kube-state-metricsを使うには2つの方法があり、kube-state-metricsを別途デプロイするレガシーな方法と、Datadog Agentに含まれるKubernetes State Metrics Coreを使う方法があります。
kube-state-metricsを別途デプロイする方法だと1.9.8という古いバージョンを使うことになってしまいます。
今まではkube-state-metricsを利用していましたが、kubernetesの1.22に対応するKubernetes State Metrics Coreを使うように変更しました。
Helmの場合は以下のように変更します。

values.yaml

...
  # datadog.kubeStateMetricsEnabled -- If true, deploys the kube-state-metrics deployment
  ## ref: https://github.com/kubernetes/kube-state-metrics/tree/kube-state-metrics-helm-chart-2.13.2/charts/kube-state-metrics
  kubeStateMetricsEnabled: false
...
  kubeStateMetricsCore:
    # datadog.kubeStateMetricsCore.enabled -- Enable the kubernetes_state_core check in the Cluster Agent (Requires Cluster Agent 1.12.0+)
    ## ref: https://docs.datadoghq.com/integrations/kubernetes_state_core
    enabled: true
...

どちらもやることは同じなので、被らないようにkubeStateMetricsEnabledをfalseにして無効にし、kubeStateMetricsCoreを有効にします。
Kubernetes State Metrics Coreはkube-state-metricsのバージョン2以上に対応した仕組みのようです。
docs.datadoghq.com Kubernetes State Metrics Coreに変更したことに伴い、Datadogでメトリクスを扱う際に利用するタグの名称を変更する必要がありました。
上記のリンク先にタグの変更に関する詳細があります。

containerdを使う

EKSでは1.21からコンテナランタイムにcontainerdを使うためのサポートが追加されました。
Kubernetesでは1.24でdockershimが削除されており、できるならばcontainerdへの移行をしたいところです。
EKSでは、AMIのbootstrap scriptを実行する時に以下のようにオプションを指定するだけでcontainerdを有効化できます。

--container-runtime containerd

ただ今回はcontainerdを試した結果、containerdの採用は見送りました。
理由はdockershimではできていたディスク使用量のメトリクスを取得することがcontainerdではできなかったためです。
以下にissueがあります。

github.com

1.21ではdockershimはまだ非推奨という段階のため、引き続きdockershimを利用することにしました。
containerdを使う際にはこのように取得したいメトリクスが取得できるかも確認が必要でした。

まとめ

クラスタマイグレーションをするとEKSの複数マイナーバージョンを一度に更新することができます。
containerdはメトリクスが取得できないことがあるので、dockershimが削除されるからといってそのままcontainerdに移行してよいかは現時点では考える必要がありそうです。
非推奨ではありますが、EKSではまだしばらくはサポートされる状況です。
インフラ系ツールを色々インストールすることでKubernetes自体は便利になりますが、Kubernetesの更新に追従してツールを更新するのが辛くなってきます。
やはりコンテナを動かすだけならEKSはオーバースペックだなぁと感じてしまいます。