Kubernetes のノードポートへの透過プロキシ

Kubernetes のノードポートへの透過プロキシ

次のコンテナを含むポッドで Kubernetes をセットアップしました。

  1. イカコンテナ
  2. transocks (redsocks のような) 透過的な SOCKS プロキシ

私はこれを Linux PC 上のローカルの k3s で実行しており、この透過プロキシを介して PC からのすべての送信トラフィックを透過的にプロキシしたいと考えています。そのため、送信ホスト トラフィックは Kubernetes ポッドの transocks ポートに強制されます。現在は機能しておらず、接続がタイムアウトします。

私が使用している iptables ルールは、ホスト ネットワークを使用して上記のコンテナーを Docker で直接実行したときに機能したため、適切であることがわかっています。squid および transocks ユーザーの uid は 31 および 32 でした。次の iptables ルールを作成しました。

#iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT
#iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT
#iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 12345
#iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 12345

12345 は、transocks がリッスンしているポートです。繰り返しますが、これらのルールは、ホスト ネットワークを使用する docker でうまく機能します。transocks は 127.0.0.1:3128 (squid ポート) に転送し、透過的にプロキシされます。ただし、ノードポート (transocks の場合は 30345、squid の場合は 30128) を使用して kubernetes ポッドを使用して試してみると、機能していないようです。タイムアウトするまで接続がハングします。

同じことを DNS でも試してみましたが、53 宛ての出力トラフィックをポート 9053 (Docker でマッピングされた DNS ポート) にリダイレクトすると動作しますが、これを Kubernetes で使用してノードポート (30053) にリダイレクトすると、同じようにハングします。つまり、何らかの理由で、トラフィックをノード ポートにリダイレクトすると、ノード ポートが動作しないようです。ここで私が見逃している点について、どなたか教えていただけないでしょうか。Kubernetes ネットワークをあまりよく理解していないに違いありません。

私の kuebrnetes のマニフェストを見たい人のために、ここにあります。

展開

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "webfilter"
      }
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "webfilter"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "squid",
            "image": "jusschwa/squid-ssl:latest",
            "ports": [
              {
                "containerPort": 3128
              }
            ]
          }, {
            "name": "transocks",
            "image": "jusschwa/transocks-proxy:latest",
            "ports": [
              {
                "containerPort": 12345
              }
            ]
          }
        ]
      }
    }
  }
}

サービス

{
  "apiVersion": "v1",
  "kind": "Service",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "type": "NodePort",
    "selector": {
      "app": "webfilter"
    },
    "ports": [
      {
        "name": "squid",
        "protocol": "TCP",
        "port": 3128,
        "targetPort": 3128,
        "nodePort": 30128
      },
      {
        "name": "transocks",
        "protocol": "TCP",
        "port": 12345,
        "targetPort": 12345,
        "nodePort": 30345
      }
    ]
  }
}

iptablesルール

iptables -t nat -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT # squid user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # transocks user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # unbound user
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 30053

ご協力ありがとうございました。

答え1

興味のある方のために言っておきますが、ノード ポートを使用するのは難しすぎると感じたので、代わりに、transocks を独自のポッドに移動し、ホスト ネットワークと上記の転送ルールを使用してこれを実現することにしました。以下は、transocks ポッドに使用したマニフェストです。

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "transocks"
  },
  "spec": {
    "hostNetwork": true,
    "dnsPolicy": "ClusterFirstWithHostNet",
    "containers": [
      {
        "name": "transocks",
        "image": "jusschwa/transocks-proxy"
      }
    ]
  }
}

これは私が使用しているトランスロック トゥールです:

listen = "0.0.0.0:12345"

# Connect to HTTP Proxy
proxy_url = "http://127.0.0.1:30128"

[log]
level = "error"

30128 は Squid プロキシのノードポートです。

関連情報