Docker網絡基礎

1、 網絡命名空間

爲了支持網絡協議棧的多個實例,Linux在網絡棧中引入了網絡命名空間,這些獨立的協議棧被隔離到不一樣的命名空間中。docker

  • 好處:經過對網絡資源的隔離,就能在一個宿主機上虛擬多個不一樣的網絡環境。而且,在Linux的網絡命名空間中能夠有本身獨立的路由表及獨立的iptables設置來提供包轉發、NAT及IP包過濾等功能。
  • 難處:爲了隔離出獨立的協議棧,須要歸入命名空間的元素有進程、套接字、網絡設備等。
  • 方法:Linux的網絡協議棧是十分複雜的,爲了支持獨立的協議棧,相關的這些全局變量都必須被修改成協議棧私有。最好的辦法就是讓這些全局變量稱爲一個Net Namespaces變量的成員,而後爲協議棧的函數調用加入一個Namespaces參數。這就是Linux實現網絡命名空間的核心。

命令:shell

  1. 建立一個命名空間:
ip netns add <name>
  1. 在命名空間中執行命令:
ip netns exec <name> <command>
  1. 經過bash命令進入內部的shell界面:
ip netns exec <name> bash
  1. 退出到外面的命名空間時,請輸入exit

因爲一個設備只能屬於一個命名空間,因此轉移後在這個命名空間中就看不到這個設備了。具體哪些設備能被轉移到不一樣的命名空間呢?在設備裏面有個重要的屬性:NETIF_F_ETNS_LOCAL,若是這個屬性爲on,就不能轉移到其餘命名空間中。而不少其餘設備如lo設備、vxlan設備、ppp設備、bridge設備等都是不可轉移的。將沒法轉移的設備移動到別的命名空間時,會獲得無效參數的錯誤提示。bash

命令:網絡

  1. 轉移設備至命名空間:
ip link set <device> netns <namespace>
  1. 查看設備是否能夠轉移:
ethtool -k <device>

操做函數

# ip netns add netns1
# ip netns show
netns1
# ip netns exec netns1 ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ip netns exec netns1 bash
# ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# exit
exit
# ip link set br0 netns netns1
RTNETLINK answers: Invalid argument
# ethtool -k br0
netns-local: on [fixed]
# ip netns del netns1

因爲網絡命名空間表明的是一個獨立的協議棧,因此它們之間是相互隔離的,彼此沒法通訊,在協議棧內部都看不到對方。爲了打破這種限制,讓處於不一樣命名空間的網絡相互通訊,甚至和外部的網絡進行通訊,咱們應用「Veth設備對」便可達到。oop

2、Veth設備對

Veth設備對的一個重要做用就是打通相互看不到的協議棧之間的壁壘,它就像一條管子,一端連着這個網絡命名空間的協議棧,一端連着另外一個網絡命名空間的協議棧。
因爲要鏈接兩個網絡命名空間,因此Veth設備都是成對出現的,就像是一對以太網卡,而且中間有一根直連的網線。既然是一對網卡,那麼咱們將其中一端稱爲另外一端的peer。在Veth設備的一端發送數據時,它會將數據直接發送到另外一端,並觸發另外一端的接收操做。學習

命令:
建立Veth設備對:spa

ip link add <veth0> type veth peer name <veth1>
  • 生成的兩個設備中,一個是veth0,它的peer是veth1

操做:.net

# ip netns add netns1
# ip link add veth0 type veth peer name veth1
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether f8:b1:56:d8:da:0a brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:82:ad:fa:6c brd ff:ff:ff:ff:ff:ff
14: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 7a:f0:93:10:6f:69 brd ff:ff:ff:ff:ff:ff
15: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 9e:dd:2b:54:78:31 brd ff:ff:ff:ff:ff:ff
# ip link set veth1 netns netns1
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether f8:b1:56:d8:da:0a brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:82:ad:fa:6c brd ff:ff:ff:ff:ff:ff
15: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 9e:dd:2b:54:78:31 brd ff:ff:ff:ff:ff:ff
# ip netns exec netns1 ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
14: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 7a:f0:93:10:6f:69 brd ff:ff:ff:ff:ff:ff
# ip netns exec netns1 ip addr add 10.1.1.2/24 dev veth1
# ip addr add 10.1.1.3/24 dev veth0
# ip link set dev veth0 up
# ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.045 ms
^C
--- 10.1.1.2 ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 7999ms
rtt min/avg/max/mdev = 0.032/0.042/0.064/0.012 ms
# ip netns exec netns1 ping 10.1.1.3
PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.038 ms
^C
--- 10.1.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.038/0.056/0.074/0.018 ms

Veth設備對如何查看對端:code

# ethtool -S veth0
NIC statistics:
     peer_ifindex: 14
# ip netns exec netns1 ip link | grep 14
14: veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

3、網橋

Linux能夠支持多個不一樣的網絡,它們之間可以相互通訊,如何將這些網絡鏈接起來並實現各網絡中主機的相互通訊呢?能夠用「網橋」。 網橋是一個二層的虛擬網絡設備,把若干個網絡接口「鏈接」起來,以使得網絡接口之間的報文可以相互轉發。網橋可以解析收發的報文,讀取目標MAC地址的信息,和本身記錄的MAC表結合,來決策報文的轉發目標網絡接口。爲了實現這些功能,網橋會學習源MAC地址(二層網橋轉發的依據就是MAC地址)。在轉發報文時,網橋只須要向特定的網口進行轉發,來避免沒必要要的網絡交互。若是它遇到一個本身從未學習到的地址,就沒法知道這個報文應該向哪一個網絡接口轉發,就將報文廣播給全部的網絡接口(報文來源的網絡接口除外)
在Linux的內部網絡棧裏實現的網橋設備,做用和上面的描述相同。過去Linux主機通常都只有一個網卡,如今多網卡的及其愈來愈多,並且又不少虛擬的設備存在,因此Linux的網橋提供了在這些設備之間相互轉發數據的二層設備。
Linux內核是經過一個虛擬的網橋設備(Net Device)來實現橋接的。這個虛擬設備能夠綁定若干個以太網接口設備,從而將它們橋接起來。這種Net Device網橋和普通的設備不一樣,最明顯的一個特徵是它還能夠有一個IP地址。
命令:

  1. 新增一個網橋設備:
brctl addbr <br_name>
  1. 爲網橋增長網口:
brctl addbr <br_name> <eth_name>
  1. 網橋的物理網卡做爲一個網口,因爲在鏈路層工做,就再也不須要IP地址了,這樣上面的IP地址天然失效:
ifconfig <eth_name> 0.0.0.0
  1. 配置網橋IP地址:
ifconfig <eth_name> <ip_address>

這樣網橋就有一個IP地址,而鏈接到上面的網卡就是一個純鏈路層設備了。

操做:

# brctl addbr bridge
# brctl addif veth0
# brctl show
bridge name     bridge id               STP enabled     interfaces
bridge          8000.9edd2b547831       no              veth0
docker0         8000.02425e4d0ba8       no              vethb8777d1
# ifconfig veth0 0.0.0.0
# ifconfig bridge 10.1.1.1/16
# ip addr show bridge
16: bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 9e:dd:2b:54:78:31 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.1/16 brd 10.1.255.255 scope global bridge
       valid_lft forever preferred_lft forever
    inet6 fe80::9cdd:2bff:fe54:7831/64 scope link
       valid_lft forever preferred_lft forever
# ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.040 ms
^C
--- 10.1.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.040/0.052/0.064/0.012 ms

注意:

  • 若是網橋上的網口不卸掉IP,至關於在網絡層工做,而網橋只能在鏈路層工做,因此網口IP不失效,將致使網橋不起做用(表現:Veth設備對不通)
# ping -I 10.1.1.3 10.1.1.2
connect: Network is unreachable
  • 網橋是不具有路由功能的,具體表現爲:主機能夠ping通veth1,而veth1卻ping不一樣主機。
# ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.034 ms
^C
--- 10.1.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.034/0.047/0.060/0.013 ms
# ip route add 192.168.0.0/24 dev bridge  proto kernel  scope link  src 10.1.1.1
# ip netns exec netns1 ping 192.168.1.2
connect: Network is unreachable
# ip netns exec netns1 ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=0.036 ms
^C
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.036/0.050/0.065/0.016 ms
  • <host_ip> : 192.168.1.2
  • <bridge_ip> : 10.1.1.1

4、iptables和Netfilter

Linux網絡協議棧很是高效,同時比較複雜。若是咱們但願在數據的處理過程當中對關心的數據進行一些操做,該怎麼辦呢?Linux提供了一套機制來爲用戶實現自定義的數據包處理過程。
在Linux網絡協議棧中有一組回調函數掛接點,經過這些掛接點掛接的鉤子函數能夠在Linux網絡棧處理數據包的過程當中對數據包進行一些操做,例如過濾、修改、丟棄等。整個掛接點技術叫做Netfilter和iptables。
Netfilter負責在內核中執行各類掛接的規則,運行在內核模式中;而iptables是在用戶模式下運行的進程,負責協助和維護內核中Netfilter的各類規則表。兩者相互配合來實現整個Linux網絡協議棧中靈活的數據包處理機制。
iptables命令用於協助用戶維護各類規則。咱們在使用Kubernetes、Docker的過程當中,一般都會去查看相關的Netfilter配置。這裏只介紹如何查看規則表,詳細的介紹請參照 iptables詳解

5、路由

路由功能由IP層維護的一張路由表來實現。當主機收到數據報文時,它用此表來決策接下來應該作什麼操做。當從網絡側接收到數據報文時,IP層首先會檢查報文的IP地址是否與主機自身的地址相同。若是數據報文中的IP地址是主機自身的地址,那麼報文將被髮送到傳輸層相應的協議中。若是報文中的IP地址不是主機自身的地址,而且主機配置了路由功能,那麼報文將被轉發,不然,報文將被丟棄。

相關文章
相關標籤/搜索