zoukankan      html  css  js  c++  java
  • 容器网络(二)docker容器访问外部网络及对外提供服务

    由于docker容器访问外部网络及对外提供服务都使用到iptable,我们先了解下iptable的基础知识。

    一、Iptables

    1、iptables的链

    iptables有5条默认的链,分别为:

    • INPUT
    • OUTPUT
    • PREROUTING
    • FORWARD
    • POSTROUTING

    2、iptables的表

    • iptables有4张表,分别为:
    • filter表,负责过滤功能
    •  nat表,网络地址转换功能
    • managle表,拆解报文,做出修改,并重新封装 的功能
    • raw表,关闭nat表上启用的连接追踪机

    3、链表的关系

    链中的规则属于四种表的其中一种

    4、常见的数据流向

    • 到本机某进程的报文:PREROUTING --> INPUT
    • 由本机转发的报文:PREROUTING --> FORWARD --> POSTROUTING
    • 由本机的某进程发出报文(通常为响应报文):OUTPUT --> POSTROUTING

    二、容器访问外部网络

    1、容器访问外部网络是通过iptable的snat实现访问外部网络的

    # docker run -it busybox
    / # ping www.baidu.com
    PING www.baidu.com (14.215.177.39): 56 data bytes
    64 bytes from 14.215.177.39: seq=0 ttl=50 time=3.459 ms
    64 bytes from 14.215.177.39: seq=1 ttl=50 time=3.432 ms
    ^C
    --- www.baidu.com ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 3.432/3.445/3.459 ms
    / # ifconfig 
    eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
              inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:6 errors:0 dropped:0 overruns:0 frame:0
              TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:989 (989.0 B)  TX bytes:426 (426.0 B)

    查看nat表

    # iptables -t nat -S
    ……
    
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    ……

    nat表规则表明,对于源地址为172.17.0.0/16段,出口网卡不是docker0的数据包进行nat转换

    2、数据包的流程图如下

    三、容器对外提供服务

    1、Docker容器是通过dnat映射或docker-proxy服务对外提供访问的

    # docker run -d -p 8080:80 httpd //-p 8080:80表示将访问宿主机8080端口的数据包转发到容器80端口的服务。
    # netstat -tlunp|grep 8080
    tcp6       0      0 :::8080                 :::*                    LISTEN      11718/docker-proxy  
    # iptables -S -t nat
    ……
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
    ……
    # curl "http://127.0.0.1:8080"
    <html><body><h1>It works!</h1></body></html>

     2、使用dnat还是docker-proxy?

    先给结论

    场景

    转发

    外部服务器访问10.30.20.87:8080

    通过iptables nat规则访问

    本机访问10.30.20.87:8080

    通过iptables nat规则访问

    本机访问127.0.0.1:8080

    通过docker-proxy 转发

    本机上的容器访问10.30.20.87:8080

    通过docker-proxy 转发

     

    完整的nat表

    # 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 POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
    -A DOCKER -i docker0 -j RETURN
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80

    1、外部服务器访问10.30.20.87:8080

     匹配到DNAT规则,访问到容器
    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80

    2、本机访问10.30.20.87:8080

    匹配到DNAT规则,访问到容器
    -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
    -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j LOG --log-prefix DOCKER-DNAT

    3、本机访问127.0.0.1:8080

    没有匹配到任何iptable,走docker-proxy

    4、本机上的容器访问10.30.20.87:8080

    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    -A DOCKER -i docker0 -j RETURN
    最后走的docker-proxy

  • 相关阅读:
    JS实例
    第一章 机器学习基础
    事件与信号
    微信公众号开发实例
    php学记笔记之函数用途
    php漏洞修复 禁用函数
    删除MYSQL账号多于的空用户
    MySql 建表、添加字段、修改字段、添加索引SQL语句写法
    php对二维数据进行排序
    iis支持IPA和APK文件下载
  • 原文地址:https://www.cnblogs.com/guoxianqi2020/p/13602580.html
Copyright © 2011-2022 走看看