虛擬IP
首先思考被隔離的容器進程,該如何跟其他 Network Namespace 裏的容器進程進行通信?
Docker 項目會默認在宿主機上創建一個名叫 docker0 的網橋,凡是連接在 docker0 網橋上的容器,就可以通過它來進行通信。
我們又該如何把這些容器“連接”到 docker0 網橋上呢?這時候,我們就需要使用一種名叫 Veth Pair 的虛擬設備了。
Veth Pair 設備的特點是:它被創建出來後,總是以兩張虛擬網卡(Veth Peer)的形式成對出現的。並且,從其中一個“網卡”發出的數據包,可以直接出現在與它對應的另一張“網卡”上,哪怕這兩個“網卡”在不同的 Network Namespace 裏。
每一個運行的容器的 Veth Pair 設備的一端會在宿主機上。你可以通過查看宿主機的網絡設備看到它。
創建的容器裏也會有一張叫作 eth0 的網卡,它正是一個 Veth Pair 設備在容器裏的這一端。
假設現在創建兩個容器,他們的虛擬ip爲172.17.0.2、172.17.0.3,宿主機的ip爲10.168.0.2
那麼構建的網絡模型如圖所示:
在此基礎上,容器之間的互聯和容器與宿主機之間的互聯是這樣的:
- 宿主機訪問容器:通過虛擬ip
- 容器訪問宿主機:通過宿主機ip
- 容器互相訪問:通過虛擬ip
這種方式有什麼問題?
在容器中的應用代碼對IP做了硬編碼,如果容器重啓,Docker會改變容器的ip地址,則會出錯。
link
運行容器的時候加上參數link
運行第一個容器:
docker run -it --name centos-1 docker.io/centos:latest
運行第二個容器:
docker run -it --name centos-2 --link centos-1:centos-1 docker.io/centos:latest
–link:參數中第一個centos-1是容器名,第二個centos-1是定義的容器別名(使用別名訪問容器),爲了方便使用,一般別名默認容器名。
測試結果如下:
[root@e0841aa13c5b /]# ping centos-1
PING centos-1 (172.17.0.7) 56(84) bytes of data.
64 bytes from centos-1 (172.17.0.7): icmp_seq=1 ttl=64 time=0.210 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=4 ttl=64 time=0.114 ms
此方法對容器創建的順序有要求,如果集羣內部多個容器要互訪,使用就不太方便。
bridge網絡
創建bridge網絡:
docker network create testnet
查詢到新創建的bridge:
docker network ls
運行容器連接到testnet網絡。
使用方法:docker run -it --name <容器名> —network --network-alias <網絡別名> <鏡像名>
docker run -it --name centos-1 --network testnet --network-alias centos-1 docker.io/centos:latest
docker run -it --name centos-2 --network testnet --network-alias centos-2 docker.io/centos:latest
3.從一個容器ping另外一個容器,測試結果如下:
ping centos-1
PING centos-1 (172.20.0.2) 56(84) bytes of data.
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=1 ttl=64 time=0.158 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=4 ttl=64 time=0.113 ms
推薦使用這種方法,自定義網絡,因爲使用的是網絡別名,可以不用顧慮ip是否變動,只要連接到docker內部bright網絡即可互訪。bridge也可以建立多個,隔離在不同的網段。
若訪問容器中服務,可以使用這用方式訪問 <網絡別名>:<服務端口號>。
參考:https://blog.csdn.net/golden_zjy/article/details/100132718