Docker中的容器網(wǎng)絡(luò)和通信原理詳解
Docker 容器網(wǎng)絡(luò)和通信原理
1. Docker 默認(rèn)的網(wǎng)絡(luò)模型
Docker Host : 安裝了 docker deamon 的主機(jī)
docker0 : 安裝了 docker 之后出現(xiàn)的網(wǎng)橋
- 通過網(wǎng)橋可以將 Linux 支持的不同的端口連接起來
- 實(shí)現(xiàn)類交換機(jī)多對多的通信
veth pair
- 虛擬以太網(wǎng)(Ethernet)設(shè)備
- 成對出現(xiàn),用于解決網(wǎng)絡(luò)命名空間之間的隔離
- 一端連接 Container network namespace,另一端連接 host network namespace
當(dāng)創(chuàng)建了一個容器之后 , 會在主機(jī)中創(chuàng)建一個虛擬的以太網(wǎng)設(shè)備 ( veth )
一端連接主機(jī)的網(wǎng)絡(luò)的命名空間
一端連接容器的網(wǎng)絡(luò)命名空間
啟動一個容器,查看容器的網(wǎng)絡(luò)設(shè)備
docker run -it centos:latest bash
可以看到容器有自己的網(wǎng)絡(luò)設(shè)備,這是連接容器網(wǎng)絡(luò)命名空間的一端
按住ctrl+p+q
退回容器,使容器在后臺運(yùn)行
這個虛擬的網(wǎng)絡(luò)設(shè)備就是連接 docker host 網(wǎng)絡(luò)命名空間的
2. Docker 網(wǎng)絡(luò)模型工作原理
2.1. 容器訪問外網(wǎng)
容器中的數(shù)據(jù)包轉(zhuǎn)發(fā)給 eth0 網(wǎng)卡,然后在轉(zhuǎn)發(fā)到 docker host 命名空間的虛擬網(wǎng)絡(luò)設(shè)備,虛擬的網(wǎng)絡(luò)設(shè)備會把數(shù)據(jù)傳給 docker0, 然后再轉(zhuǎn)發(fā)給 eth0 ( 物理網(wǎng)卡 ),
SNAT 源地址轉(zhuǎn)換:把 docker0 的源地址轉(zhuǎn)換成 docker host 主機(jī)所在網(wǎng)段的 IP 地址
iptables -t nat -vnL POSTROUTING
MASQUERADE 就是 SNAT ,底層轉(zhuǎn)發(fā)是由 iptables 來承載的
2.2 外網(wǎng)訪問容器
首先外網(wǎng)的數(shù)據(jù)包能夠傳送到 eth0 網(wǎng)卡,內(nèi)核接收到數(shù)據(jù)之后會進(jìn)行 DNAT (目標(biāo)地址轉(zhuǎn)換)
所以容器的 port 就是: 但訪問宿主主機(jī)的 3306 端口,會被轉(zhuǎn)發(fā)到容器的某個端口
可以通過 iptables 看到 docker 鏈
iptables -t nat -nL
不管哪個 IP , 不管目標(biāo)地址是哪個,只要訪問對應(yīng)端口,就轉(zhuǎn)換到 172.17… 的對應(yīng)端口
3. Docker 四種網(wǎng)絡(luò)模型
- bridge [ 橋接式網(wǎng)絡(luò) ( Bridge container A ) ]:–network bridge(默認(rèn)網(wǎng)絡(luò)模型)
橋接容器,除了有一塊本地回環(huán)接口 ( Loopback interface ) 外,還有一塊私有接口 ( Private interface ) 通過容器虛擬接口 ( Container virtual interface ) 連接到橋接虛擬接口 ( Docker bridge virtual interface ),之后通過邏輯主機(jī)接口 ( Logical host interface ) 連接到主機(jī)物理網(wǎng)絡(luò) ( Physical network interface )。橋接網(wǎng)卡默認(rèn)會分配到 172.17.0.0/16 的IP地址段。如果我們在創(chuàng)建容器時沒有指定網(wǎng)絡(luò)模型,默認(rèn)就是 ( Nat ) 橋接網(wǎng)絡(luò),這也就是為什么我們在登錄到一個容器后,發(fā)現(xiàn) IP 地址段都在 172.17.0.0/16 網(wǎng)段的原因。
容器通過虛擬以太網(wǎng)設(shè)備連接到主機(jī)的網(wǎng)絡(luò)命名空間,通過主機(jī)的命名空間實(shí)現(xiàn)對外網(wǎng)的訪問
- host [ 開放式容器 ( Open container ) ]:–network host
比聯(lián)盟式網(wǎng)絡(luò)更開放,聯(lián)盟式網(wǎng)絡(luò)是多個容器共享網(wǎng)絡(luò) ( Net ) , 而開放式容器 ( Open contaner ) 就直接共享了宿主機(jī)的名稱空間。因此物理網(wǎng)卡有多少個,那么該容器就能看到多少網(wǎng)卡信息。我們可以說 Open container 是聯(lián)盟式容器的衍生。
讓容器和主鍵共享同一個網(wǎng)絡(luò)命名空間,容器中的 IP 地址和 Docker host IP 地址是完全一直的,有利于對容器服務(wù)的訪問
- none [封閉式網(wǎng)絡(luò)(Closed container)]:–network none
封閉式容器,只有本地回環(huán)接口 ( Loopback interface ) ,和服務(wù)器看到的 lo 接口類似),無法與外界進(jìn)行通信。
這種網(wǎng)絡(luò)模式中只有 Loopback 這種網(wǎng)路接口,不能去連接外網(wǎng)
- container [聯(lián)盟式網(wǎng)絡(luò) ( Joined container A | Joined container B ]:–network container:c1(容器名稱或容器ID)
每個容器都各有一部分名稱空間 ( Mount , PID , User ),另外一部分名稱空間是共享的( UTS , Net , IPC ) 。由于它們的網(wǎng)絡(luò)是共享的,因此各個容器可以通過本地回環(huán)接口 ( Loopback interface ) 進(jìn)行通信。除了共享同一組本地回環(huán)接口 ( Loopback interface ) 外,還有一塊一塊私有接口 ( Private interface ) 通過聯(lián)合容器虛擬接口 ( Joined container virtual interface )連接到橋接虛擬接口 ( Docker bridge virtual interface ),之后通過邏輯主機(jī)接口 ( Logical host interface ) 連接到主機(jī)物理網(wǎng)絡(luò) ( Physical network interface )。
可以共享兩個容器的命名空間
4. 查看指定類型的網(wǎng)絡(luò)模型
4.1 查看所有容器的網(wǎng)絡(luò)模型
# 查看已有的網(wǎng)絡(luò)模型 docker network ls docker netword list
4.2 查看指定網(wǎng)絡(luò)模型的詳細(xì)信息
root@VM-8-13-debian:~# docker network inspect bridge [ { "Name": "bridge", "Id": "6e7985ab54cdd0f9143da410b03f5e0df82146d3e0256fee573e6d3c64de4df5", "Created": "2023-10-12T18:42:05.876320519+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { # 子網(wǎng)和網(wǎng)關(guān) "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, # 哪些容器連接到了這個網(wǎng)絡(luò) "Containers": { "420df0739e938ad67819430697329aa0cd0b9dc83be296995bfdf3a90b74b6e7": { "Name": "etcd", "EndpointID": "52e9e6d2601301c87c5dcaa2d8cfd47e2da9317692d2572e201207e98ca03a3c", # 容器的IP地址和MAC地址 "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "e01f2b3407cb1962b15630623e7d4ecd1ac2e40e256e3d2d87390dd31ef38985": { "Name": "quizzical_nobel", "EndpointID": "560ab4c4cf83a011fdeec12e2ac3e3b0c4252a7cb81a5ae115067ba82eea9dfb", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" } }, # 默認(rèn)選項(xiàng) "Options": { # 是不是默認(rèn)網(wǎng)橋 "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", # 是否開啟上網(wǎng)功能(源地址轉(zhuǎn)換 SNAT) "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": {} } ]
4.3 查看 docker 支持的網(wǎng)絡(luò)模型
root@VM-8-13-debian:~# docker info | grep Network Network: bridge host ipvlan macvlan null overlay
5. 創(chuàng)建指定類型的網(wǎng)絡(luò)模型
5.1 bridge
- 查看幫助
docker network create -h
- 創(chuàng)建網(wǎng)絡(luò)模型
# 1.簡單寫法 docker network create Mysql # 2.復(fù)雜寫法 docker network create -d bridge --subnet "192.168.100.0/24" --gateway "192.168.100.1" -o com.docker.network.bridge.name=docker1 Mysql # com.docker.network.bridge.name 就是上面查看網(wǎng)絡(luò)模型選項(xiàng)信息里面的內(nèi)容
- 驗(yàn)證是否創(chuàng)建成功
root@VM-8-13-debian:~# docker network ls NETWORK ID NAME DRIVER SCOPE b14e183c0386 1panel-network bridge local 136c9c1912fc Mysql bridge local d60f5e7ed7e9 backend_default bridge local 6e7985ab54cd bridge bridge local affe2ac83252 host host local 20037e8c62b7 kafka_default bridge local df9f2ca51637 logs_default bridge local aeecc2524ba4 none null local # 同時也可以使用 docker network inspect Mysql查看詳細(xì)信息
- 啟動一個容器連接到創(chuàng)建的網(wǎng)絡(luò)
# docker run -it --network Mysql busybox / # ping wwww.baidu.com PING wwww.baidu.com (110.242.68.66): 56 data bytes 64 bytes from 110.242.68.66: seq=0 ttl=250 time=10.616 ms 64 bytes from 110.242.68.66: seq=1 ttl=250 time=10.601 ms 64 bytes from 110.242.68.66: seq=2 ttl=250 time=10.595 ms --- wwww.baidu.com ping statistics --- 11 packets transmitted, 11 packets received, 0% packet loss round-trip min/avg/max = 10.589/10.612/10.628 ms
可以看出是可以正常 ping 通的
5.2 host
docker run -it --network host --rm busybox # 啟動Nginx 服務(wù) docker run -d --network host nginx:latest
# 查看容器運(yùn)行狀態(tài) # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6677b213271 nginx:latest "/docker-entrypoint.…" 7 seconds ago Up 6 seconds youthful_shtern
# 查看docker host 80端口狀態(tài) # ss -anput | grep ":80" tcp LISTEN 0 511 *:80 *:* users:(("nginx",pid=42866,fd=7),("nginx",pid=42826,fd=7)) tcp LISTEN 0 511 :::80 :::* users:(("nginx",pid=42866,fd=8),("nginx",pid=42826,fd=8))
host 網(wǎng)絡(luò)模型用的是和宿主主機(jī)同一個命名空間
缺點(diǎn): 無法啟動第二個這樣的容器 ( 端口很稀缺 )
5.3 none
root@VM-8-13-debian:~# docker run -it --network none busybox / # ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
可以看到是沒有網(wǎng)絡(luò)的,如果連接了只能在本地做一下測試
如果需要有更多的網(wǎng)絡(luò),可以創(chuàng)建虛擬的網(wǎng)絡(luò)設(shè)備
5.4 聯(lián)盟網(wǎng)絡(luò)
- 創(chuàng)建c1容器,使用默認(rèn)網(wǎng)絡(luò)模型
root@VM-8-13-debian:~# docker run -it --name c1 --rm busybox:latest / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
- 創(chuàng)建 c2 容器,與 c1 容器共享網(wǎng)絡(luò)命名空間
root@VM-8-13-debian:~# docker run -it --name c2 --network container:c1 --rm busybox:latest root@VM-8-13-debian:~# docker run -it --name c2 --network container:c1 --rm busybox:latest / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:11 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:866 (866.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
可以看到兩者的虛擬網(wǎng)卡一模一樣
# 在c2容器中創(chuàng)建文件并開啟httpd服務(wù) echo "hello world" >> /tmp/index.html ls /tmp index.html httpd -h /tmp # 驗(yàn)證80端口是否打開 / # netstat -npl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 :::80 :::* LISTEN 10/httpd # 在c1容器中進(jìn)行訪問驗(yàn)證 docker exec c1 wget -O - -q 127.0.0.1 hello world
網(wǎng)絡(luò)共享,文件系統(tǒng) 獨(dú)立
6. 跨 Docker Host 容器間通信實(shí)現(xiàn)
也就是一臺主機(jī)中的 docker 容器和另一臺主機(jī)中的 docker 容器在不使用 host 網(wǎng)絡(luò)模型的情況下如何通信
這個之后有時間我再慢慢寫
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker系列學(xué)習(xí)之Swarm mode管理節(jié)點(diǎn)常用命令詳解
這篇文章主要為大家介紹了Docker系列學(xué)習(xí)之Swarm mode管理節(jié)點(diǎn)常用命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10CentOS 7安裝Docker服務(wù)詳細(xì)過程
這篇文章主要為大家介紹了CentOS 7安裝Docker服務(wù)詳細(xì)過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11docker搭建minio集群的實(shí)現(xiàn)示例
Docker MinIO集群是一種基于Docker的MinIO分布式存儲解決方案,本文主要介紹了docker搭建minio集群的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-12-12利用?trap?在?docker?容器優(yōu)雅關(guān)閉前執(zhí)行環(huán)境清理的方案
這篇文章主要介紹了利用?trap?在?docker?容器優(yōu)雅關(guān)閉前執(zhí)行環(huán)境清理的問題,需要在容器的啟動腳本中,加入 trap 指令,來完成容器在退出前需要做的所有事情,本文通過腳本示例給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-12-12使用Docker?Compose搭建部署ElasticSearch的配置過程
Elasticsearch使用的是一種名為倒排索引的數(shù)據(jù)結(jié)構(gòu),這一結(jié)構(gòu)的設(shè)計(jì)可以允許十分快速地進(jìn)行全文本搜索,本文重點(diǎn)給大家介紹使用Docker?Compose搭建部署ElasticSearch的配置過程,感興趣的朋友一起看看吧2022-02-02使用Dockerfile實(shí)現(xiàn)容器內(nèi)部服務(wù)隨容器自啟動的方法
這篇文章主要介紹了使用Dockerfile實(shí)現(xiàn)容器內(nèi)部服務(wù)隨容器自啟動,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06