Docker網(wǎng)絡(luò)模型以及容器通信詳解續(xù)篇
本篇接著上篇:【Docker0網(wǎng)絡(luò)及原理探究】,繼續(xù)深入探究容器網(wǎng)絡(luò)通信原理,通過學(xué)習(xí)Docker網(wǎng)路驅(qū)動(dòng)模型,更好地解決容器間的通信問題????
1、Docker的網(wǎng)絡(luò)驅(qū)動(dòng)模型
1.1、Docker的網(wǎng)絡(luò)驅(qū)動(dòng)模型分類:
- bridge:Docker中默認(rèn)的網(wǎng)絡(luò)驅(qū)動(dòng)模型,在啟動(dòng)容器時(shí)如果不指定則默認(rèn)為此驅(qū)動(dòng)類型;
- host:打破Docker容器與宿主機(jī)之間的網(wǎng)絡(luò)隔離,直接使用宿主機(jī)的網(wǎng)絡(luò)環(huán)境,該模型僅適用于Docker17.6及以上版本;
- overlay:可以連接多個(gè)docker守護(hù)進(jìn)程或者滿足集群服務(wù)之間的通信;適用于不同宿主機(jī)上的docker容器之間的通信;
- macvlan:可以為docker容器分配MAC地址,使其像真實(shí)的物理機(jī)一樣運(yùn)行;
- none:即禁用了網(wǎng)絡(luò)驅(qū)動(dòng),需要自己手動(dòng)自定義網(wǎng)絡(luò)驅(qū)動(dòng)配置;
- plugins:使用第三方網(wǎng)絡(luò)驅(qū)動(dòng)插件;
1.2、Docker網(wǎng)絡(luò)模式
查看docker網(wǎng)絡(luò) docker network ls
[root@--- ~]# docker network ls NETWORK ID NAME DRIVER SCOPE feafa30d4051 bridge bridge local e8bf4fced9e2 host host local 6263db0933b9 none null local [root@--- ~]#
Docker內(nèi)置這三個(gè)網(wǎng)絡(luò),運(yùn)行容器時(shí),你可以使用該--network
標(biāo)志來指定容器應(yīng)連接到哪些網(wǎng)絡(luò)。
該bridge
網(wǎng)絡(luò)代表docker0
所有Docker安裝中存在的網(wǎng)絡(luò)。除非你使用docker run --network=<NETWORK>
選項(xiàng)指定,否則Docker守護(hù)程序默認(rèn)將容器連接到此網(wǎng)絡(luò)。
我們?cè)谑褂?code>docker run創(chuàng)建Docker容器時(shí),可以用 --net
選項(xiàng)指定容器的網(wǎng)絡(luò)模式,Docker可以有以下4種網(wǎng)絡(luò)模式:
host模式
:使用--net=host
指定。none模式
:使用--net=none
指定。bridge模式
:使用--net=bridge
指定,默認(rèn)設(shè)置。container模式
:使用--net=container:NAME_or_ID
指定。
docker run -it -P --name tomcat01 --net=bridge tomcat # 默認(rèn)設(shè)置 docker run -it -P --name tomcat02 --net=none tomcat # ...
2、容器通信問題
- 由于不同容器通過
veth pair
連接在虛擬網(wǎng)橋docker0
上,所以容器之間可以通過IP
互相通信,但是無法通過容器名進(jìn)行通信。docker0不支持容器名連接訪問 - 默認(rèn)網(wǎng)橋
bridge
上的容器只能通過IP互連,無法通過DNS
解析名稱或別名。假如我們?cè)赾ontainer1中部署了Web服務(wù),在container2中部署了mysql,container1中的Web服務(wù)往往需要連接container2的mysql,這是只能靠IP進(jìn)行連接,但是docker也無法保證容器重啟后的IP地址不變,所以更好的方式是通過別名進(jìn)行互聯(lián),在網(wǎng)絡(luò)中加入DNS服務(wù)器,將容器名與IP地址進(jìn)行匹配,省去了手動(dòng)修改Web服務(wù)中連接mysql的IP的過程。
為了實(shí)現(xiàn)不同容器通過容器名或別名的互連,docker提供了以下幾種:??
- 在啟動(dòng)docker容器時(shí)加入
--link
參數(shù),但是目前已經(jīng)被廢棄,廢棄的主要原因是需要在連接的兩個(gè)容器上都創(chuàng)建--link選項(xiàng),當(dāng)互連的容器數(shù)量較多時(shí),操作的復(fù)雜度會(huì)顯著增加; - 啟動(dòng)docker容器后進(jìn)入容器并修改
/etc/hosts
配置文件(本地DNS解析),缺點(diǎn)是手動(dòng)配置較為繁雜; - 用戶自定義bridge網(wǎng)橋,這是目前解決此類問題的主要方法,提供更好的隔離效果和更好的互通性(更好的隔離效果是針對(duì)外界網(wǎng)絡(luò),而更好的互通性則是指同一
bridge
下的不同容器之間),用戶自定義bridge在容器之間提供了自動(dòng)DNS解析。
容器在默認(rèn)情況下以隔離方式運(yùn)行,它們完全不知道同一計(jì)算機(jī)上有其他進(jìn)程或容器。 那么,如何使容器能夠彼此通信? 答案就是網(wǎng)絡(luò)連接。 如果兩個(gè)容器在同一網(wǎng)絡(luò)上,那么它們可彼此通信。 如果沒在同一網(wǎng)絡(luò)上,則沒法通信。
3、容器之間通信的主要方式總結(jié)
3.1、通過容器ip訪問
容器重啟后,ip會(huì)發(fā)生變化。通過容器ip訪問不是一個(gè)好的方案。
3.2、通過宿主機(jī)的ip:port訪問
通過宿主機(jī)的ip:port
訪問,只能依靠監(jiān)聽在暴露出的端口的進(jìn)程來進(jìn)行有限的通信。
3.3、通過--link
建立連接(官方不推薦使用)
原理分析:
- 運(yùn)行容器時(shí),指定參數(shù)link,使得源容器與被鏈接的容器可以進(jìn)行相互通信,并且接受的容器可以獲得源容器的一些數(shù)據(jù),比如:環(huán)境變量。
- 與
/etc/hosts
中的主機(jī)條目不同,如果重新啟動(dòng)源容器,則不會(huì)自動(dòng)更新存儲(chǔ)在環(huán)境變量中的IP地址。我們建議使用主機(jī)條目/etc/hosts
來解析鏈接容器的IP地址。 - 除了環(huán)境變量之外,Docker還將源容器的主機(jī)條目添加到
/etc/hosts
文件中。(本質(zhì)上就是通過--link
參數(shù),自動(dòng)的給容器添加hosts
配置)
--link
建立連接步驟:?
啟動(dòng)tomcat01,tomcat02
docker run -it -P --name tomcat01 tomcat docker run -it -P --name tomcat02 tomcat
--link
通過配置/etc/hosts
實(shí)現(xiàn)連接通過
link
建立連接的容器,被鏈接的容器能 ping 通源容器,反過來不行。被鏈接容器會(huì)繼承源容器的環(huán)境變量信息
建立link
連接
tomcat02
容器 link 到 tomcat03
上
docker run -it -P --name tomcat03 --link tomcat02 tomcat
查看tomcat03 hosts配置
[root@--- ~]# docker exec -it tomcat03 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat02 099602f3ff7f #?--link命令配置生成的條目? 172.17.0.4 a20a10b7e728 [root@--- ~]#
3.4、??通過 User-defined networks(推薦)
用戶自定義網(wǎng)橋步驟:?
創(chuàng)建用戶自定義bridge網(wǎng)橋
[root@--- ~]# docker network create test-network 799426d70aa28b73b4a777c85b338186eafadd1558b13c43e07a9fd9a8b545e7 [root@iZm5e23n3ueobwkjtfartxZ ~]# docker network ls NETWORK ID NAME DRIVER SCOPE feafa30d4051 bridge bridge local e8bf4fced9e2 host host local 6263db0933b9 none null local 799426d70aa2 test-network bridge local #?創(chuàng)建的橋接網(wǎng)絡(luò)?
刪除網(wǎng)橋:
docker network rm test-network
把之前啟動(dòng)的 mysql01,centos01,centos02 容器加入到自定義bridge網(wǎng)橋中: connect
docker network connect test-network mysql01 docker network connect test-network centos01 docker network connect test-network centos02
查看自定義bridge網(wǎng)橋信息
docker network inspect 799426d70aa2 [ { "Name": "test-network", "Id": "799426d70aa28b73b4a777c85b338186eafadd1558b13c43e07a9fd9a8b545e7", "Created": "2021-10-03T20:30:03.325679562+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", #?test-network的子網(wǎng)? "Gateway": "172.18.0.1" #?test-network的網(wǎng)關(guān)? } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "29298987c51b777b546bf6626560020ce235e390e1d7fcfe188c6db228ca4edf": { "Name": "mysql01", "EndpointID": "a69560a1872a25af042c74132df5dcade6e0e93faf9102185c1de19f6c8b3b36", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", #?mysql01 容器的IP,與之前不同? "IPv6Address": "" }, "cb1922b95b9316d129b54f3545fad9729092926e10a1d5517f8928db42706151": { "Name": "centos01", "EndpointID": "f0cf5feb77ec23526fe5cee217dba9271125b9b4106c81bc7d58253ac48a4caf", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", #?centos01 容器的IP,與之前不同? "IPv6Address": "" }, "cc6f510b9765ba018dbafd416c9774ddf5fd3ff55fa992827f55516e8dc70b6a": { "Name": "centos02", "EndpointID": "6c88540d719014e441d3119c4388e62d311b07acf009106e16aa66d7ebaf5763", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", #?centos02 容器的IP,與之前不同? "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
通過容器名或別名互連通信
進(jìn)入centos01容器,ping centos02
, ping mysql01
可以發(fā)現(xiàn)centos01可以和centos02、mysql01容器之間可以通信
docker exec -it cb1922b95b93 /bin/bash?? [root@cb1922b95b93 /]# ping centos02?? PING centos02 (172.18.0.4) 56(84) bytes of data. 64 bytes from centos02.test-network (172.18.0.4): icmp_seq=1 ttl=64 time=0.118 ms 64 bytes from centos02.test-network (172.18.0.4): icmp_seq=2 ttl=64 time=0.113 ms ... ping mysql01?? PING mysql01 (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql01.test-network (172.18.0.2): icmp_seq=1 ttl=64 time=0.107 ms 64 bytes from mysql01.test-network (172.18.0.2): icmp_seq=2 ttl=64 time=0.103 ms ...
斷開網(wǎng)絡(luò)
由于我們的容器仍然連接著默認(rèn)bridge網(wǎng)橋docker0,而現(xiàn)在我們已經(jīng)不需要它,所以應(yīng)該將容器與docker0的連接斷開,執(zhí)行以下操作disconnect
:
docker network disconnect bridge mysql01 docker network disconnect bridge centos01 docker network disconnect bridge centos02
查看默認(rèn)bridge網(wǎng)橋docker0的容器網(wǎng)絡(luò)配置
docker network inspect feafa30d4051?? [ { "Name": "bridge", "Id": "feafa30d4051f24353508959bd420fd163ad0c98d6b30ec8ff13b59a59552bb1", "Created": "2021-09-26T15:10:27.167774553+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": {}, #?之前的容器服務(wù),已經(jīng)從默認(rèn)網(wǎng)橋中移除? "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": {} } ]
最后
了解了Docker網(wǎng)絡(luò)、容器通信之后,對(duì)繼續(xù)學(xué)習(xí)服務(wù)網(wǎng)格(Service Mesh
)與Kubernetes
的服務(wù)發(fā)現(xiàn)有很大幫助。很多的項(xiàng)目架構(gòu)也都是從網(wǎng)絡(luò)通信角度進(jìn)行的層級(jí)、模塊劃分(比如:網(wǎng)路拓?fù)鋱D、終極系統(tǒng)架構(gòu)異地多活)。關(guān)于網(wǎng)絡(luò),學(xué)完之后你會(huì)發(fā)現(xiàn)很多東西都串一塊了,超級(jí)有意思??
到此這篇關(guān)于Docker網(wǎng)絡(luò)模型以及容器通信詳解續(xù)篇的文章就介紹到這了,更多相關(guān)Docker網(wǎng)絡(luò)模型以及容器通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用docker環(huán)境變量動(dòng)態(tài)配置nginx的問題小結(jié)
這篇文章主要介紹了使用docker環(huán)境變量動(dòng)態(tài)配置nginx,整個(gè)方案,采用的是通過docker run -e xxxx=xxx先往容器注入環(huán)境變量,然后進(jìn)一步通過envsubst指令將環(huán)境變量寫入到具體的文件當(dāng)中,實(shí)現(xiàn)動(dòng)態(tài)配置文件內(nèi)容,需要的朋友可以參考下2022-06-06Docker?Compose+Nestjs構(gòu)建Dapr?Redis發(fā)布訂閱分布式應(yīng)用
這篇文章主要為大家介紹了Docker?Compose+Nestjs構(gòu)建Dapr?Redis發(fā)布訂閱分布式應(yīng)用步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08docker部署訪問postgres數(shù)據(jù)庫的實(shí)現(xiàn)方法
本文主要介紹了docker部署訪問postgres數(shù)據(jù)庫的實(shí)現(xiàn)方法,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03docker搭建odoo16開發(fā)環(huán)境的實(shí)現(xiàn)
Odoo是全球流行的開源企業(yè)管理套件,本文主要介紹了docker搭建odoo16開發(fā)環(huán)境的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04基于Dockerfile創(chuàng)建zabbix監(jiān)控體系代碼實(shí)例
這篇文章主要介紹了基于Dockerfile創(chuàng)建zabbix監(jiān)控體系代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05