[Linux網路、名稱空間、veth裝置對、docker的host模式、container模式、none模式、brideg模式、網橋的增刪查,容器與網橋的連線斷開]
阿新 • • 發佈:2021-06-24
[Linux網路、名稱空間、veth裝置對、docker的host模式、container模式、none模式、brideg模式、網橋的增刪查,容器與網橋的連線斷開]
網路名稱空間
為了支援網路協議棧的多個例項,Linux 在網路協議棧中引入了網路名稱空間(Network Namespace),這些獨立的協議棧被隔離到不同的名稱空間中。處於不同的名稱空間的網路協議棧是完全隔離的,彼此之間無法進行網路通訊,就好像兩個“平行宇宙”。通過這種對網路資源的隔離,就能在一個宿主機上虛擬多個不同的網路環境,而 Docker 正是利用這種網路名稱空間的特性,實現了不同容器之間的網路隔離。在 Linux 的網路名稱空間 內可以有自己獨立的Iptables 來轉發、NAT 及 IP 包過濾等功能。
Linux 的網路協議棧是十分複雜的,為了支援獨立的協議棧,相關的這些全域性變數都必須修改為協議棧私有。最好的辦法就是讓這些全域性變數成為一個 Net Namespace 變數的成員,然後為了協議棧的函式呼叫加入一個Namespace 引數。這就是 Linux 網路名稱空間的核心。所以的網路裝置都只能屬於一個網路名稱空間。當然,通常的物理網路裝置只能關聯到 root 這個名稱空間中。虛擬網路裝置則可以被建立並關聯到一個給定的名稱空間中,而且可以在這些名稱空間之間移動。
建立一個名稱空間
ip netns add liuhaojie(名稱空間名) ip netns add liupengfei(名稱空間名)
檢視建立過的名稱空間
ip netns list
Veth 裝置
引入 Veth 裝置對是為了在不同的網路名稱空間之間進行通訊,利用它可以直接將兩個網路名稱空間連結起 來。由於要連線的兩個網路名稱空間,所以 Veth 裝置是成對出現的,很像一對乙太網卡,並且中間有一根直連 的網線。既然是一對網絡卡,那麼我們將其中一端稱為另一端的 peer。在 Veth 裝置的一端傳送資料時,它會將數 據直接傳送到另一端,並觸發另一端的接收操作。
建立Veth裝置對
ip link add veth(Veth名稱) type veth peer name veth001(Veth名稱) 生成了兩個 veth 裝置, 互為對方的 peer ! ! ! !
檢視 Veth 裝置對
ip link list
ip link show
ip a
將 Veth裝置對 分發至 名稱空間
將 veth2 裝置對分發至 liupengfei 名稱空間
ip link set veth2 netns liupengfei(名稱空間)
如何進入名稱空間
ip netns exec liupengfei(名稱空間) bash
名稱空間的 veth 裝置對分配 IP
# 給當前名稱空間的 veth1 分配 ip
ip addr add 172.16.0.112/20 dev veth1
ip netns exec liupengfei(名稱空間) ip addr add 172.16.0.111/20 dev veth2
# 給 liupengfei 名稱空間中的 veth2 分配 ip
注意!!! 設定IP之後重啟 veth 裝置對,否則會 ping 不通 !!!
名稱空間的 veth 裝置對刪除 IP
# 給當前名稱空間的 veth1 分配 ip
ip addr del 172.16.0.112/20 dev veth1
ip netns exec liupengfei(名稱空間) ip addr del 172.16.0.111/20 dev veth2
# 給 liupengfei 名稱空間中的 veth2 分配 ip
重啟veth裝置對
ip netns exec liupengfei ip link set dev veth2 down
ip netns exec liupengfei ip link set dev veth2 up
ip link set dev veth1 down
ip link set dev veth1 up
Docker 網路模式
Docker 使用 Linux 橋接的方式,在宿主機虛擬一個 Docker 容器網橋(docker0),Docker 啟動一個容器時會 根據 Docker 網橋的網段分配給容器一個 IP 地址,稱為 Container-IP,同時 Docker 網橋是每個容器的預設閘道器。 因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的 Container-IP 直接通訊。
Docker 網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路是無法定址到的,這也意味著外 部網路無法通過直接 Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到 宿主主機(埠對映),即 docker run 建立容器時候通過 -p 或 -P 引數來啟用,訪問容器的時候就通過[宿主 機 IP]:[對映容器的埠]訪問容器。
HOST模式
使用宿主主機的網絡卡
docker run --network host [映象名稱|ID]
如果啟動容器的時候使用 host 模式,那麼這個容器將不會獲得一個獨立的 Network Namespace,而是和宿主機共用一個 Network Namespace。容器將不會虛擬出自己的網絡卡,配置自己的 IP 等,而是使用宿主機的 IP 和埠。但是,容器的其他方面,如檔案系統、程序列表等還是和宿主機隔離的。
使用 host 模式的容器可以直接使用宿主機的 IP 地址與外界通訊,容器內部的服務埠也可以使用宿主機的 埠,不需要進行 NAT,host 最大的優勢就是網路效能比較好,但是 docker host 上已經使用的埠就不能再 用了,網路的隔離性不好。
host 演示
nginx 並沒有對外暴露埠,但是 127.0.0.1 可以成功連線到nginx ,說明host模式容器確實是使用了主機的網絡卡
container模式
共享一個容器的網路,幾個容器使用container指向同一個容器的時候,共用一個網絡卡。
docker run -d --network "container:[共享容器名稱]" nginx
這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。 新建立的容器不會建立自己的網絡卡,配置自己的 IP,而是和一個指定的容器共享 IP、埠範圍等。同樣,兩個 容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過 lo 網絡卡裝置通訊。
none模式
不為容器提供任何網路
docker run -d --network none 映象[名稱|ID]
使用 none 模式,Docker 容器擁有自己的 Network Namespace,但是,並不為 Docker 容器進行任何網路 配置。也就是說,這個 Docker 容器沒有網絡卡、IP、路由等資訊。需要我們自己為 Docker 容器新增網絡卡、配置 IP 等。
這種網路模式下容器只有 lo 迴環網路,沒有其他網絡卡。none 模式可以在容器建立時通過--network=none 來指定。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。
bridge 網橋模式
將多個容器使用docker網橋進行地址轉換的方式實現網路互通
當 Docker 程序啟動時,會在主機上建立一個名為 docker0 的虛擬網橋,此主機上啟動的 Docker 容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個 二層網路中。
從 docker0 子網中分配一個 IP 給容器使用,並設定 docker0 的 IP 地址為容器的預設閘道器。在主機上建立 一對虛擬網絡卡 veth pair 裝置,Docker 將 veth pair 裝置的一端放在新建立的容器中,並命名為 eth0(容器的網 卡),另一端放在主機中,以 vethxxx 這樣類似的名字命名,並將這個網路裝置加入到 docker0 網橋中。可以 通過 brctl show 命令檢視。
bridge 模式是 docker 的預設網路模式,不寫--net 引數,就是 bridge 模式。使用 docker run -p 時,docker 實際是在 iptables 做了 DNAT 規則,實現埠轉發功能。可以使用 iptables -t nat -vnL 檢視。
建立網橋
docker network create chenyang(網橋名)
引數:
-d : 指定網橋的型別 (預設就是bridge)
--gateway : 指定閘道器
--subnet : 指定子網
檢視網橋
展示當前主機上網橋列表
docker network ls
docker network list
檢視網橋的詳細資訊
docker network inspect [網橋名稱|id]
使用網橋
docker run -d --network chenyang(網橋名) nginx(映象名|ID)
同一網橋中容器依然隔離
同一個網橋中又啟動了一個nginx容器,用centos的容器連線127.0.0.1沒連線上,證明網橋中容器隔離
同一網橋可以互相訪問
同一個網橋中的容器可以通過IP來訪問,也可以通過容器ID來訪問,如果想要通過容器名稱來訪問,需要映象啟動的時候使用 -- name 自定義一個容器名稱。不自定義容器名稱則不能通過容器名稱來訪問。
刪除網橋
docker network rm 網橋名稱(一個或多個) # 不在使用中的網橋才可以刪除
清空網橋
清空空閒的(不在使用中的網橋)並且是自創的網橋
docker network prune [引數] 網橋名稱
-f :跳過二次確認選擇,直接刪除
容器連線上一個網橋
給一個容器修改網橋,把容器當前的網橋修改成你指定的網橋
docker network connect [引數] [網橋名稱] [容器名稱]
斷開連結
斷開容器和網橋的連線關係。如果容器連線的不是docker0的網橋,斷開連線之後會預設連線docker0的網橋,如果再與docker0的網橋斷開,容器就變成了none模式,也就是隻有迴環網路,其他皆不存在。
docker network disconnect [引數] [網橋名稱] [容器名稱]