容器網絡(二)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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM