Docker網絡


1. docker網絡介紹

  大量的互聯網應用服務需要多個服務組件,這往往需要多個容器之間通過網絡通信進行相互配合。

  docker 網絡從覆蓋范圍可分為單個 host 上的容器網絡和跨多個 host 的網絡。

  docker 目前提供了映射容器端口到宿主主機和容器互聯機制(映射)來為容器提供網絡服務,在啟動容器的時候,如果不指定參數,在容器外部是沒有辦法通過網絡來訪問容器內部的網絡應用和服務的。

docker 安裝時會自動在host上創建三個網絡,查看一下docker網絡:

[root@alph ~]# docker network ls
NETWORK ID       NAME            DRIVER            SCOPE
59cb3737df3c        bridge              bridge              local
8b9081147227        host                host                local
ea6732b465e8        none                null                local
[root@alph ~]#

2. docker none網絡

       none 網絡就是什么都沒有的網絡。掛在這個網絡下的容器除了 lo(本地回環地址),沒有其他任何網卡。容器創建時,可以通過 --network=none 指定使用 none 網絡

啟動容器:
[root@alph ~]# docker run -itd --network=none --name box reg.yunwei.edu/learn/httpd:latest
18f6521f1ae21775203a3d0efe40b62082a4edb637e074292ab6f6e665cee361

查看:
18f6521f1ae21775203a3d0efe40b62082a4edb637e074292ab6f6e665cee361
[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   7 seconds ago       Up 7 seconds                            box
 
進入容器:
[root@alph ~]# docker exec -it 18f6521f1ae2 /bin/bash

查看ip
root@18f6521f1ae2:/usr/local/apache2# ip a            #僅有lo 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
root@18f6521f1ae2:/usr/local/apache2# ^C
root@18f6521f1ae2:/usr/local/apache2#

none 網絡的應用

  封閉的網絡意味着隔離,一些對安全性要求高並且不需要聯網的應用可以使用 none 網絡。

  比如某個容器的唯一用途是生成隨機密碼,就可以放到 none 網絡中避免密碼被竊取。

3. host網絡

       連接到 host 網絡的容器,共享 docker host 的網絡棧,容器的網絡配置與 host 完全一樣。可以通過 --network=host 指定使用 host 網絡。

[root@alph ~]# docker run -itd --network=host --name box2  reg.yunwei.edu/learn/httpd:latest
[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   23 seconds ago      Up 22 seconds                           box2
18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box

[root@alph ~]# docker exec -it d478bbdb1ef8 /bin/sh 
# 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:50:56:37:0c:29 brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.88/24 brd 192.168.16.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:25:8a:98:c6 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:25ff:fe8a:98c6/64 scope link
       valid_lft forever preferred_lft forever
# hostname 
alph

       在容器中可以看到 host 的所有網卡,並且連 hostname 也是 host 的。

  直接使用 Docker host 的網絡最大的好處就是性能,如果容器對網絡傳輸效率有較高要求,就可以選擇 host 網絡。

  當然不便之處就是犧牲一些靈活性,比如要考慮端口沖突問題,Docker host 上已經使用的端口就不能再用了。

  Docker host 的另一個用途是讓容器可以直接配置 host 網路。比如某些跨 host 的網絡解決方案,其本身也是以容器方式運行的,這些方案需要對網絡進行配置,比如管理 iptables。

4. docker bridge 網絡

       docker 安裝時會創建一個 命名為 docker0 的 linux bridge。如果不指定--network,創建的容器默認都會掛到 docker0 上。

[root@alph ~]# brctl show
bridge name     bridge id       STP enabled     interfaces
docker0         8000.0242258a98c6       no

       當前docker0 上沒有其他網絡設備,創建一個容器查看變化。

[root@alph ~]# docker run -itd  --name box3  reg.yunwei.edu/learn/httpd:latest  5ddc5295e266aaf49c897710ccbb1e02273f49b15afd1bdfb8f4dfffc1de9dfe
[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
5ddc5295e266        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   17 seconds ago      Up 17 seconds       80/tcp              box3
d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   9 minutes ago       Up 9 minutes                            box2
18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box
[root@alph ~]# docker exec -it 5ddc5295e266 /bin/bash
root@5ddc5295e266:/usr/local/apache2# 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@alph ~]# brctl show
bridge name     bridge id       STP enabled     interfaces
docker0         8000.0242258a98c6       no          vethaecb9c8

  一個新的網絡接口 vethaecb9c8 被掛到了 docker0 上,vethaecb9c8就是新創建容器的虛擬網卡。eth0@if7和vethaecb9c8是一對 veth pair。veth pair 是一種成對出現的特殊網絡設備,可以把它們想象成由一根虛擬網線連接起來的一對網卡,網卡的一頭(eth0@if7)在容器中,另一頭(vethaecb9c8)掛在網橋 docker0 上,其效果就是將 eth0@if7 也掛在了 docker0 上。

       eth0@if7已經配置了ip 172.17.0.2/16,這個網段有配置信息network inspect bridge 決定。

[root@alph ~]# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "59cb3737df3cea7308084fb5c112836f55520e8546cd7e7603949ab4db36a0e4",
        "Created": "2019-07-15T22:10:23.832317973+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5ddc5295e266aaf49c897710ccbb1e02273f49b15afd1bdfb8f4dfffc1de9dfe": {
                "Name": "box3",
                "EndpointID": "cb51e0323762eed6e4ea588cf64f9b0f06ffc79642c71e98008e54b3a3923341",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

5. 自定義創建網絡

  可通過 bridge 驅動創建類似前面默認的 bridge 網絡

 

(1)利用bridge驅動創建名為my-net2網橋(docker會自動分配網段):

[root@alph ~]# docker network create --driver bridge my-net2
966e69c70ce3eb189be4d993f97e6c572b470f7c74f8104059e27bd04cf9c95a

(2)查看一下當前 host 的網絡結構變化:

[root@alph ~]# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
59cb3737df3c        bridge              bridge              local
8b9081147227        host                host                local
966e69c70ce3        my-net2             bridge              local
ea6732b465e8        none                null                local

(3)查看容器bridge網橋配置(bridge就是容器和網橋形成一對veth pair)

[root@alph ~]# docker network inspect bridge   my-net2
    {
        "Name": "my-net2",
        "Id": "966e69c70ce3eb189be4d993f97e6c572b470f7c74f8104059e27bd04cf9c95a",
        "Created": "2019-07-16T02:25:29.664999007+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",  #16為掩碼。提供更多的服務
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

       刪除網絡用命令 rm

[root@alph ~]# docker network create --driver bridge my-net3
596fc585538f6862425300dcdc35b62a759f8b11feb249d142492c5519a6a0c2
[root@alph ~]# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
59cb3737df3c        bridge              bridge              local
8b9081147227        host                host                local
966e69c70ce3        my-net2             bridge              local
596fc585538f        my-net3             bridge              local
ea6732b465e8        none                null                local
[root@alph ~]# docker rm my-net3
Error: No such container: my-net3
[root@alph ~]# docker network  rm my-net3 
my-net3
[root@alph ~]# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
59cb3737df3c        bridge              bridge              local
8b9081147227        host                host                local
966e69c70ce3        my-net2             bridge              local
ea6732b465e8        none                null                local

(4)利用bridge驅動創建名為my-net3網橋(用戶自定義網段及網關)

[root@alph ~]# docker run -itd --network=my-net3 --name box4 reg.yunwei.edu/learn/httpd:latest
1fd7e0d3e08345da6e7259fbf6dcb0bf95861ec457236e81125737840032c539
[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
1fd7e0d3e083        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   18 seconds ago      Up 17 seconds       80/tcp              box4
5ddc5295e266        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour    80/tcp              box3
d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box2
18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   2 hours ago         Up 2 hours                              box

(5)啟動容器使用新建的my-net3網絡

[root@alph ~]# docker exec -it box4
"docker exec" requires at least 2 arguments.
See 'docker exec --help'.
Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...] [flags]
Run a command in a running container
[root@alph ~]# docker exec -it box4 /bin/sh
# 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
19: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:16:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.22.1.2/24 brd 172.22.1.255 scope global eth0     #自定義的網段
       valid_lft forever preferred_lft forever

(6)啟動容器使用my-net3網絡並指定ip(只有使用 --subnet 創建的網絡才能指定靜態 IP,如果是docker自動分配的網段不可以指定ip)

[root@alph ~]# docker run -it --network=my-net3 --ip 172.22.1.10 reg.yunwei.edu/learn/httpd:latest /bin/sh
# 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
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:16:01:0a brd ff:ff:ff:ff:ff:ff
    inet 172.22.1.10/24 brd 172.22.1.255 scope global eth0
       valid_lft forever preferred_lft forever

(7)讓已啟動不同vlan的box容器,可以連接到my-net2(其實在box中新建了my-net2的網卡)

[root@alph ~]# docker network connect my-net2 box4
[root@alph ~]# docker exec -it box4 /bin/sh
# 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
19: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:16:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.22.1.2/24 brd 172.22.1.255 scope global eth0
       valid_lft forever preferred_lft forever
23: eth1@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default                     #連接到box2的網卡
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth1
       valid_lft forever preferred_lft forever
#

(8)使用--name指定啟動容器名字,可以使用docker自帶DNS通信,但只能工作在user-defined 網絡,默認的 bridge 網絡是無法使用 DNS 的。

docker run -it --network=my_net2 --name=bbox1 busybox
docker run -it --network=my_net2 --name=bbox2 busybox

 (9)容器之間的網絡互聯

  a). 首先創建一個 db 容器

[root@alph ~]#  docker run -dti --name db reg.yunwei.edu/learn/centos:7
2b9cdc455352f8a5e2da50db61fef706089f4abe7ba7c4b91033cc2a55a55bf8

 b). 創建一個 web 容器,並使其連接到 db  

[root@alph ~]# docker run -dti --name web --link db:dblink  reg.yunwei.edu/learn/centos:7 /bin/bash
40bba17b3dfe2ad01d6b80d78230c975e127340170d15a49e8f7c905bbd075fe

-link db:dblink 實際是連接對端的名字和這個鏈接的名字,也就是和 db 容器建立一個叫做 dblink 的鏈接

  c). 查看鏈接的情況

[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED              STATUS                      PORTS               NAMES
40bba17b3dfe        reg.yunwei.edu/learn/centos:7       "/bin/bash"          About a minute ago   Up About a minute                               web
2b9cdc455352        reg.yunwei.edu/learn/centos:7       "/bin/bash"          About a minute ago   Up About a minute                               db

 d). 使用 ping 命令來測試網絡鏈接的情況

[root@alph ~]# docker exec -it 40bba17b3dfe /bin/bash
[root@40bba17b3dfe /]# ping db
PING dblink (172.17.0.3) 56(84) bytes of data.
64 bytes from dblink (172.17.0.3): icmp_seq=1 ttl=64 time=48.5 ms
64 bytes from dblink (172.17.0.3): icmp_seq=2 ttl=64 time=0.058 ms

再換到db容器來ping web容器,因為連接是單向的,因此是ping不同的

[root@alph ~]# docker exec -it db /bin/sh
sh-4.2# ping web

(10)容器端口映射

  在啟動容器的時候,如果不指定參數,在容器外部是沒有辦法通過網絡來訪問容器內部的網絡應用和服務的。

  當容器需要通信時,我們可以使用 -P (大)和 -p (小)來指定端口映射。

  -P(大) : Docker 會隨機映射一個 49000 ~ 49900 的端口到容器內部開放的網絡端口

  -p (小):則可以指定要映射的端口,並且在一個指定的端口上只可以綁定一個容器。

 

支持的格式有

  IP : HostPort : ContainerPort     (將Host端口映射給Container)

  IP : : ContainerPort      (隨機生成一個端口號映射為Container)

  IP : HostPort :           (類似的,讓容器隨機生成一個端口)      

a)映射所有接口地址,此時綁定本地所有接口上的 5000 到容器的 5000 接口,訪問任何一個本地接口的 5000 ,都會直接訪問到容器內部

[root@alph ~]# docker run -itd -p 8081 --name http reg.yunwei.edu/learn/httpd 
c69494d7692d9cd5aa0ce24c286ad607adb9879f35cb8ce214a1002d8c24c336

通過訪問宿主機的端口號來訪問容器

嘗試在容器http更改html文件,再刷新查看

[root@alph ~]# docker ps -a
CONTAINER ID        IMAGE                               COMMAND              CREATED              STATUS                         PORTS                  NAMES
2d7cc376dd27        reg.yunwei.edu/learn/httpd          "httpd-foreground"   About a minute ago   Up About a minute              0.0.0.0:8081->80/tcp   http
[root@alph ~]# docker exec -it http /bin/bash
root@2d7cc376dd27:/usr/local/apache2# ls               #工作目錄
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
root@2d7cc376dd27:/usr/local/apache2# cd htdocs/ #容器文件目錄
root@2d7cc376dd27:/usr/local/apache2/htdocs# ls
index.html
root@2d7cc376dd27:/usr/local/apache2/htdocs#  echo " It is so beautiful!" >> inde.html

b)多次使用可以實現多個接口的映射

docker run -dti -p 5000:5000 -p 5022:22 centos:7.0 /bin/bash

c)映射到指定地址的指定接口

  此時會綁定本地 192.168.4.169 接口上的 5000 到容器的 5000 接口

docker run -dti -p 192.168.4.169:5000:5000 centos:7.0 /bin/bash

d) 映射到指定地址的任意接口

此時會綁定本地 192.168.4.169 接口上的任意一個接口到容器的 5000 接口

docker run -dti -p 192.168.4.169::5000 centos:7.0 /bin/bash

e) 使用接口標記來指定接口的類型

docker run -dti -p 192.168.4.169::5000/UDP centos:7.0 /bin/bash

11) 通過端口映射實現訪問本地的 IP:PORT 可以訪問到容器內的 web

[root@alph ~]# for id in `docker ps -a | awk '{print $1}' | grep -v CONTAINER`;do docker rm -f $id;done
[root@alph ~]# docker run -itd --name http reg.yunwei.edu/learn/httpd:latest
34099c67cf07685fa830c1feb143d2f948a5231a48d5d542a285d3cd62a074d4
[root@alph ~]# docker exec -it http /bin/bash
root@34099c67cf07:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
root@34099c67cf07:/usr/local/apache2#
 

將容器http的/usr/local/apache2導出以免丟失目錄下內容
[root@alph ~]# docker cp http:/usr/local/apache2 ./
[root@alph ~]# ls
anaconda-ks.cfg  apache2  doc_file  docker  test
[root@alph ~]#  cd apache2/
[root@alph apache2]# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules

將現在在root下的目錄apache2映射給容器下的/usr/local/apache2
[root@alph ~]# docker run -itd -v /root/apache2/:/usr/local/apache2 -p 8081:80 --name http2  reg.yunwei.edu/learn/httpd
31ca9cce1b2c61043bfa385a1572bf9d1bf76fa19a45c8f7b2a63c983f9073a8
 

映射完成后相當於共享文件夾,在容器創建的文件在宿主機相應目錄下能夠查到,同樣在宿主機相關文件進行的修改對容器有效
[root@alph ~]# docker exec -it http2 /bin/bash
root@31ca9cce1b2c:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
root@31ca9cce1b2c:/usr/local/apache2# touch aaaaa
root@31ca9cce1b2c:/usr/local/apache2# exit
exit
[root@alph apache2]# ls
aaaaa  bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
[root@alph apache2]# cd htdocs/
[root@alph htdocs]# ls
index.html
[root@alph htdocs]# vim index.html
<html><body><h1>It works!</h1></body></html>
<html><body><h1>It so beautiful!</h1></body></html>
將該容器刪除后其文件將不受影響,再次激活該容器該文件可以繼續使用,這是一種動態的更改。


免責聲明!

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



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