1. 程式人生 > 其它 >docke網路型別詳解

docke網路型別詳解

一、bridge網路

1.建立一個測試容器
[root@localhost ~]# docker run -d -it --name busybox_1 busybox /bin/sh -c "while true;do sleep 3600;done"
03b308c847edd23f21ba69afb825d92f7aaeb05b1ff4431dd47ccee439a0361a
2.檢視當前機器docker有哪些網路
[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fa30a4d17b5b        bridge              bridge              local
a03aaca35833        host                host                local
d85c50eb947c        none                null                local
3.檢視bridge詳細資訊(如果沒有指定網路,預設使用bridge網路)
[root@localhost ~]# docker network inspect fa30a4d17b5b  #fa30a4d17b5b  為bridge的ID
.....
        "Containers": {                    #該欄位表示名稱為busybox_1的Container網路連線到的是bridge這個網路
            "03b308c847edd23f21ba69afb825d92f7aaeb05b1ff4431dd47ccee439a0361a": {  #容器的ID
                "Name": "busybox_1",        #容器的名稱
                "EndpointID": "c850f22941894ef8655a80a96e4be4c5045699b70b4bc17201f80f07a27a3b4d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",  #地址
                "IPv6Address": ""
            }
        },
......
4.檢視宿主機及容器busybox_1這個容器的網路介面,其中宿主機的veth66a7ab0@if110與容器中的eth0@if111網路介面實際上是一對pari,而veth66a7ab0@if110又連線到docker0上
[root@localhost ~]# ip a   #檢視宿主網路介面
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:fd:34:4b brd ff:ff:ff:ff:ff:ff
    inet 172.16.150.135/24 brd 172.16.150.255 scope global eth0
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:23:c0:91:f9 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
111: veth66a7ab0@if110: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 7e:59:81:8b:54:a2 brd ff:ff:ff:ff:ff:ff link-netnsid 0

[root@localhost ~]# docker exec busybox_1  ip a  #檢視busybox_1容器的網路介面
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    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
110: eth0@if111: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
5.驗證veth66a7ab0網路與docker0相連線
[root@localhost ~]# brctl show   #如果沒有該命令,yum安裝 bridge-utils軟體包即可
bridge name    bridge id        STP enabled    interfaces
docker0        8000.024223c091f9    no        veth66a7ab0
6.建立第二測試容器
[root@localhost ~]# docker run -d -it --name busybox_2 busybox /bin/sh -c "while true;do sleep 3600;done"
b884db0bf4a862281b1dfb66457c7f565896fce1a40151619e80c2c5b1499216
7.再次檢視bridge網路資訊
[root@localhost ~]# docker network inspect bridge
......      
      "Containers": {
            "03b308c847edd23f21ba69afb825d92f7aaeb05b1ff4431dd47ccee439a0361a": {
                "Name": "busybox_1",
                "EndpointID": "c850f22941894ef8655a80a96e4be4c5045699b70b4bc17201f80f07a27a3b4d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "b884db0bf4a862281b1dfb66457c7f565896fce1a40151619e80c2c5b1499216": {
                "Name": "busybox_2",  #busybox_2 也連線到bridge
                "EndpointID": "a5e56917165daf2965bf7f24cf9ce58c88e4ff3c1118544c49ca5f25172af28d",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
......
8.檢視本地網路介面,發現多了113: vethc039e93@if112
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:fd:34:4b brd ff:ff:ff:ff:ff:ff
    inet 172.16.150.135/24 brd 172.16.150.255 scope global eth0
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:23:c0:91:f9 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
111: veth66a7ab0@if110: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 7e:59:81:8b:54:a2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
113: vethc039e93@if112: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ea:a2:a8:dc:48:78 brd ff:ff:ff:ff:ff:ff link-netnsid 1
9.檢視bridge網路資訊,發現docker0連線率兩個介面了
[root@localhost ~]# brctl show
bridge name    bridge id        STP enabled    interfaces
docker0        8000.024223c091f9    no        veth66a7ab0
                                        vethc039e93
簡單拓撲圖:
總結:實質上docker容器之間通過與docker0介面連線.實現先互直接通訊,感覺有點像交換機?
10.docker訪問公網簡單拓撲圖
小結:實質上docker訪問公網網路通過docker0 NAT轉發實現

二、host網路

1.檢視當前服務埠
[root@localhost ~]# netstat -tnlp  #除了sshd,沒有其他服務埠
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      965/sshd            
tcp6       0      0 :::22                   :::*                    LISTEN      965/sshd    
2.建立一個測試容器,指定使用host網路
[root@localhost ~]# docker run  -d --privileged --name my_centos  --network host  docker.io/centos /usr/sbin/init  #建議使用centos映象,後續測試需要
cfb8d105dcb44947ce794d890b67c905df9aa1ba67ef2675fd1a51177d47835d
3.檢視host網路資訊(注意容器的網路資訊)
[root@localhost ~]# docker network inspect host 
......
 "Containers": {
            "cfb8d105dcb44947ce794d890b67c905df9aa1ba67ef2675fd1a51177d47835d": {
                "Name": "my_centos",
                "EndpointID": "4250d74b28f8125688bd7d0f1475a7d107135c0e87367a9c35c197fd981b7cd4",
                "MacAddress": "",   #可以看到我們建立的容器此時並沒有Mac和IP地址
                "IPv4Address": "",
                "IPv6Address": ""
            }

......
4.進入容器內部,檢視網路資訊
[root@localhost ~]# docker exec -it my_centos /bin/bash
[root@localhost /]# ip a    #預設沒有相關檢視命令
bash: ip: command not found
[root@localhost /]# ifconfig
bash: ifconfig: command not found
[root@localhost /]# yum install net-tools -y  #我們yum安裝(是不是很奇怪,沒有網路地址怎麼安裝)
[root@localhost /]# ifconfig    #內容太多不粘了,但是顯示的應該是當前宿主機的網路資訊
[root@localhost /]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -   
5.在容器總安裝httpd伺服器,並啟動
[root@localhost /]# yum install httpd -y
[root@localhost /]# systemctl restart httpd
[root@localhost /]# netstat -tnlp  #發現多了80埠
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1305/httpd          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -   
6.退出容器,在宿主機上檢視當前網路連線
[root@localhost ~]# netstat -tnlp #宿主機上80埠也被開放了
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      7032/httpd          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      965/sshd            
tcp6       0      0 :::22                   :::*                    LISTEN      965/sshd   
7.對於host模式的思考:
host模式下是怎麼佔領埠的?

host模式端口占用模式是你的容器佔用你主機上當前所監聽的埠(官網描述為publish),比如我們都知道Nginx佔用80埠,那麼當我們用host模式啟動的時候,主機上的80埠會被Nginx佔用,這個時候其他的容器就不能指定我們的8080埠了,但是可以指定其他埠,所以說一臺主機上可以執行多個host模式的容器,只要彼此監聽的埠不一樣就行。

host模式下使用-p或者-P會出現WARNING: Published ports are discarded when using host network mode

當你是host模式的時候,主機會自動把他上面的埠分配給容器,這個時候使用-p或者-P是無用的。但是還是可以在Dockerfile中宣告EXPOSE埠

host模式設計的原因

host模式設計出來就是為了效能,訪問主機的埠就能訪問到我們的容器,使容器直接暴露在公網下,但是這卻對docker的隔離性造成了破壞,使得安全性大大降低。這種模式有利有弊,對於每個人來說看法都不一樣,具體取捨看個人。

三、none網路

1.建立一個測試容器
[root@localhost ~]#  docker run -d --name test1 --network none busybox  /bin/sh -c "while true;do sleep 36000;done"
ca1771ebfe436137156568cd570c116d12bd85e782dbec365c9f62a70209d028
2.檢視none網路資訊
[root@localhost ~]# docker network inspect none 
......
        "Containers": {
            "ca1771ebfe436137156568cd570c116d12bd85e782dbec365c9f62a70209d028": {
                "Name": "test1",  #容器無法看到Mac和IP地址
                "EndpointID": "ddcff44cdedb78f59108c6978345a256baa8bb09965461b2ffac58d5334fdba6",
                "MacAddress": "",
                "IPv4Address": "",
                "IPv6Address": ""
            }
......
3.進入容器檢視網路資訊
[root@localhost ~]# docker exec -it test1 /bin/sh
/ # ip a           #只有迴環介面
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    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

小結:none網路的容器只有一個自己的迴環介面,沒有任何 IP 地址分配,所有這個網路中的每個容器都是孤立的。但是所有網路配置我們都可以自己配置,如IP、網絡卡等