V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
fangwenxue
V2EX  ›  问与答

docker iptables 指定出口 ip

  •  
  •   fangwenxue · 2023-06-04 22:32:16 +08:00 · 1247 次点击
    这是一个创建于 520 天前的主题,其中的信息可能已经有所发展或是发生改变。
    docker network create network_1 --driver bridge --subnet 192.168.33.0/24
    
    iptables -t nat -I POSTROUTING -s 192.168.33.0/24 -j SNAT --to-source 公网 ip
    
    docker run -d --network network_1 xxx
    
    

    • 现在容器无法访问网络
    8 条回复    2023-06-06 17:28:58 +08:00
    raffdevian
        1
    raffdevian  
       2023-06-05 00:40:23 +08:00
    你在说啥, 驴唇不对马嘴。
    路由使用 ip route 命令, 关 SNAT 啥事
    raffdevian
        2
    raffdevian  
       2023-06-05 00:44:35 +08:00
    > How can i specify the outgoing ethernet interface while using docker's bridge network?

    > By default, Docker uses the default route on the host system to determine the outgoing Ethernet interface for containers connected to a bridge network. However, you can override this behavior and specify a specific outgoing Ethernet interface by configuring a custom routing table.

    Here are the general steps to specify the outgoing Ethernet interface for containers in Docker's bridge network:

    1. Identify the name of the outgoing Ethernet interface on your host system. You can use the `ip link` command to list the available interfaces:
    ```bash
    ip link
    ```

    2. Create a new routing table in the host's network configuration file (e.g., `/etc/iproute2/rt_tables`) by adding an entry at the end. Choose a unique identifier for the table (e.g., `200`) and specify a name (e.g., `outgoing_eth_table`):
    ```
    200 outgoing_eth_table
    ```

    3. Configure the new routing table by adding a rule that matches traffic from the bridge network (`my-bridge-network`) and directs it to the desired outgoing Ethernet interface (`ethX`). Replace `<outgoing_interface>` with the actual interface name identified in step 1:
    ```bash
    ip route add default via <gateway_ip> dev <outgoing_interface> table outgoing_eth_table
    ip rule add from <bridge_subnet> table outgoing_eth_table
    ```

    For example:
    ```bash
    ip route add default via 192.168.1.1 dev eth0 table outgoing_eth_table
    ip rule add from 172.20.0.0/16 table outgoing_eth_table
    ```

    4. Connect containers to the bridge network as usual:
    ```bash
    docker run --network=my-bridge-network --name my-container -d <image_name>
    ```

    By following these steps, you create a custom routing table that specifies the outgoing Ethernet interface (`ethX`) for traffic originating from the bridge network (`my-bridge-network`). Docker will then utilize this routing table when forwarding packets from containers to the internet.

    Please note that these steps are general guidelines, and the exact commands and configuration files may vary depending on your Linux distribution and version.
    raffdevian
        3
    raffdevian  
       2023-06-05 01:00:18 +08:00
    中文版本

    当使用 Docker 的桥接网络时,您可以通过以下方式配置所需的出站以太网接口:

    1. 确定主机系统上的出站以太网接口名称。您可以使用 `ip link` 命令列出可用接口:
    ```bash
    ip link
    ```

    2. 在主机的网络配置文件(例如 `/etc/iproute2/rt_tables`)中创建一个新的路由表。在文件末尾添加一条条目,选择一个唯一的标识符(例如 `200`)并指定一个名称(例如 `outgoing_eth_table`):
    ```
    200 outgoing_eth_table
    ```

    3. 通过添加规则来配置新的路由表,该规则匹配来自桥接网络(`my-bridge-network`)的流量,并将其指向所需的出站以太网接口(`ethX`)。用实际的接口名称替换 `<outgoing_interface>`。
    ```bash
    ip route add default via <gateway_ip> dev <outgoing_interface> table outgoing_eth_table
    ip rule add from <bridge_subnet> table outgoing_eth_table
    ```

    例如:
    ```bash
    ip route add default via 192.168.1.1 dev eth0 table outgoing_eth_table
    ip rule add from 172.20.0.0/16 table outgoing_eth_table
    ```

    4. 按照平常的方式将容器连接到桥接网络:
    ```bash
    docker run --network=my-bridge-network --name my-container -d <image_name>
    ```

    通过按照这些步骤进行操作,您可以创建一个自定义的路由表,用于指定来自桥接网络(`my-bridge-network`)的流量所使用的出站以太网接口(`ethX`)。Docker 将在将容器的数据转发到互联网时使用此路由表。

    请注意,这些步骤仅供参考,具体的命令和配置文件可能因您使用的 Linux 发行版和版本而有所不同。
    julyclyde
        4
    julyclyde  
       2023-06-05 11:41:31 +08:00
    需要在心里建立一个基本概念就是:
    首先,iptables 不负责路由选择、转发等各种事务
    fangwenxue
        5
    fangwenxue  
    OP
       2023-06-05 13:51:21 +08:00
    @julyclyde 我有 2 个公网 ip
    2 个公网 IP 路由配置都正常,CURL 测试也正常
    需求是
    docker 运行 2 个容器,每个容器走不同的公网出口
    zzlyzq
        6
    zzlyzq  
       2023-06-05 17:30:57 +08:00
    iptables -t nat -A POSTROUTING -o eth0 -s $ip_container_A -j SNAT --to-source $公网 ip_A
    iptables -t nat -A POSTROUTING -o eth0 -s $ip_container_B -j SNAT --to-source $公网 ip_B

    试试看,主要是加上出接口
    fangwenxue
        7
    fangwenxue  
    OP
       2023-06-05 18:27:51 +08:00
    @zzlyzq 这个有加的,截图 iptables 有
    zzlyzq
        8
    zzlyzq  
       2023-06-06 17:28:58 +08:00
    我发现你在创建网桥的时候,没有指定网桥自己的 ip 地址(作为容器的网关)。只需要在命令后面加上就好了。
    docker network create network_1 --driver bridge --subnet 192.168.33.0/24 --gateway=192.168.33.1

    否则,你这个网桥就是干巴巴的一个交换机下面接了一个电脑,怎么着也上不了网。
    本地测试通过。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3817 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:15 · PVG 08:15 · LAX 16:15 · JFK 19:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.