docker系列(三) docker的網絡模式以內部通訊

簡介

關於docker的安裝文檔,請參照上篇文章<docker系列二在宿主機上的安裝和卸載>,本文主要針對docker中容器間的通訊方式以內部通訊進行說明。 [toc]html

容器間的通訊

自從docker容器出現,容器的網絡通訊一直是衆人關注的焦點,而容器的網絡方案又能夠分爲兩大部分:node

  1. 單主機的容器間通訊;
  2. 跨主機的容器間通訊。

單主機Docker網絡通訊

咱們在使用docker run建立 Docker 容器時,可使用--network=選項指定容器的網絡模式,Docker 有如下 4 種網絡模式:linux

  • host 模式,使用--network=host指定,不支持多主機;
  • bridge 模式,使用--network=bridge指定,默認設置,不支持多主機;
  • container 模式,使用--network=container:NAME_or_ID指定,即joiner 容器,不支持多主機;
  • none 模式,使用--network=none指定,不支持多主機。

bridge模式

bridge之使用默認網橋

當Docker進程啓動時,會在主機上建立一個名爲docker0的虛擬網橋,此主機上啓動的Docker容器會鏈接到這個虛擬網橋上。虛擬網橋的工做方式和物理交換機相似,這樣主機上的全部容器就經過交換機連在了一個二層網絡中。從docker0子網中分配一個 IP 給容器使用,並設置 docker0 的 IP 地址爲容器的默認網關。在主機上建立一對虛擬網卡veth pair設備,Docker 將 veth pair 設備的一端放在新建立的容器中,並命名爲eth0(容器的網卡),另外一端放在主機中,以vethxxx這樣相似的名字命名,並將這個網絡設備加入到 docker0 網橋中。能夠經過brctl show命令查看。安裝brctl命令:nginx

yum install -y bridge-utils 
[root@linux-node4 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242d84b7159       no

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

實驗過程以下:docker

  • 步驟一:建立兩個容器
    docker run   --name docker1      nginx:1.13.12
    docker run -d --name docker2 nginx:1.13.12
  • 步驟二:查看機器上多了兩個veth虛擬網卡,查看網絡地址如咱們以前說的同樣
[root@linux-node4 ~]# 
[root@linux-node4 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242d84b7159       no              veth8c72f4a
                                                        vethf15e034
                         [root@linux-node4 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
75539117a127        nginx:1.13.12       "nginx -g 'daemon of…"   About an hour ago   Up About an hour    80/tcp              docker2
69f1c16d206c        nginx:1.13.12       "nginx -g 'daemon of…"   About an hour ago   Up About an hour    80/tcp              docker1    
[root@linux-node4 ~]# docker inspect 75539117a127 |grep 172.17
            "Gateway": "172.17.0.1",
            "IPAddress": "172.17.0.3",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",

bridge之使用自定義網橋

使用自定義的網橋網絡

docker network create -d bridge my-net4  --subnet=192.168.100.1/24

建立一個自定義網橋-d指定模式爲bridge,也能夠爲overlay,--subnet指定子網範圍; 建立兩個容器,並鏈接到咱們自建的網橋:curl

[root@linux-node4 ~]# docker run -d --name=my_test1  --network my-net4 nginx:1.13.12
ffc47de3992c52730ff2590b4b3903fe737521b9c713170d19b747fa2941c8b1

查看容器的網絡地址,驗證其ip地址是不是咱們自定義的網絡。tcp

[root@linux-node4 ~]# docker inspect ffc47de3992 |grep 192
                    "Gateway": "192.168.100.1",
                    "IPAddress": "192.168.100.2",

注意同一個網橋內的網絡是相互能夠通訊的,本篇不作過多說明。oop

host模式

若是啓動容器的時候使用host模式,那麼這個容器將不會得到一個獨立的Network Namespace,而是和宿主機共用一個 Network Namespace。容器將不會虛擬出本身的網卡,配置本身的 IP 等,而是使用宿主機的 IP 和端口。可是,容器的其餘方面,如文件系統、進程列表等仍是和宿主機隔離的。 Host模式以下圖所示:

驗證步驟以下:

建立一個網絡類型爲host的容器
docker run  -d --net=host --name=my_host1  nginx:1.13.12

由於nginx容器自己的端口號是80,因此咱們直接使用本地的接口來訪問宿主機的ip和端口號。

[root@linux-node4 ~]# !curl
curl http://127.0.0.1:80 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

若是使用這種網絡模式的時候注意不要一個容器啓動多個實例,會引發端口衝突不能起來,這種網絡模型是沒法使用nat轉化的。 host模式有利也有弊,主要包括如下缺點:

  • 容器沒有隔離、獨立的網絡棧:容器由於與宿主機共享網絡而爭搶資源,而且容易崩潰也可能致使主機崩潰,這在生產環境是不容許發生的;
  • 端口資源:docker host上已經使用的端口就不能再使用了 host模式的優勢以下:
  • 能夠直接使用宿主機ip與外界通訊,無需額外進行nat轉換,因爲容器與外部通訊,再也不須要使用bridge等方式轉發或者進行數據包的封裝,性能上有很大優點。

container模式

這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的 IP,而是和一個指定的容器共享 IP、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過 lo 網卡設備通訊。 Container模式示意圖:

咱們仍是經過實驗來驗證這個結論吧,上文咱們已經建立了一個自定義網橋的容器,連接到這個容器裏面便可

[root@linux-node4 ~]#  docker run -d --name docker_con3 --net=container:ffc47de3992c busybox sleep 6000 
933dd7fce1a67883869a6235c3a4f7835c983e079592087734715d05f6bd755e

進入容器內部驗證網絡是否跟預期一致:
[root@linux-node4 ~]# docker exec -it  933dd7fce1a6 sh     
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
33: eth0@if34: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.2/24 brd 192.168.100.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.100.1   0.0.0.0         UG    0      0        0 eth0
192.168.100.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0

None模式

使用none模式,Docker 容器擁有本身的 Network Namespace,可是,並不爲Docker 容器進行任何網絡配置。也就是說,這個 Docker 容器沒有網卡、IP、路由等信息。須要咱們本身爲 Docker 容器添加網卡、配置 IP 等。 None模式示意圖:

[root@linux-node4 ~]#  docker run -d  --net=none  --name docker_none2  busybox  sleep 6000    
247fb9eace8b5dedcb47b7f2015eb06f18d4eb67eb323560dcfaaf7ef1069773
網絡狀況驗證:
[root@linux-node4 ~]# docker exec -it  247fb9eace8b  /bin/sh 
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    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
/ # route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
/ #
相關文章
相關標籤/搜索