《原神攻略》1.6版海島找沉船任務技巧
阿新 • • 發佈:2021-06-15
Docker網路本質上是通過修改iptables規則(Linux下)或路由表(Windows下)實現的
Docker的網路子系統是外掛化的,以driver外掛的形式提供:
安裝Docker後會自動安裝三種網路:
- bridge
- host
- overlay
- macvlan
- none
- 第三方的網路外掛
# docker network create --driver xxx <NETWORK>不指定driver時,預設使用bridge,此時創建出來的是使用者自定義Bridge網路 run一個容器的時候,使用引數--network=<NETWORK>來確定容器連線到哪個網路(只能使用一次、指定一個) 不過容器執行後,可以讓容器連線多個網路:
# docker network connect <NETWORK> <容器名>
# docker network ls NETWORK ID NAME DRIVER SCOPE 34390e4712c7 bridge bridge localkubeku 9e4981e4d429 host host local 5f961fc8f8f9 none null local
預設Bridge網路
當Docker程序啟動時,會在主機上建立一個名為docker0的虛擬網橋,此主機上啟動的容器會連線到這個虛擬網橋上。 虛擬網橋的工作方式和物理交換機類似,主機上的所有容器相當於通過它(作為交換機)連在了一個二層網路中。 該網橋可以看作主機的網路堆疊(network stack)的一部分,可以在主機上展示:$ if addr show 5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:16從docker0子網中分配一個IP給容器使用,並設定docker0的IP地址為容器的預設閘道器。 在主機上建立一對虛擬網絡卡veth pair裝置,Docker將veth pair裝置的一端放在新建立的容器中,並命名為eth0(容器的網絡卡),另一端放在主機中,以veth*這樣類似的名字命名,並將這個網路裝置加入到docker0網橋中。 即,docker使用Linux namespace技術將veth對映成在容器中顯示的乙太網卡eth0。因此,docker容器只能通過IP地址(不支援自動服務發現)與同一臺宿主機中的容器(同一個虛擬網橋上的網段)通訊。 舊版docker提供了--link引數來允許docker0網路中容器的通訊(不推薦),不對映它們的埠到宿主主機上,而是直接在兩個容器之間建立一個安全的隧道。--link引數的侷限性在於:使用 /etc/hosts靜態檔案來進行的解析,比如一個主機掛了後,重新啟動IP可能會改變。雖然說這種改變Docker是可能更新/etc/hosts檔案,但是這有諸多問題,可能會因為競爭冒險導致/etc/hosts檔案損毀,也可能還在執行的容器在取得/etc/hosts的解析結果後,不再去監視該檔案是否變動。種種原因都可能會導致舊的主機無法通過容器名訪問到新的主機。 在dockerfile中使用expose關鍵字(相當於docker run的時候使用--expose引數),就可以expose埠。 但expose只是記錄了哪個埠被使用了,並不實際對映或者開啟某個埠,因為構建映象時不知道建立容器的時候宿主機上哪些埠可用。 在docker run時使用--publish(-p)引數就可以publish埠。不指定主機埠的話會將容器埠對映到宿主機的隨機可用的高位埠(>30000)。 發往這些埠的容量最終會被轉發到各自對應的容器內,docker實際是在iptables做了DNAT規則,實現埠轉發功能;容器所有到外部網路的連線,源地址都會使用iptables的源地址偽裝操作(SNAT規則)變為主機的IP地址。 可以使用iptables -t nat -vnL檢視。:51:bb:4d brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:16ff:fe51:bb4d/64 scope link valid_lft forever preferred_lft forever
Host網路
如果啟動容器的時候使用host網路,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網絡卡、配置自己的IP等,而是使用宿主機的IP和埠。 但是,容器的其他方面,如檔案系統、程序列表等還是和宿主機隔離的。 容器被新增到了主機的容器網路堆疊。容器與主機的網路是沒有隔離的,例如使用Host模式的容器在80埠運行了一個web服務,那麼在宿主機的80埠也能訪問這個web服務。None網路
Docker容器擁有自己的Network Namespace,但不會為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。需要我們自己為Docker容器新增網絡卡、配置IP等。 attach進入一個none模式的容器,檢視它的網路堆疊:$ docker attach nonenetcontainer root@0cb243cd1293:/# 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 root@0cb243cd1293:/# ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host 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:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Container模式
這是一種較為特別的網路模式。 這個模式指定新建立的容器沒有自己的網路(不會建立自己的網絡卡、配置自己的IP)、也不和宿主機共享,而是和已經存在的一個容器共享一個Network Namespace。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過eth0網絡卡通訊。 這種模式的網路隔離性處於bridge模式和host模式之間。使用者自定義網路
如果想要通過容器名獲得IP地址,可以建立一個使用者自定義Bridge網路 同該網路中,可以使用對方容器的容器名、服務名、網路別名來找到對方。這個時候幫助進行服務發現的是Docker內建的DNS。所以,無論容器是否重啟、更換IP,內建的DNS都能正確指定到對方的位置。 該網路提供了更好的隔離性,因為:容器不會預設加入此網路,可以隨時加入、移出;每一個使用者自定義Bridge網路都有自己的網橋macvlan網路
macvlan網路會為每個容器的網絡卡分配一個mac地址:$ docker network create -d macvlan \ --subnet=172.16.86.0/24 \ --gateway=172.16.86.1 \ -o parent=eth0 pub_netparent如果是ent0.xxx,Docker會認為它是子介面,會自動建立這個網路介面