docker爲容器創建獨立的網絡環境,實現宿主和容器、容器之間的網絡隔離,默認使用bridge模式的網絡,實現容器之間、容器與宿主機之間、乃至與外界之間 的網絡通信。
但是我們在實際部署應用的時候,發現並不能直接通過容器內部端口訪問另外一個容器的應用(比如:mysql容器端口是3306,web應用不能直接通過3306訪問mysql),而是通過端口映射到宿主機器來實現容器之間的訪問。
那麼有什麼方式能實現直接通過容器內部端口進行數據通訊呢?那就是通過network方式。
docker network創建一個橋接網絡,在docker run的時候將容器指定到新創建的橋接網絡中,這樣同一橋接網絡中的容器就可以通過互相訪問。
1、創建network
[root@iZbp13sno1lc2yxlhjc4b3Z ~]# docker network create my-network
[root@iZbp13sno1lc2yxlhjc4b3Z ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e4de24aaf1c2 bridge bridge local
093caaca12b4 host host local
a2b05d7d591a my-network bridge local
6e6497f8e311 none null local
[root@iZbp13sno1lc2yxlhjc4b3Z ~]#
可以看到my-network已經創建好,另外其他3個是docker默認創建的。
2、創建容器時指定網絡
在創建容器時指定使用my-network網絡,並設置網絡別名。
docker run -itd --name mysql --network my-network --network-alias mysql -e MYSQL_ROOT_PASSWORD=root mysql:5.7.24
–network 指定使用的網絡
–network-alias 設置網絡別名
如果容器已創建好但是之前沒有指定自己的網絡,則使用下面命令修改:
docker network connect --alias mysql my-network mysql
第一個mysql是網絡別名 第二個mysql是容器名
3、通過網絡別名測試訪問
進入web容器,使用ping命令測試
[root@iZbp13sno1lc2yxlhjc4b3Z ~]# docker exec -it tomcat_kq bash
root@161eee53356c:/usr/local/tomcat# ping mysql
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.my-network (172.18.0.2): icmp_seq=1 ttl=64 time=0.049 ms
可以看到通過mysql網絡別名可以直接訪問。
另外通過容器id或者主機名也是可以訪問的。但是你不加入這個自定義網絡,則沒法訪問。這個在項目實際應用中非常重要,特別是通過主機名識別服務的項目,如springcoud項目
4、項目實際應用
修改web項目訪問mysql的數據庫地址,由ip改爲網絡別名,端口爲容器內部端口:
jdbc:mysql://mysql:3306/kaoqin?allowMultiQueries=true
注意:mysql是前面設置的網絡別名,3306是容器內部端口
這裏特別提一下springcloud項目,eureka中心一般是通過主機名來中註冊發現服務的,但是一放到docker容器中,springboot應用就報錯,提示不能發送心跳到註冊中心,就是因爲容器中間的網絡隔離造成的,通過把所有容器加入到自定義網絡就能解決此問題。