LoginSignup
15
5

More than 1 year has passed since last update.

EKSでPrivate IPアドレス枯渇したのでaws-nodeの設定を見直した

Posted at

本記事はZOZO Advent Calendar 2021その1の15日目の記事です。

はじめに

最近地方移住を進めており、ワクワクすっぞな亀井と申します。

さて、ZOZOTOWNはモノリシックなアーキテクチャからマイクロサービスアーキテクチャにリプレイスを進めており、マルチテナントなEKSクラスタを運用しております。
また、ZOZOTOWNは毎年正月にセールを行っており、ありがたいことに1年のピークとなるトラフィックが流れるイベントとなっております。

リプレイスによるサービスの増加と、正月セールのためのPodスケールにより、EKSでPrivate IPアドレスが枯渇してしまう事態に遭遇しました。その際対応したaws-node daemonsetの設定変更について記事にしようと思います。

Podが多数稼働するEKSクラスタを運用されている方の参考になれば幸いです。

Private IPアドレス枯渇?

Podスケールを行った際にPodがPendingで起動しない事態に遭遇しました。
AWSマネジメントコンソールでEKSの該当ノードグループを確認したところ、下記のような問題が出力されておりました。

Amazon Autoscaling was unable to launch instances because there are not enough free addresses in the subnet associated with your AutoScaling group(s).

Privateサブネットは、サブネットマスクが/20(IPアドレス数 4096)で3AZを使用しており4096*3=12,288のIPアドレスが使用可能な、比較的大きめのサブネットを用意しておりました。Podスケールを行ったとはいえ、起動ノードは合計で400台程だったため、400台で12,288のIPアドレスが足りない・・・だと?という状態でした。

Private IPアドレス枯渇の原因

aws-nodeの下記パラメータの初期設定により、稼働Pod以上のIPアドレス数がノードごとに確保されてしまっていることがIPアドレス枯渇の原因でした。

WARM_ENI_TRAGET: 1(ノードが確保する余剰ENI数)
ref. https://github.com/aws/amazon-vpc-cni-k8s#warm_eni_target

上記設定により最低確保されるIPアドレスは「ENIごとのIPアドレス数(インスタンスタイプごとに異なる)*2(ENI数。標準の1+WARN_ENI_TARGET:1)」で計算され、例えばインスタンスタイプm5.xlargeのノードでは「15*2」で最低で30IPが確保されてしまいます。

400台程のノードが稼働していたので、400ノード*30IP=12,000IPが使用されておりました。実際にはm5.xlargeよりサイズの大きいインスタンスタイプも存在したため、12,288IPに到達してしまっていたようです。

ノードで確保されているIPアドレスは、AWSマネージドコンソールから該当のノードのEC2 Instance、ネットワーキングタブで確認可能です。

aws-nodeの設定見直し

IPアドレス枯渇の対応として、下記が考えられましたが

  • (1)ノードの確保IPアドレスを減らし起動可能なノード数を増やす
  • (2)Privateサブネットを拡張しPrivate IPアドレスを増やす

まずは(1)を進めることにしました。

ノードの確保IPアドレスを減らす

aws-nodeの下記パラメータをチューニングしました。

  • MINIMUM_IP_TARGET
    • ノードが確保する最低IPアドレス数
    • デフォルトnone
    • 搭載予定Pod数+αの値を設定する
  • WARM_IP_TARGET
    • ノードが確保する余剰IPアドレス数
    • デフォルトnone
    • このパラメータが設定されると、WARM_ENI_TARGEは無視される

1ノードに8Pod程度(deamonset、deploymentなど)搭載が予想されたため、下記の様に設定を行いました。

  • MINIMUM_IP_TARGE: 10
  • WARM_IP_TARGET: 2

aws-nodeではこれらのパラメータを環境変数で設定出来、下記コマンドで設定が可能です。

kubectl set env -n kube-system daemonset/aws-node MINIMUM_IP_TARGET=10 WARM_IP_TARGET=2

または、aws-node daemonsetのmanifestに下記を追加しapplyすることでも設定が可能です。(該当箇所のみ記載しております)

spec:
  template:
    spec:
      containers:
      - name: aws-node
        env:
        - name: "MINIMUM_IP_TARGET"
          value: "10"
        - name: "WARM_IP_TARGET"
          value: "2"

設定された環境変数は下記コマンドで確認が可能です。

kubectl get daemonset -n kube-system aws-node -o yaml |yq -r '.spec.template.spec.containers[] |select ( .name == "aws-node" ).env'

この設定により、インスタンスタイプm5.xlargeのノードが確保するIPは 30→12 に減らすことが出来ました。

EKSアドオン環境における設定方法

EKS v1.18以降では、いくつかのdaemonsetをEKSアドオンとしてeksctlやCFnなどから管理が可能となりました。aws-nodeも対応しており、弊社はCFnでaws-nodeをEKSアドオンとして管理しております。

残念ながら、CFnでは環境変数を設定するオプションは現在提供されておりません・・・。そのため、上記のkubectl set envを実行する方法でお茶を濁している状況です。

AWSのコンテナロードマップには、EKSアドオンからMINIMUM_IP_TARGETWARM_IP_TARGETを設定を変更できるようにするissueが発行されているので、ゆくゆくはCFnからオプションとして設定が可能になるだろうと期待しております。

同じ気持ちの方は、是非issueへ👍をお願いします。

まとめ

  • EKSのノードはaws-node daemonsetのデフォルト設定により、多数のPrivate IPアドレスが確保されてしまい(m5.xlargeの場合最低で30IP)、思いがけずPrivate IP枯渇に直面する可能性があります。
  • aws-nodeの環境変数MINIMUM_IP_TARGETWARM_IP_TARGETを設定することで、ノードが確保するIPアドレスを抑制することが出来、IP枯渇を回避することが可能です。
  • ただし、環境変数は現在EKSアドオンからは設定できず、kubectl set envコマンドなどを実行し設定する必要があります。(ゆくゆく設定が可能になるだろうと期待しております)
15
5
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
15
5