docker 容器之間通信


簡介

我們安裝Docker后,它會自動創建三個網絡,bridge(創建容器默認連接到此網絡)、 none 、host。

  • host:容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。
  • None:該模式關閉了容器的網絡功能,相當於一個回環網絡。
  • Bridge:此模式會為每一個容器分配、設置IP等,並將容器連接到一個叫docker0的虛擬網橋,通過docker0網橋以及Iptables nat表配置與宿主機通信。

關於上述提到的三個網絡解釋如下:

  • Host:相當於Vmware中的橋接模式,與宿主機在同一個網絡中,但沒有獨立的IP地址。眾所周知,Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離進程,Mount Namespace隔離文件系統,Network Namespace隔離網絡等。一個Network Namespace提供了一份獨立的網絡環境,包括網卡、路由、Iptable規則等都與其他的Network Namespace隔離。一個Docker容器一般會分配一個獨立的Network Namespace。但如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。基於Host模式啟動的容器,在容器內執行ifconfig時,看到的都是宿主機上的信息。該模式不夠靈活,容易出現端口沖突問題。
  • None:該模式將容器放置在它自己的網絡棧中,但是並不進行任何配置。實際上,該模式關閉了容器的網絡功能,類似於會換地址,在以下兩種情況下是有用的:容器並不需要網絡(例如只需要寫磁盤卷的批處理任務)。
  • overlay:顧名思義:覆蓋,但它又不是覆蓋,它的作用就是在容器原有的網絡基礎之上,再添加一塊網卡,並為其分配一個IP地址,可以將所有的docker容器關聯到同一個局域網中,適用於容器與容器是跨主機進行通信的場景。
  • Bridge:相當於Vmware中的NAT模式,容器使用獨立的network Namespace,並且連接到docker0虛擬網卡(默認模式)。通過docker網橋以及IPtables nat表配置與宿主機通信;Bridge模式是Docker默認的網絡設置,此模式會為每一個容器分配一個Network nameSpace、設置IP等,並將一個主機上的Docker容器連接到一個虛擬網橋docker0上。

Bridge如圖:

image-20210106154817605

網絡模式使用總結

上面講了關於docker的網絡模式,主要關於以哪種方式讓服務器內部的容器與公網進行通信。

1、假如使用的是默認的橋接網絡模式,啟動容器的時候需要使用參數-p 宿主機端口:容器端口設置端口的映射。

2、假如使用的是host主機模式,因為使用的是宿主機的ip與端口,那就直接可以與公網通信。

相關命令

查看docker創建的網絡

 #執行該命令查看docker創建的網絡
 docker network ls    

創建新網絡

docker network create <network-name>

將容器連接到網絡

docker run --net=<network-name> ...

或者將已存在容器加入新的網絡

docker network connect <network-name> <container-name>

按名稱ping容器

docker exec -ti <container-name-A> ping <container-name-B>

Ps:需要注意的是,如果容器沒有指定名稱(–name),那么就只能用id

啟動容器並指定模式

默認是Bridge

在容器啟動命令時用參數--net=host指定當前容器網絡模式

如:

 docker run -itd --net=host centos:7 /bin/bash

查看容器元信息

docker inspect 容器ID

docker網絡連接命令介紹

docker network connect 命令是用於將docker容器連接到某個網絡中,或者與其他容器建聯,容器可以使用容器名或者容器ID。

用法

docker network connect [OPTIONS] NETWORK CONTAINER

選項

名稱,簡寫 默認 說明
--alias 為容器添加網絡范圍的別名
--ip 指定IP地址
--ip6 指定IPv6地址
--link 添加鏈接到另一個容器
--link-local-ip 添加容器的鏈接本地地址

相關命令

命令名稱 說明
docker network connect 將容器連接到網絡
docker network create 創建一個網絡
docker network disconnect 斷開容器的網絡
docker network inspect 顯示一個或多個網絡的詳細信息
docker network ls 列出網絡
docker network prune 刪除所有未使用的網絡
docker network rm 刪除一個或多個網絡

docker默認Bridge內部通信

在實際的項目環境中,肯定會存在多個服務間通信的情況。也就是多個容器之間通信。

那么該如何通信呢?

它們都是通過默認的bridge進行通信的。

啟動兩個centos7

docker run -itd --name centos1 centos:7

docker run -itd --name centos2 centos:7

查看兩個容器的元信息

主要是看虛擬ip

該命令會返回所有元信息

docker inspect 5c266f40400e

可以使用過濾並一次查詢兩個ip

docker inspect --format '{{ .NetworkSettings.IPAddress }}' 容器id1 容器id2

[root@localhost ~]# docker inspect --format '{{ .NetworkSettings.IPAddress }}' 5c266f40400e 861e6b2f0566
172.18.0.2
172.18.0.3

可以看到兩個容器虛擬ip分別為172.18.0.2 172.18.0.3

宿主機ping容器

[root@localhost ~]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.077 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.054 ms
^C
--- 172.18.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.054/0.070/0.079/0.011 ms
[root@localhost ~]# ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 172.18.0.3: icmp_seq=3 ttl=64 time=0.041 ms
^C
--- 172.18.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.041/0.048/0.053/0.009 ms

可以看到兩個都可以ping通

容器間互ping

開兩個ssh窗口

容器1

#進入容器
docker exec -it 5c266f40400e

[root@5c266f40400e /]# ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.052 ms
^C
--- 172.18.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.052/0.062/0.072/0.010 ms
[root@5c266f40400e /]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.032 ms
^C
--- 172.18.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.032/0.032/0.032/0.000 m

容器2

#進入容器
docker exec -it 861e6b2f0566 /bin/bash

[root@861e6b2f0566 /]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.068 ms
^C
--- 172.18.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.058/0.063/0.068/0.005 ms
[root@861e6b2f0566 /]# ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.022 ms
^C
--- 172.18.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.022/0.027/0.032/0.005 ms

總結

經過上面的測試你會發現宿主機,容器,容器和容器根據虛擬ip連通完全沒有問題

缺點

在docker中容器間直接通過ip進行服務訪問是存在弊端的。假如上面例子中某個centos容器突然掛掉重啟也失敗,只能重新run一個。這時ip可能會發生變化,那就需要進去直接修改相關配置信息,就很不友好。

解決辦法

因此Docker也提供了基於容器名來與其它容器通信。

docker基於容器名通信

容器之間若要通過容器名之間進行網絡通信,需要保證兩個容器在同一交換機下,且是在非默認的名為bridge的交換機下.

所以在創建容器之前,需要新建一個交換機,網絡創建前,可以使用docker network ls查看當前的交換機.。

創建網絡交換機

docker network create myNerwork

image-20210106163649485

啟動兩個容器並指定網絡

docker run -itd --name centos3 --network=myNerwork centos:7
docker run -itd --name centos4 --network=myNerwork centos:7

進入網絡交換機中查看網絡信息

docker network inspect myNerwork

#返回
[
    {
        "Name": "myNerwork",
        "Id": "c4fc8902df6c6343c56fe7966d4454cf0cee43a8ce9c843bbe1613b3232de98f",
        "Created": "2021-01-06T16:35:32.8229922+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "04e723114d3fd9f92b50f37b960db168ffe7eb16302e36b257dcc52a78585caf": {
                "Name": "centos4",
                "EndpointID": "38002e89da4897edf1a27ebf57cf8723950a2e7c0e260c19fb99b8deb66ecc54",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "5f7d789b38691678e0b9f0226b23f9839d9eb2ad4ece436d3e5db9d650ba5e3c": {
                "Name": "centos3",
                "EndpointID": "647a516fa3d579ee2f7031a3e0c06f2c29d50e9ca94696957d5ad5b8a60d6724",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

發現兩個容器都已經在新的網絡中了

測試容器使用容器名互ping

分別進入兩個容器

容器1

docker exec -it 5f7d789b3869 /bin/bash

[root@5f7d789b3869 /]# ping centos4
PING centos4 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos4.myNerwork (172.17.0.3): icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from centos4.myNerwork (172.17.0.3): icmp_seq=2 ttl=64 time=0.091 ms
64 bytes from centos4.myNerwork (172.17.0.3): icmp_seq=3 ttl=64 time=0.050 ms
64 bytes from centos4.myNerwork (172.17.0.3): icmp_seq=4 ttl=64 time=0.065 ms
64 bytes from centos4.myNerwork (172.17.0.3): icmp_seq=5 ttl=64 time=0.048 ms
^C
--- centos4 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.048/0.063/0.091/0.017 ms

沒啥問題

容器2

docker exec -it centos4 /bin/bash

[root@04e723114d3f /]# ping centos3
PING centos3 (172.17.0.2) 56(84) bytes of data.
64 bytes from centos3.myNerwork (172.17.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from centos3.myNerwork (172.17.0.2): icmp_seq=2 ttl=64 time=0.066 ms
64 bytes from centos3.myNerwork (172.17.0.2): icmp_seq=3 ttl=64 time=0.094 ms
64 bytes from centos3.myNerwork (172.17.0.2): icmp_seq=4 ttl=64 time=0.084 ms
^C
--- centos3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.044/0.072/0.094/0.019 ms

沒啥問題


免責聲明!

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



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