文章目錄
- 一、Docker網路間通信
- `1.1.宿主機ping容器,可以正常通信`
- `1.2.容器ping宿主機,可以正常通信`
- `1.3.容器ping外網,可以正常通信(前提條件是宿主機能訪問外網)`
- `1.4.容器ping另外一個容器`
- 二、Docker網路常用技術
- `2.1.網路命名空間`
- 網路命名空間的操作
- `2.2.Veth設備對`
- 創建veth設備對
- 實作veth設備對之間的通信
- 常用操作
- `2.3.網橋`
- 把veth0連接到網橋docker1
- 洗掉網橋
- 三、理解docker0
- `3.1.iptables和Netfilter`
- `3.2.路由`
- 路由表的創建
- 路由表的查看
- 四、Docker的網路實作
- `4.1.Docker啟動后`
- NAT表
- filter表
- `4.2.運行不映射埠的容器`
- `4.3.運行映射了埠(80:80)的容器`
- NAT表
- filter表
一、Docker網路間通信
啟動一個測驗容器
docker run -d --name test busybox sleep 36000
查看容器的IP地址
docker exec -it test ip a s

網卡eth0@if11和172.17.0.2/16的IP是docker自動分配給容器的
1.1.宿主機ping容器,可以正常通信

1.2.容器ping宿主機,可以正常通信

1.3.容器ping外網,可以正常通信(前提條件是宿主機能訪問外網)

1.4.容器ping另外一個容器
再啟動一個容器test1
docker run -d --name test1 busybox sleep 36000
查看容器test1的IP

ping測驗

容器之間是可以正常通信的
問題:那么它們之間是如何實作通信的呢?
二、Docker網路常用技術
查看Docker容器在哪個網路命名空間
2.1.網路命名空間
-
為了支持網路協議堆疊的多個實體,Linux在網路堆疊中引入了網路命名空間,
-
處于不同命名空間中的網路堆疊是
完全隔離的,彼此之間無法通信,就好像兩個“平行宇宙” -
通過對網路資源的隔離,就能在一個宿主機上虛擬多個不同的網路環境
網路命名空間的操作
ip netns add ns1 #創建命名空間ns1
ip netns list #列出命名空間
ip netns exec ns1 ifconfig #在命名空間中執行命名,此時沒有任何網路設備
ip netns exec ns1 bash #進入到命名空間
exit #退出到外面的命名空間
ip link set br0 netns ns1 #把br0設備轉移到ns1命名空間中
ethtool -k br0 | grep netns #如果netns-local的值是on,說明不可以轉移,否則可以轉移
ip netns del ns1 #洗掉網路命名空間
2.2.Veth設備對
通過Veth設備對可以直接將兩個網路命名空間連接起來,實作不同網路命名空間之間的通信
創建veth設備對
ip link add veth0 type veth peer name veth1 #創建Veth設備對
ip link show
在當前網路命名空間出現了一對veth設備對

ip netns add ns1 #創建命名空間ns1
ip link set veth1 netns ns1 #把veth1轉移到ns1命名空間中
ip link show
veth1已經查看不到了

ip netns exec ns1 ip link show #在ns1中查看網路設備
veth1已經移動到ns1網路命名空間了
14: veth1@if15解釋
14表示設備的編號
veth1表示設備名
if15表示該設備的peer設備編號為15

注意:我們在Docker容器中看到的網路設備是eth0,這是因為Docker在將Veth設備放入容器后改名為eth0,簡直以假亂真
實作veth設備對之間的通信
ip netns exec ns1 ip addr add 10.1.1.11/24 dev veth1
ip netns exec ns1 ip link set dev veth1 up
ip addr add 10.1.1.10/24 dev veth0
ip link set dev veth0 up
ping 10.1.1.11
設定IP地址后可以正常通信,這也就實作了不同網路命名空間的通信

常用操作
Veth設備查看對端
ip netns exec ns1 ethtool -S veth1

2.3.網橋
把veth0連接到網橋docker1
brctl addbr docker1 #新增網橋docker1
brctl addif docker1 veth0 #將veth0連接到網橋docker1
ifconfig veth0 0.0.0.0 #veth0作業在鏈路層,因此不再需要IP地址
ifconfig docker1 10.1.1.1/24 #給網橋配置IP地址
brctl show #查看網橋資訊
網橋docker1下連接了veth0

bridge link #顯示哪些設備連接到網橋中

洗掉網橋
ip link set dev docker1 down
brctl delbr docker1
三、理解docker0

Docker啟動后會自動創建一塊網卡——docker0,默認地址為172.17.0.1/16

docker0相當于一個可以配置IP的網橋,類似于三層交換機,所有容器均連接到docker0上,由docker0來實作MAC尋址和路由轉發
每啟動一個容器,就會分配一個IP地址
默認使用橋接(bridge)模式,通過Veth設備對技術來實作通信
3.1.iptables和Netfilter
Netfilter負責在內核中執行各種掛接的規則,運行在內核模式中
而iptables是在用戶模式下運行的行程,負責協助和維護內核中Netfilter的各種規則表,
iptables 命令介紹
3.2.路由
路由表的創建
Linux的路由表至少包括兩個表,一個是LOCAL表,另一個是MAIN表,
LOCAL表包含所有本地設備地址,LOCAL路由表是在配置網路設備地址時自動創建的,用于供Linux協議堆疊識別本地地址,以及進行本地各個不同網路介面之間的資料轉發
通過如下命令查看LOCAL表的內容:
ip route show table local type local
MAIN表用于各類網路IP地址的轉發,
路由表的查看
ip route list

netstat -rn或route -n

標志是U,說明是可達路由
標志是G,說明這個網路介面連接的是網關,否則說明這個介面是直連主機
四、Docker的網路實作
詳細介紹Docker啟動后、運行不映射埠的容器、運行映射了埠的容器時iptables的區別(使用iptables-save查看)
4.1.Docker啟動后
NAT表
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
前兩條匹配生效后,都會執行DOCKER鏈,而此時DOCKER鏈為空,所以前兩條只是做了一個框架,并沒有實際效果
若本地出發的資料包不是發往docker0的,則需要進行動態地址修改(MASQUERADE),將源地址從容器的地址(172段)修改為宿主機網卡的IP地址,之后就可以發送給外面的網路了,即SNAT
filter表
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
第1條:如果接收到的資料包屬于以前已經建立好的連接,那么允許直接通過,這樣接收到的資料表又走回docker0,并中轉到相應的容器
第2條是框架,發往docker0的包都會走DOCKER鏈
第3條:來自docker0的包,如果Forward到非docker0的本地IP地址設備,是允許的,這樣,docker0設備的包就可以根據路由規則中轉到宿主機的網卡設備,從而訪問外面的網路
第4條:docker0的包還可以被中轉給docker0本身,即連接在docker0網橋上的不同容器之間的通信也是允許的
4.2.運行不映射埠的容器
iptable與Docker啟動后一樣
4.3.運行映射了埠(80:80)的容器
共增加了如下三條規則
NAT表
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
第1條:作用是將原地址和目標地址為容器IP 172.17.0.2/32, 且目標埠為80,MASQUERADE動態地轉換為可用的宿主機IP地址—沒搞懂為什么要這么做
第2條:其作用是將訪問宿主機80埠請求的流量轉發到容器172.17.0.2的80埠上,所以,外界訪問Docker容器是通過iptables做DNAT實作的,
filter表
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
從非docker0發往docker0且目的地址為172.17.0.2/32,埠是tcp 8443的包是允許的
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290390.html
標籤:其他
