美文网首页
Docker 网络 (二)

Docker 网络 (二)

作者: wayyyy | 来源:发表于2020-01-17 23:04 被阅读0次

    容器与外部网络的访问,这里涉及2个问题:

    1. 容器访问外部世界
    2. 外部世界访问容器
    容器访问外部世界
    root@JD:~# iptables -t nat -S
    -P PREROUTING ACCEPT
    -P INPUT ACCEPT
    -P OUTPUT ACCEPT
    -P POSTROUTING ACCEPT
    -N DOCKER
    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    -A DOCKER -i docker0 -j RETURN
    

    在 NAT 表中,有这么一条规则:
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    其含义是:如果网桥 docker0 收到来自 172.17.0.0/16 网段的外出包,把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换(NAT)

    • 容器内ping百度

      root@JD:~# docker run -it busybox
      / # ping www.baidu.com
      PING www.baidu.com (106.120.159.141): 56 data bytes
      64 bytes from 106.120.159.141: seq=0 ttl=48 time=27.228 ms
      64 bytes from 106.120.159.141: seq=1 ttl=48 time=27.242 ms
      64 bytes from 106.120.159.141: seq=2 ttl=48 time=27.172 ms
      64 bytes from 106.120.159.141: seq=3 ttl=48 time=27.263 ms
      64 bytes from 106.120.159.141: seq=4 ttl=48 time=27.083 ms
      64 bytes from 106.120.159.141: seq=5 ttl=48 time=27.147 ms
      
    • 在docker0上抓icmp

      root@JD:~# tcpdump -i docker0 -n icmp
      tcpdump: verbose output suppressed, use -v or -vv for full protocol   decode
      listening on docker0, link-type EN10MB (Ethernet), capture size   262144 bytes
      22:53:51.665408 IP 172.17.0.2 > 106.120.159.142: ICMP echo   request, id 1536, seq 0, length 64
      22:53:51.693649 IP 106.120.159.142 > 172.17.0.2: ICMP echo   reply, id 1536, seq 0, length 64
      22:53:52.665515 IP 172.17.0.2 > 106.120.159.142: ICMP echo   request, id 1536, seq 1, length 64
      22:53:52.693792 IP 106.120.159.142 > 172.17.0.2: ICMP echo   reply, id 1536, seq 1, length 64
      
    • 在eth0上抓icmp

      root@JD:~# tcpdump -i eth0 -n icmp
      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
      listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
      22:53:54.665744 IP 192.168.0.3 > 106.120.159.142: ICMP echo request, id 1536, seq 3, length 64
      22:53:54.693804 IP 106.120.159.142 > 192.168.0.3: ICMP echo reply, id 1536, seq 3, length 64
      22:53:55.665827 IP 192.168.0.3 > 106.120.159.142: ICMP echo request, id 1536, seq 4, length 64
      22:53:55.693894 IP 106.120.159.142 > 192.168.0.3: ICMP echo reply, id 1536, seq 4, length 64
      

      docker0 收到 容器 的 ping 包,源地址为容器 IP 172.17.0.2,这没问题,交给 MASQUERADE 处理,ping 包的源地址变成了eth0 的 IP 192.168.0.3

    • 处理步骤:

      1. 容器发送 ping 包:172.17.0.2 > www.baidu.com
      2. docker0 收到包,发现是发送到外网的,交给 NAT 处理。
      3. NAT 将源地址换成 eth0的 IP:192.168.0.3 > www.baidu.com
      4. ping 包从 eth0 发送出去,到达 www.baidu.com

    外部世界访问容器

    docker 可将容器对外提供服务的端口映射到 host 的某个端口,外网通过该端口访问容器。

    root@JD:~# docker run -d -p 80 httpd
    92854d59dfa5c7311603df918d102c3d0da4373678d2ab3d835185a5392b666e
    root@JD:~# docker ps
    CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
    92854d59dfa5        httpd               "httpd-foreground"   5 seconds ago       Up 4 seconds        0.0.0.0:32768->80/tcp   epic_joliot
    root@JD:~# curl 192.168.0.3:32768
    <html><body><h1>It works!</h1></body></html>
    

    每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量。

    root@JD:~# ps -aux | grep docker-proxy
    root     21849  0.0  0.0 108196  2608 ?        Sl   23:20   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.2 -container-port 80
    root     22119  0.0  0.0  14224   976 pts/2    S+   23:21   0:00 grep --color=auto docker-proxy
    
    • 处理步骤
      1. docker-proxy 监听 host 的 32773 端口。
      2. 当 curl 访问 10.0.2.15:32773 时,docker-proxy 转发给容器 172.17.0.2:80。
      3. httpd 容器响应请求并返回结果。

    相关文章

      网友评论

          本文标题:Docker 网络 (二)

          本文链接:https://www.haomeiwen.com/subject/kwvhzctx.html