Docker網絡概述
1.橋接模式介紹
bridge模式是docker的默認網絡模式。
橋接模式是一種用于連接兩個不同網絡段的設備,使它們能夠共享通信的一種方式。
橋接設備工作在OSI模型的第二層,即數據鏈路層,通常基于MAC地址進行幀轉發。
物理層連接: 橋接設備通常有兩個或多個網絡接口,用于連接不同的物理網絡。
這些接口可以是以太網接口,Wi-Fi接口等。
MAC地址學習: 當橋接設備啟動時,它開始學習連接的網絡上設備的MAC地址。
橋接設備通過觀察網絡流量并記錄源MAC地址來建立MAC地址表。
幀轉發: 當設備發送幀(數據包)時,橋接設備查看目標MAC地址。
如果目標MAC地址在橋接設備的MAC地址表中,它會將幀僅發送到相應接口。
如果目標MAC地址不在表中,橋接設備會將幀發送到所有其他接口
橋接模式在物理和數據鏈路層上工作,通過學習和轉發MAC地址,連接不同的網絡,從而使它們看起來像是一個單一的網絡。這種模式通常用于局域網的擴展和連接。
2.Docker網絡實現原理
橋接模式是一種網絡模式,它在 Docker 中的工作方式可以分為以下幾個步驟:
- 虛擬網絡橋創建: 當您啟動 Docker 守護進程時,Docker 創建一個虛擬網絡橋(通常稱為 docker0),它是一個虛擬的網絡設備,類似于物理網絡設備的交換機。
- 分配唯一的 IP 地址: 每次您運行一個容器時,Docker 分配一個唯一的 IP 地址給該容器。這個 IP 地址是在橋接模式網絡的子網中。
- 連接容器到橋接網絡: 當容器啟動時,Docker 將容器的虛擬網絡接口(veth pair)連接到虛擬網絡橋上。其中一個端點位于容器內,而另一個端點位于主機上。
- 容器與主機通信: 通過橋接模式,容器可以直接與主機通信。這意味著容器可以訪問主機上運行的服務,而主機也可以通過容器的 IP 地址訪問容器內的服務。
- 容器之間的通信: 如果有多個容器在相同的橋接網絡上運行,它們可以通過各自的 IP 地址直接通信。Docker 會自動在橋接網絡上設置路由,使得容器之間可以直接交流。
- NAT(網絡地址轉換): 默認情況下,Docker 使用 Network Address Translation(NAT)技術,將容器的私有 IP 地址映射到主機上的公共 IP 地址。這樣,容器可以與外部網絡通信,而外部網絡看到的是主機的 IP 地址。
Docker網橋是宿主機虛擬出來的,并不是真實存在的網絡設備,外部網絡是無法尋址到的,這也意味著外部網絡無法直接通過 Container-IP 訪問到容器。
如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主主機(端口映射),即 docker run 創建容器時候通過 -p 或 -P 參數來啟用,訪問容器的時候就通過[宿主機IP]:[容器端口]訪問容器。
示例:
docker run -itd --name test1 -P nginx:1.22.0 /bin/bash
#隨機映射端口(從32768開始)docker run -itd --name test2 -p 43000:80 nginx:1.22.0 /bin/bash
#指定映射端口
宿主機端口:主機上用于接收來自外部請求的端口。在這個例子中,它是43000。
容器端口:Docker容器內部正在監聽的端口。在這個例子中,它是80,因為NGINX通常默認監聽80端口。#使用 docker run -p 時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。
可以使用iptables -t nat -vnL 查看。
docker exec -it test1 bash
cd /usr/share/nginx/html/
echo this is test1 > index.html
cd /bin/
nginxdocker exec -it test2 bash
cd /usr/share/nginx/html/
echo this is test2 > index.html
cd /bin/
nginx瀏覽器訪問:
20.0.0.10:32768
20.0.0.10:43000
Docker網絡模式詳解
安裝Docker時,它會自動創建三個網絡,bridge(創建容器默認連接到此網絡)、 none 、host
//查看docker網絡列表
docker network ls
或
docker network listdocker network ls
NETWORK ID NAME DRIVER SCOPE
3dab1f670163 bridge bridge local
4f62ba81b69c host host local
4fef7ef6a38b none null local
-------------------------------------------------------------------------------------------
NAME: 是Docker網絡的名稱。在這里,你列出了三個網絡,它們的名稱分別是bridge、host和none。
NETWORK ID: 每個Docker網絡都有一個唯一的網絡ID。
DRIVER: 這是Docker使用的網絡驅動程序。在這里,bridge表示使用的是橋接網絡,host表示使用的是主機網絡,而none表示沒有網絡。
SCOPE: 表示網絡的作用范圍。local表示該網絡僅在本地主機上可用。
-------------------------------------------------------------------------------------------//使用docker run創建Docker容器時,可以用 --net 或 --network 選項指定容器的網絡模式
host模式:使用 --net=host 指定。
none模式:使用 --net=none 指定。
container模式:使用 --net=container:NAME_or_ID 指定。
bridge模式:使用 --net=bridge 指定,默認設置,可省略。
1.Host
主機模式:
容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。
在主機模式下,容器與主機共享同一個網絡命名空間,直接使用主機的網絡棧。
這使得容器可以使用主機的 IP 地址和端口,從而不需要進行額外的端口映射。
docker run -itd --name test1 --network host nginx /bin/bash
docker exec -it test1 bashroot@pup1:/bin# cd /usr/share/nginx/html/
root@pup1:/usr/share/nginx/html# echo this is nginx > index.html cd /bin/
root@pup1:/bin# nginx
#開啟容器nginx服務時需要關閉宿主機的nginx服務,防止端口沖突瀏覽器訪問本機地址:20.0.0.10
2.Container
這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。?
新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過lo網卡設備通信。
docker run -itd --name test2 --net=container:test1 nginx /bin/bash
docker exec -it test2 bashcd /usr/share/nginx/html/
echo this is nginx2 > index.html
nginx#需要先關閉容器test1的nginx服務
exec -it test1 bash
nginx -s stop瀏覽器訪問本機地址:
20.0.0.10
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8daac0b47a21 nginx "/docker-entrypoint.…" 13 minutes ago Up 13 minutes test2
08f7a9d0ddc9 nginx "/docker-entrypoint.…" 59 minutes ago Up 59 minutes test1docker inspect -f '{{.State.Pid}}' 8daac0b47a21
47563ls -l /proc/47563/ns
#查看可以發現兩個容器的 net namespace 編號相同
3.None
該模式關閉了容器的網絡功能。
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。?也就是說,這個Docker容器沒有網卡、IP、路由等信息。
這種網絡模式下容器只有lo回環網絡,沒有其他網卡。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性。
docker run -itd --name test3 --net=none nginx /bin/bash
docker exec -it test3 bash
nginxcd /usr/share/nginx/html/
echo this is nginx3 > index.htmlcd /etc
cat hosts
curl 127.0.0.1
?
4.Bridge
默認為該模式,此模式會為每一個容器分配、設置IP等,并將容器連接到一個docker0虛擬網橋,
通過docker0網橋以及iptables nat 表配置與宿主機通信。
5.自定義網絡
直接使用bridge模式,是無法支持指定IP運行docker的,例如執行以下命令就會報錯:
docker run -itd --name test3 --network bridge --ip 172.17.0.10 nginx:latest /bin/bash
//創建自定義網絡
#可以先自定義網絡,再使用指定IP運行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
-------------------------------------------------------------------------------------------
#docker1 為執行 ifconfig -a 命令時,顯示的網卡名,如果不使用 --opt 參數指定此名稱,
那你在使用 ifconfig -a 命令查看網絡信息時,看到的是類似 br-110eb56a0b22 這樣的名字,這顯然不怎么好記。#mynetwork 為執行 docker network list 命令時,顯示的bridge網絡模式名稱。
-------------------------------------------------------------------------------------------
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 nginx:latest /bin/bash進入虛擬機訪問172.18.0.10
補充
查看容器的輸出和日志信息
docker logs 容器的ID/名稱
#創建容器時不加/bin/bash