docker有3種網路:
使用命令docker network ls,執行結果如下,
NETWORK ID NAME DRIVER SCOPE
82e8822065c7 bridge bridge local
a36f938bc6c6 host host local
55ee9a442ee8 none null local
1,bridge:是NAT Bridge,在宿主機器上創建一個軟體的交換機或者是網卡,
用ifconfig可以看到多了個【docker0】,
【docker0】既可以作為交換機,也可以作為網卡,不給它地址就是交換機,給它地址就既能當交換機也能當網卡,
linux內核可以為行程創建虛擬網卡對,這個網卡對就像網線一樣,有2個頭,
一頭連接到自己行程所屬的網路命名空間,另一頭連接任何地方,
linux內核也可以創建軟體交換機,使用【brctl】命令創建,
創建虛擬網路,以實作讓行程C1和行程C2可以通信,
- 步驟1:創建一個網線m
- 步驟2:創建一個網線n
- 步驟3:創建一個虛擬交換機S1,
- 步驟4:讓網線m的一端連上行程C1所屬的網路命名空間,讓網線m的另一端連上虛擬交換機S1,
- 步驟5:讓網線n的一端連上行程C2所屬的網路命名空間,讓網線n的另一端連上虛擬交換機S1,
- 行程C1和行程C2就可以通信了,
創建虛擬網路,以實作讓行程C1和行程C3可以通信,
- 步驟1:創建一個網線k
- 步驟2:創建一個虛擬交換機S2,
- 步驟3:創建一個圖中間的微內核,讓這個內核代替路由器,或者不需要路由器的話,創建1根網線,連接S1和S2,這樣一來就不需要步驟4了,
- 步驟4:創建2根網線,讓S1和S2都連都微內核上,
- 行程C1和行程C3就可以通信了,

有個著名的開源的創建虛擬交換機的軟體:OVS(OpenVSwitch).
overlay network(疊加網路)
C1(192.168.1.3)和C5(192.168.1.4)在同一個網段,物理機器h1(10.1.1.3)和h2(10.1.1.4)連接在同一個交換機上,因為C1和C5在同一個網段,所以它們2個可以互相看見,當C1要發送資料給C5時,ip報文里是C1:C5,然后經過虛擬網橋(docker0),轉發給物理機器h1,物理機器h1在【ip報文C1:C5】外面再包裹一層【h1:h2】,物理機器h2接受到報文后,拆掉外層的【h1:h2】,發現里面還有【C1:C5】,所以通過虛擬網橋(docker0),轉發給C5,

上圖里面的【docker0】,就是在運行docker daemon行程的機器上,執行ifconfig,看到的【docker0】,它是nat bridge,每啟動一個容器,就產生一條網線,一端就插在【docker0】上,一端插在自己容器的網路命名空間上,,
那么如何查看,【docker0】上插了幾根網線呢?
使用【yum install bridge-utils】里面的【brctl show】命令,查看網橋上插了哪些網線,
[root@localhost ys]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242af11c649 no veth93593bc
vethc7cb2ca
從上面的執行結果可以看出來,在【docker0】上插了2根網線分別是veth93593bc和vethc7cb2ca,用在宿主機上使用ifconfig,可以看到這2個網線,
[root@localhost ys]# ifconfig
veth93593bc: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 ..... prefixlen 64 scopeid 0x20<link>
ether ..... txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethc7cb2ca: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 .. prefixlen 64 scopeid 0x20<link>
ether ..... txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
使用【ip link show】也可以看到veth93593bc和vethc7cb2ca,而且還可以發現veth93593bc的另一端是if14,vethc7cb2ca的另一端是if12
[root@localhost ys]# ip link show
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:af:11:c6:49 brd ff:ff:ff:ff:ff:ff
13: vethc7cb2ca@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether a2:a3:b8:3c:8c:88 brd ff:ff:ff:ff:ff:ff link-netnsid 0
15: veth93593bc@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether b2:24:a8:13:4d:56 brd ff:ff:ff:ff:ff:ff link-netnsid 1
【iptables -t nat -vnL】查看,發現了下面的規則,所以說明docker0是nat bridge,
iptables種的DNAT和SNAT概念
Chain POSTROUTING (policy ACCEPT 47 packets, 3073 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
in:*,代表:從任何介面進來
out:!docker0,代表:不從docker0出去
source:172.17.0.0/16,代表:原地址來自172.17.0.0/16的任何主機地址,
destination:0.0.0.0/0,代表:發送到任何主機地址,
target:MASQUERADE,代表:做源地址轉換 (SNAT ),也就是自動在本機上選擇一個源地址,
把上面的話連接起來的意思:從任何介面進來,不從docker0出去,原地址是來自172.17.0.0/16的任何主機地址,發送到任何主機地址,做源地址轉換,
創建網路命名空間
查看ip命令的工具包是否安裝:rpm -q iproute
使用ip命令,看到object里有網路命名空間(netns),所以我們用ip命令就可以創建網路命名空間,
[root@localhost ys]# ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
ip [ -force ] -batch filename
where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
vrf }
OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
-h[uman-readable] | -iec |
-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
-4 | -6 | -I | -D | -B | -0 |
-l[oops] { maximum-addr-flush-attempts } | -br[ief] |
-o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
-rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}
-
獲得ip netns命令的幫助資訊:
[root@localhost ys]# ip netns help Usage: ip netns list//查看當前系統里的網路命名空間 ip netns add NAME//添加網路命名空間 ip netns set NAME NETNSID ip [-all] netns delete [NAME] ip netns identify [PID]//讓某個行程使用某個網路命名空間 ip netns pids NAME ip [-all] netns exec [NAME] cmd ...//在某個網路命名空間上執行網路命令, ip netns monitor ip netns list-id -
命令
ip netns使用例子:創建網路命名空間和查看網路命名空間[root@localhost ys]# ip netns list [root@localhost ys]# ip netns add ns1 [root@localhost ys]# ip netns add ns2 [root@localhost ys]# ip netns list ns2 ns1 -
獲取ip link命令的幫助資訊:
ip link help[root@localhost ys]# ip link help Usage: ip link add [link DEV] [ name ] NAME [ txqueuelen PACKETS ] [ address LLADDR ] [ broadcast LLADDR ] [ mtu MTU ] [index IDX ] [ numtxqueues QUEUE_COUNT ] [ numrxqueues QUEUE_COUNT ] type TYPE [ ARGS ] ...后面太多了,省略了, -
在指定的網路命名空間里執行網路命令:
# ip netns exec ns1 ifconfig -
給網路命名空間創建網線(虛擬網卡對),命令里面的【type】是網卡對的型別,veth是以太網,
# ip link add name veth1.1 type veth peer name veth1.2使用
ip link show可以看到剛創建的veth1.1和veth1.2,他們互為一對,而且他們都是插宿主機上的,22: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 4e:e3:65:60:bb:08 brd ff:ff:ff:ff:ff:ff 23: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 2a:16:5b:ce:fe:f6 brd ff:ff:ff:ff:ff:ff使用
ifconfig,發現他們都沒有被顯示出來,因為還沒有激活他們,用ifconfig -a是可以顯示出來的,先創建一個網路命名空間:
ip netns add ns1,然后讓veth1.2插在ns1上,# ip link set dev veth1.2 netns ns1然后在宿主機網路命名空間上執行
ip link show,發現veth1.2沒有了,因為veth1.2已經到ns1網路命名空間里了,23: veth1.1@if22: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 2a:16:5b:ce:fe:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0再去ns1網路命名空間里,執行
ip netns exec ns1 ifconfig -a,發現veth1.2在里面,veth1.2: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0也可以修改veth1.2的名字,修改成eth0.
# ip netns exec ns1 ip link set dev veth1.2 name eth0執行
ip netns exec ns1 ifconfig -a,發現變成了eth0了,eth0: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 -
讓虛擬網卡插在某個網路命名空間,
# ip link set dev veth1.2 netns ns1 -
激活虛擬網卡(賦給它IP就是激活),
激活veth1.1
# ifconfig veth1.1 10.1.0.1/24 up執行
ifconfig,發現虛擬網卡veth1.1有ip地址了,veth1.1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 10.1.0.1 netmask 255.255.255.0 broadcast 10.1.0.255 ether 2a:16:5b:ce:fe:f6 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0激活ns1里的eth0
# ip netns exec ns1 ifconfig eth0 10.1.0.2/24 up執行
ifconfig,發現虛擬網卡eth0有ip地址了,eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.1.0.2 netmask 255.255.255.0 broadcast 10.1.0.255 inet6 fe80::4ce3:65ff:fe60:bb08 prefixlen 64 scopeid 0x20<link> ether 4e:e3:65:60:bb:08 txqueuelen 1000 (Ethernet) RX packets 11 bytes 1447 (1.4 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 7 bytes 586 (586.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0從宿主機ping一下ns1里的eth0,是可以ping通的,
# ping 10.1.0.2 PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data. 64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.073 ms再從ns1ping一下宿主機的veth1.1,也是可以ping通的,
# ip netns exec ns1 ping 10.1.0.1 PING 10.1.0.1 (10.1.0.1) 56(84) bytes of data. 64 bytes from 10.1.0.1: icmp_seq=1 ttl=64 time=0.039 ms -
使用
ip命令可以創建虛擬網卡,使用brctl,可以創建虛擬交換機,有了它倆,就可以模擬很多虛擬網路,比如物理橋,nat橋等,不需要安裝額外的虛擬機,很輕量,
有個問題,docker容器間是如何互相通信的呢?
-
假設容器都是以bridge方式啟動
-
2個容器都插在docker0上,那么這2個容器都在172.17網段上,互相通信沒有任何問題,
-
容器和宿主機互相通信沒有問題,
-
客戶端CL1,要通過80埠訪問nginx容器WEB1,但是客戶端CL1同nginx容器WEB1在不同的網路,如何通信呢?nginx容器WEB1所在的宿主機只能使用DNAT技術,才能實作通信,也就是說客戶端CL1訪問的是宿主機,宿主機再轉發給nginx容器WEB1,
這就有個問題了,如果web2和web3也是nginx,也要使用80埠,那么宿主機轉發的時候就不知道轉給哪個容器了,
-

另一種方式:容器可以有獨立的6個命名空間,為了2個容器間可以用lo(127.0.0.1)通信,讓他們只擁有3個(user,mount, pid)獨立的命名空間,另外3個(uts, net, ipc)他們共享使用,

二,host:
容器間可以共用3個(uts, net, ipc)空間,那么容器可以和宿主機(docker daemon行程所運行的機器)共用嗎?是可以的,讓一個容器A和宿主機共用3個(uts, net, ipc)空間,讓其他的容器使用橋接,這樣一來容器A就有了管理網路的特權,這就是docker的host連接方式,
三,none:容器沒有網卡,只有lo,所以不能網路通信,
docker 網路種類:

查看網路連接具體資訊的命令(inspect 可以查看任何docker object):
# docker network inspect bridge/host/none
查看容器的網路連接具體資訊,
# docker container inspect ng1
c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/102264.html
標籤:其他
上一篇:pr安裝問題
