気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM等について、学んだことや備忘録をアウトプットとして残し、情報を必要としている誰かにとって「かゆいところに手が届く」ブログとなることを願いながら記事を書いています。

【Kubernetes】Docker Desktop(Windows)でLoadBalancerのsessionAffinity: ClientIPを指定した場合にうまく通信できない問題への対応方法

スポンサーリンク

概要

Docker Desktop(Windows) KubernetesのServicetype: LoadBalancerを指定し、
セッションを維持するためにsessionAffinity: ClientIPを指定すると対象のポートに通信できない問題が発生する。

  • 以下のようなメッセージが出て、とても悲しい
    • このページは動作していません
    • データが送信されませんでした。
    • ERR_EMPTY_RESPONSE

sessionAffinity: ClientIPを指定しない場合は通信できるが、レプリカ数を増やしたい場合に問題となるため、解消したい

  • sessionAffinity: ClientIPとは?・・・ステートフルなサービス利用時に必要。リクエスト先のPodに関して、ユーザーのクライアントIPを元に、セッションを考慮して振り分けてくれる
  • 例:APサーバー上でセッションを管理しているアプリがあり、APサーバーが2台あるとする*1
    • APサーバー1で処理したら、セッションが終わるまでAPサーバー1と通信する必要がある。理由としては、APサーバー1上にセッション情報があり、セッションIDを識別しているため。
    • ここで、sessionAffinityオプションがないと、途中でAPサーバー2(セッションが存在しないサーバー)に振り分けられてしまい、セッションタイムアウトが発生してしまう。
    • KubernetesのPodの1つが、APサーバー1つに対応するイメージ。
例: type: LoadBalancer, sessionAffinity: ClientIP
apiVersion: v1
kind: Service
metadata:
  name: ap
spec:
  selector:
    app: ap
  ports:
  - port: 8888
    targetPort: 8080
  type: LoadBalancer
  sessionAffinity: ClientIP

対応方法

  • 下記の記事のとおり、WSLカーネルをダウンロード&オプション付きでビルドし、利用するように設定すれば解消可能。*2

medium.com

  • 手順の概要

・[1] 以下のスクリプトを1行ずつ実行する
注意:25行目は、Windows側から実行する必要がある。

gist.github.com

・[2] 任意の場所にカーネルファイル(bzImage)を配置する
本記事では、C:\wsl\kernel\bzImageへの配置を前提とする

・[3] ユーザーのホームディレクトリ%USERPROFILE%.wslconfigファイルを作成する

・[4] .wslconfigに以下の内容を記載する

[wsl2]
kernel=C:\\wsl\\kernel\\bzImage

・[5] WSLを再起動する

> wsl --shutdown
> wsl

これで心置きなく、LoadBalancerのsessionAffinityを指定できるようになる。

*1:APサーバー上ではなく、キーバリューストアなどの外部にセッション情報を持たせることができれば特に問題にはならない

*2:カーネルビルド用に、UbuntuのDockerイメージを取得し、カーネルビルドに必要なモジュールをインストール。WSLカーネルのソースコードを取得し、CONFIG_NETFILTER_XT_MATCH_RECENT設定を有効にした上で、ビルド実行。ビルドイメージをWindowsにコピーし、WSLで利用するように設定