netfilterはUDP応答パケットの宛先IPを正しく置き換えることができません。

netfilterはUDP応答パケットの宛先IPを正しく置き換えることができません。

我々は、小規模なkuberentesクラスター(CentOS 7、Kuberenetes 1.13 + Flannel)を実行しており、TCP構成をわずかに調整した後(以下を参照)、DNSが正しく機能しないことがわかりました。

私は私たちの変更が私が観察したものと直接関係していないと思い、クーバーネティスも責任がないと思います。 IPテーブルを確認しましたが、私が知っている限り、すべてが大丈夫です。私が観察した内容は次のとおりです。

  1. Pod 10.23.118.10 は、UDP(53) パケットを DNS ClusterIP 10.22.0.10 に送信します。
  2. 次に、パケットの宛先IPをClusterIP(10.22.0.10)からDNSサーバーPod(10.23.118.2)のIP(DNAT)に変更します。
  3. サーバーは要求を受信して​​処理し、応答を10.23.118.10に返します。
  4. この時点で、netfilterはパケットを転送する前に送信元IP 10.23.118.2を10.22.0.10に置き換える必要がありますが、何らかの理由でそうしません。
  5. Libcはパケットを受信し、10.22.0.10の代わりに10.23.118.2からの応答を表示したりポートに接続できなかったというICMPパケットを受信するため、これを拒否します。

ここに画像の説明を入力してください。

奇妙なことに、これはDNS要求が同じシステムで実行されているポッドに送信された場合にのみ発生します。 DNS要求が他のシステムで実行されているポッドから来る場合、すべてがうまく機能します。

この姿を私たちだけ見たわけではないようです。似たような状況がありますか?これがLinux netfilterのバグであるか、ブリッジインターフェイスを設定するときにdocker / kubernetesが問題を引き起こしたかどうかはわかりません。詳細はどこで探すべきですか?

これは私たちが適用したいTCP構成です。

net.core.somaxconn = 1000
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0

ベストアンサー1

問題はCentOS 7のデフォルト設定のようです。

設定が再ロードされると、設定sysctl -p --systemも再ロードされます/usr/lib/sysctl.d/00-system.conf。私たちは/usr/lib/sysctl.d/00-system.conf次のことを見ることができます:

# Disable netfilter on bridges.
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

これが完了すると(ブリッジでnetfilterを無効にする)、NAT機能はdocker0ブリッジで正しく機能しません。

興味深いことに、dockerを再起動してシステムに問い合わせると、sysctl -a次のことがわかります。

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

この設定は、起動時にDocker自体によって変更されると想定できます。

これはDockerを再起動するのが役に立つ理由を説明します。

おすすめ記事