docker 網絡設置概述

docker有3種網絡:

使用命令docker network ls,執行結果以下。html

NETWORK ID          NAME                DRIVER              SCOPE
82e8822065c7        bridge              bridge              local
a36f938bc6c6        host                host                local
55ee9a442ee8        none                null                local

1,bridge:是NAT Bridge。在宿主機器上建立一個軟件的交換機或者是網卡。

ifconfig能夠看到多了個【docker0】。linux

【docker0】既能夠做爲交換機,也能夠做爲網卡。不給它地址就是交換機,給它地址就既能當交換機也能當網卡。nginx

linux內核能夠爲進程建立虛擬網卡對,這個網卡對就像網線同樣,有2個頭。

一頭鏈接到本身進程所屬的網絡命名空間,另外一頭鏈接任何地方。c++

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。web

上圖裏面的【docker0】,就是在運行docker daemon進程的機器上,執行ifconfig,看到的【docker0】,它是nat bridge。每啓動一個容器,就產生一條網線,一端就插在【docker0】上,一端插在本身容器的網絡命名空間上。docker

那麼如何查看,【docker0】上插了幾根網線呢?shell

使用【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的另外一端是if12tcp

[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: veth1.2@veth1.1: <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: veth1.1@veth1.2: <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

相關文章
相關標籤/搜索