web-dev-qa-db-ja.com

Dockerコンテナーからホスト127.0.0.1にUDPパケットを転送する方法

127.0.0.1:8125でリッスンするStatsDデーモンを備えたホスト(A)があります。

root@A# netstat -uln
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
udp        0      0 127.0.0.1:8125          0.0.0.0:*                          

そして、Dockerコンテナー(B)がホストAで開始され、ブリッジネットワークが設定されています。

root@A# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "02b013615710b375744975ff74bdd0b5dcc8c25debba4fa23ad8f53da2c684e3",
        "Created": "2017-04-21T08:13:04.389253904Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "e1fde895c871504f64627c88531a380269ee9fe8a9fa5237a98c81500fa47a7a": {
                "Name": "B",
                "EndpointID": "4e4a8758e811bb48cecec67d339c182c60e1d955126506cddb7d451e818c5535",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.Host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

私のネットワークインターフェイス:

root@A# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope Host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope Host 
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:60:00:2c:63 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:60ff:fe00:2c63/64 scope link 
       valid_lft forever preferred_lft forever

ここで、次のようなメトリックを持つUDPパケットをコンテナBからAのStatsD(127.0.0.1:8125)に送信したいと思います。

root@B# echo "metric.name:1|c" | nc -w 1 -u 172.17.0.1 8125

UDPパケットを172.17.0.1:8125から127.0.0.1:8125に転送するには、次に何をすべきですか?

私はiptablesルールを追加しようとしました:

root@A# iptables -t nat -A PREROUTING -p udp -i docker0 -d 172.17.0.1 --dport 8125 -j DNAT --to-destination 127.0.0.1:8125

しかし、StatsDにはまだUDPパケットが表示されません。

iptables nat:

root@A# iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 736 packets, 53956 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 211K   13M DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
    3   116 DNAT       udp  --  docker0 *       0.0.0.0/0            172.17.0.1           udp dpt:8125 to:127.0.0.1:8125

Chain INPUT (policy ACCEPT 724 packets, 53227 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 838 packets, 57674 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   20  1186 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 1407 packets, 91792 bytes)
 pkts bytes target     prot opt in     out     source               destination         
84593 5296K MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:8080

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
 1285 77084 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
  933 55820 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:8080

iptablesフィルター:

root@A# iptables -t filter -L -n -v
Chain INPUT (policy ACCEPT 33641 packets, 5895K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
2298K 1931M DOCKER-ISOLATION  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
1165K  662M DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
 602K  560M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
1133K 1269M ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 27954 packets, 14M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 8285  685K ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:8080

Chain DOCKER-ISOLATION (1 references)
 pkts bytes target     prot opt in     out     source               destination         
2298K 1931M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

なにが問題ですか?

重要:

  1. Aの127.0.0.1:8125でのみstatsdを使用する必要があります(172.17.0.1:8125でリッスンするように設定することはできません)
  2. Dockerネットワークは「ブリッジ」のみです(「ホスト」は使用できません)
3
Futurama1

誰かが気にしたら、私は問題を解決しました

sysctl -w net.ipv4.conf.docker0.route_localnet=1
4
Futurama1