blog.comame.xyz

2 日間ほど MetalLB と格闘していた。

経緯

  • シングルノード Kubernetes クラスターのノードと、SoftEther を 1 つのマシンに同居させていた

このマシンには 2 つの NIC が生えており、片方は SoftEther のローカルブリッジを設定することで、リモートアクセスに使用していた。そのマシンに MetalLB を Layer-2 モードでデプロイしたところ、SoftEther のローカルブリッジに使用しているインターフェースが MetalLB によって割り当てられた External IP の ARP 応答を行うことで、VPN でリモートアクセスしている環境から Pod にアクセスできなくなる問題が発生した (これは既知の問題であり、SoftEther のドキュメントにも振る舞いが明記されている)。

  • FortiGate を買った

せっかく BGP を喋るので、MetalLB を BGP モードにしてみたかった。

BGP モードがうまく動かない

MetalLB の Configuration を参考に設定したところ、BGP は確立し、ノード内から External IP を使用して Pod と通信できるものの、ノード外からの通信が Pod に到達しない問題が発生した。一晩かけて慣れないパケットキャプチャとにらめっこすると、どうやらマシンの物理インターフェースまではたどり着いているものの、そこから Pod までルーティングされていないことが判明した。

ノード内からは繋がることから、Kubernetes のネットワークアドオンとして使用している flannel や MetalLB が致命的な原因ではいだろうと推測した。1 日かけて MetalLB の Issue を漁り倒し、物理インターフェースに割り当てられているサブネットとは違う IP アドレスでパケットを受け取っているため、応答先が分からなくなっているのではないかという素人の適当な仮説を立てた。

試しに ip route add でルートを設定してみたところ、自宅のネットワーク内からは Pod と通信できるようになり、良かった良かったと思いきや、別の問題が発生した。意気揚々とバーチャル IP を割り当ててインターネットから到達できるようにしたところ、なぜかホストが RST パケットを返し、Connection Refused エラーが出現するようになった。おそらく iptables の設定をいじれば直るだろうと思ったが、Kubernetes によって複雑な設定が書き込まれていたため、解決する気力を失って放り投げた。

BGP を使うとどのようにパケットが飛んでくるか予測しやすくなりそうで嬉しいので、しばらくしたらまた再挑戦したい。

SoftEther のローカルブリッジと ARP 応答問題

MetalLB の Issue を漁っていたところ、「L2 モードでインターフェースを指定したい」(https://github.com/metallb/metallb/issues/277) というものを発見した。どうやらインターフェースを指定するオプションを導入する方向に議論が向かっているようなので、今後どうなるかが楽しみである。

とりあえず、ワークアラウンドが提案されていた (感謝) のでそれを導入してみることにする。

ところで

WireShark とにらめっこしていたら昨晩は 3 時間しか眠れなかった。自宅でサーバを運用するとありとあらゆるところで何かしら問題が起きるので、それが楽しいところではあるなあと思う。

SoftEther のローカルブリッジのドキュメントを読み直していたところ、ローカルブリッジに使用するインターフェースは TCP/IP を無効にするように書かれていた。この設定を行ったときに MetalLB はどう振る舞うか検証したい。