LoginSignup
5
3

More than 1 year has passed since last update.

ClusterAutoscalerでのスケールイン時のDaemonSetの挙動に気をつける

Last updated at Posted at 2022-10-26

Kubernetes環境でサーバー自体のスケールイン・アウトを管理する場合、ClusterAutoscaler(以下CA)を使用することがあります。
CAでスケールインするときのDaemonSetの挙動について気をつけないといけないなぁと思ったことがあるので記載します。

  • この記事中の想定環境
    • Kubernetesプラットフォーム
      • AWS EKS
        • Ver1.21
    • ClusterAutoscaler
      • Ver1.21.3

DaemonSetを利用する用途として「ログ収集」があります。
アプリケーションのPodがログを標準出力した場合、ホスト上の /var/log/containers/ にログが出力されます。
DaemonSetを利用し、自ホスト上のログをFluentdなど使用しログ収集先に転送する、といったようなことをするためです。

このような用途でDaemonSetを使用する場合、Nodeを削除する際にDaemonSet管理下のPodはDaemonSet以外のPodよりも早く消えてはいけません。
なぜならNodeの削除する際はDrainを行いPodの排出を行いますが、その際もログは吐き続けているからです。
仮にアプリケーションのPodよりも先にDaemonSetのFluentdのPodが先に消えてしまうと、それ以降に出力したログを収集できません。

ではCAでスケールインする場合はどういう挙動になるのでしょうか?

ということで検証してみます。

CAでのスケールイン時のDaemonSetのデフォルトの挙動の検証

以下のようなPodがいる状態です。

$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-gccws","Running"]
["kube-proxy-q7v7h","Running"]
["daemonset-fluentd-cwzb2","Running"]
["deployment-app-6d4b447dfb-7zhgt","Running"]

見てわかるようにDaemonSetのFluentdのPodとDeploymentのアプリケーションPodを想定したものです。
アプリケーションPodには spec.containers.lifecycle.preStopsleep 15 を仕込んでおり、Podを終了してもすぐには消えないようにしてあります。

この状態でCAがスケールインをすると・・・

$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-gccws","Running"]
["kube-proxy-q7v7h","Running"]
["deployment-app-6d4b447dfb-7zhgt","Running"]

DaemonSetのFluentdのPodがまず消えてしまいました。
これではアプリケーションPodが出力しているログを収集できません。

なぜDaemonSetのPodが先に消えてしまうのか?

CAのデフォルト設定を眺めてみると以下の設定がありました。

option name default description
daemonset-eviction-for-empty-nodes false Whether DaemonSet pods will be gracefully terminated from empty nodes
daemonset-eviction-for-occupied-nodes true Whether DaemonSet pods will be gracefully terminated from non-empty nodes

どうやら non-empty nodes に対してDaemonSetのPodを排出するような設定がデフォルトのようです。
このオプションを変更することにより、DaemonSetのPodを消さないようにできそうです。

※このオプションが使用できるのはCAのバージョン v1.21.3 以降です。

デフォルトの挙動を変更して実行

--daemonset-eviction-for-occupied-nodes=false をCAの引数に追加します。
その後検証用Podを以下のように立ち上げて

$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-s2bdl","Running"]
["kube-proxy-wtfhh","Running"]
["daemonset-fluentd-9zbl4","Running"]
["deployment-app-6d4b447dfb-2q7f4","Running"]

この状態でCAでスケールインすると・・・

$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-s2bdl","Running"]
["kube-proxy-wtfhh","Running"]
["daemonset-fluentd-9zbl4","Running"]

DaemonSetのPodはDeploymentのPodよりも長く生存しています!

ということで、スケールイン時にPodがどのように消えていくのかは注意する必要があります。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3