五、docker容器的網絡訪問


一、運行容器為什么要跟宿主機映射端口,外界才能訪問?

默認情況下,容器使用的ip是172.17.0.0/16網段的,外界的用戶只能訪問宿主機的192.168.32.0/24網段,無法訪問172.17.0.0/16網段。我們運行容器的目的:是希望運行在容器中的服務,能夠被外界訪問,這里就涉及到了外網192.168.32.0/24到容器內網172.17.0.0/16網段的轉換,所以需要做端口映射。

二、docker運行容器端口映射的方法

指定映射(docker 自動添加一條iptables規則實現端口映射)
-p hostPort:containerPort
-p ip:hostPort:containerPort 
-p ip::containerPort(隨機端口)
-p hostPort:containerPort:udp
-p 81:80 -p 443:443 可以指定多個-p

隨機映射
docker run -P (隨機端口)

iptables
[root@inode3 ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80
#容器172.17.0.2的tcp80端口已經映射到了外網的80端口上

三、docker容器的四種網絡模式

1、容器網絡配置命令

docker run --name 運行的容器名稱 --net=網絡參數選項 -p 容器端口映射 鏡像名稱:鏡像版本

--net=網絡參數選項

None:不為容器配置任何網絡功能,--net=none

Container:與另一個運行中的容器共享Network Namespace,--net=container:containerID

Host:與主機共享Network Namespace,--net=host

Bridge:Docker設計的NAT網絡模型

docker網絡查看命令

[root@inode4 ~]#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a736b9bf0850        bridge              bridge              local
db0ed8b2be23        host                host                local
0339ee737df3        mac1                macvlan             local
90c917be552d        none                null                local

2、容器的四種網絡模式

docker容器的網絡通信原理:

1、 當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上,所以有默認地址172.17.0.0/16的地址。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。

[root@inode4 ~]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
    inet6 fe80::42:8cff:fe57:ebf8  prefixlen 64  scopeid 0x20<link>
    ether 02:42:8c:57:eb:f8  txqueuelen 0  (Ethernet)
    RX packets 194130  bytes 20622371 (19.6 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 250033  bytes 780264041 (744.1 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2、 從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址為容器的默認網關。在主機上創建一對虛擬網卡veth pair設備,Docker將veth pair設備的一端放在新創建的容器中,並命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網絡設備加入到docker0網橋中。可以通過brctl show命令查看。

yum install -y bridge-utils-1.5-9.el7.x86_64
[root@inode4 ~]# brctl show
bridge name    bridge id        STP enabled    interfaces
docker0        8000.02428c57ebf8    no        veth16bb7cf #宿主機中docker0的網卡
                                        vethccb0469 #容器的網卡(在容器中eth0)

第一種網絡模式:Bridge(docker默認的網絡模式)

bridge模式是docker的默認網絡模式,不寫--net參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。可以使用iptables -t nat -vnL查看。

[root@inode3 ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80
#容器172.17.0.2的tcp80端口已經映射到了外網的80端口上

docker bridge原理圖

bridge案例

[root@inode3 ~]# docker run --net=bridge -it centos:6.9 /bin/bash
[root@b796f4521c28 /]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
      inet addr:172.17.0.3  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:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:508 (508.0 b)  TX bytes:0 (0.0 b)

[root@b796f4521c28 /]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
 0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
 172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

第二種模式:Host

如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。

docker host原理圖

 

host案例

[root@inode3 ~]# docker run -it --net=host centos:6.9 /bin/bash
[root@inode3 /]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:E2:7B:77  
      inet addr:192.168.32.103  Bcast:192.168.32.255  Mask:255.255.255.0
      inet6 addr: fe80::dceb:89ad:3d37:bebe/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:603672 errors:361 dropped:444 overruns:0 frame:0
      TX packets:245020 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:795145514 (758.3 MiB)  TX bytes:20746259 (19.7 MiB)

發現ip與宿主機的ip一樣

第三種模式:Container 網絡模式

這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。

docker container原理圖

 

命令格式

docker run --name 運行容器名稱 -d -p 容器的端口影身 --network container:共享網絡的容器名 鏡像:鏡像版本

container案例

現有運行容器web1

[root@inode3 ~]# docker inspect web1 |grep -i "ipaddress"
        "SecondaryIPAddresses": null,
        "IPAddress": "172.17.0.2",
                "IPAddress": "172.17.0.2",

運行一個新的容器centos6.9,網絡與容器web1共享

 
[root@inode3 ~]# docker run -it --name centos6.9 --network container:web1 centos:6.9
[root@7c5d1590be34 /]# ifconfig eth0
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:17 errors:0 dropped:0 overruns:0 frame:0
      TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:0 
      RX bytes:1280 (1.2 KiB)  TX bytes:1272 (1.2 KiB)

新運行的容器centos6.9的ip已經與容器web1共享,他們的文件系統是不共享 在容器centos6.9的/tmp目錄下創建一個ywx.log文件

[root@7c5d1590be34 tmp]# touch ywx.log
[root@7c5d1590be34 tmp]# ls
anaconda-post.log  yum.log  ywx.log

查看容器web1的/tmp目錄 [root@inode3 ~]# docker exec -it web1 /bin/bash root@7c5d1590be34:/# ls /tmp

第四種模式:none

使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息,只有lo 網絡接口。需要我們自己為Docker容器添加網卡、配置IP等。

不參與網絡通信,運行於此類容器中的進程僅能訪問本地回環接口;僅適用於進程無須網絡通信的場景中,例如:備份、進程診斷及各種離線任務等。

docker none原理圖

 

none案例

 
[root@inode3 ~]# docker run -it --name centos6.9 --network none centos:6.9 /bin/bash
[root@9703a325d77f /]# ifconfig eth0
eth0: error fetching interface information: Device not found
[root@9703a325d77f /]# ifconfig     
lo        Link encap:Local Loopback  
      inet addr:127.0.0.1  Mask:255.0.0.0
      UP LOOPBACK RUNNING  MTU:65536  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

 


免責聲明!

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



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