深入理解 Docker 網路設置:Bridge 模式原理與實現
在使用 Docker 建立容器並指定網路為 Bridge 模式時,Docker 使用了多項技術來實現容器與Host的網路通信。以下將深入探討這些技術的原理以及如何實現,幫助大家更好地理解 Docker 網路設置。
使用 Veth Pair 實現容器與Host的通信
Docker 在建立容器時使用了 veth pair 技術。這是一種在容器的 Network Namespace 和Host之間建立虛擬網路介面的方法。其中一端連接到容器的 Network Namespace 中,另一端連接到Host的 docker0 介面(虛擬交換機),從而實現容器與 Host 的網路通信。
bash# Docker 在安裝過程中會建立一個 docker0 的網路介面 ip link add docker0 type bridge # 設定作為 Network Namespace 與Host通訊的 Gateway IP ip addr add 172.17.0.1/16 dev docker0
做完以上的動作後,會生成 172.17.0.0/16 的網路環境,接下來 Docker 會執行以下的動作,將容器的網路與 Host 間的網路通道給建立起來:
1. 創建 Veth Pair:bash# Docker 在安裝過程中會建立一個 docker0 的網路介面 ip link add eth0@if? type veth peer name veth????@if?
其中,eth0@if? 是容器內的網路介面名稱,veth????@if? 則是連接到 Host 的虛擬交換機(docker0)的介面名稱。(? 是一串隨機字元)
2. 將網路介面(eth0@if?)加入容器的 Network Namespace 中:
baship link set eth0@if? netns ${CONTAINER-NAMESPACE}
baship link set veth????@if? master docker0
4. 在容器的 Network Namespace 中,為 eth0@if? 介面設置 IP 地址:
baship -n ${CONTAINER-NAMESPACE} \ addr add 172.17.0.2 dev eth0@if?
設置容器的 Default Gateway
容器需要知道如何將封包發送到Host,從而實現與外部網路的通信。為了實現這一點,我們需要為容器設置 Default Gateway。
baship netns exec ${CONTAINER-NAMESPACE} \ ip route add default via 172.17.0.1
透過 NAT 實現外部通信
要實現容器與外部通信,需要透過 NAT(Network Address Translation)來修改封包的來源 IP 地址,以便讓它們看起來像是由 Host 發送的。在上圖這個例子中,容器的網路網段是 172.17.0.0/16,而 Host 的 eth0 實際 IP 是 10.88.0.4/24,這兩個網段是不同的。當容器發送封包到外部時,將會透過 iptable 來修改封包的來源 IP 地址,將其從 172.17.0.2 改為 10.88.0.4,然後再通過 eth0 介面發送出去。這樣做的目的是讓外部主機能夠正確識別封包的來源,從而建立正確的通信連接。
bashiptables -t nat -A POSTROUTING -s 172.17.0.2/24 -j MASQUERADE # MASQUERADE 這個動作是動態的獲取 Host 的網卡的實際 IP 的位址做 NAT
實現 Port Forwarding
為了讓容器的服務可以透過 Host 的 Port 與外部進行通信,列如 docker run --network=bridge -p 80:8080
我們需要設置 NAT 規則實現 Port Forwarding。
bashiptables \ -t nat \ -A DOCKER \ -j DNAT \ --dport 8080 \ --to-destination 172.17.0.2:80
完成這些設置後,容器內部就能夠與外部網路進行通信,同時也可以通過 Host 上的 Port 8080 與容器的 Port 80 進行映射。
Reference:
留言
張貼留言