Macvlan 網絡方案實踐

原文連接:Macvlan 網絡方案實踐node

經過上篇文章的學習,咱們已經知道 Macvlan 四種模式的工做原理,其中最經常使用的就是 Bridge 模式,本文咱們將經過實驗來驗證 Macvlan Bridge 模式的連通性。linux

Macvlan 是 linux 內核比較新的特性,能夠經過如下方法判斷當前系統是否支持:ubuntu

$ modprobe macvlan
$ lsmod | grep macvlan
  macvlan                19233  0
複製代碼

若是第一個命令報錯,或者第二個命令沒有返回,則說明當前系統不支持 Macvlan,須要升級系統或者升級內核。bash

1. 各個 Linux 發行版對 Macvlan 的支持

Macvlan 對 Kernel 版本依賴:Linux kernel v3.9–3.19 and 4.0+。幾個重要發行版支持狀況:網絡

  • ubuntu:>= saucy(13.10)
  • RHEL(Red Hat Enterprise Linux): >= 7.0(3.10.0)
  • Fedora: >=19(3.9)
  • Debian: >=8(3.16)

各個發行版的內核均可以自行手動升級,具體操做能夠參考官方提供的文檔。oop

以上版本信息參考了這些資料:post

2. 實驗環境

後面的測試將會在如下環境進行:學習

OS hostname 物理網卡 IP Gateway
CentOS 7.3 node1 ens160 192.168.179.9/16 192.168.1.1
CentOS 7.3 node2 ens160 192.168.179.10/16 192.168.1.1

個人本地操做系統爲 MacOS,IP 爲 10.8.0.241,網關爲 10.8.0.1測試

3. 連通性測試

下面開始對 Bridge 模式下 Macvlan 的連通性進行測試。ui

首先在 node1 上建立兩個 network namespace:

# 開啓混雜模式
$ ip link set ens160 promisc on

$ ip netns add ns1
$ ip netns add ns2
複製代碼

而後建立 Macvlan 接口:

$ ip link add link ens160 mac1 type macvlan mode bridge
複製代碼

建立的格式爲 ip link add link <PARENT> <NAME> type macvlan mode <MODE>,其中 <PARENT> 是 Macvlan 接口的父接口名稱,<NAME> 是新建的 Macvlan 接口的名稱,這個名字能夠任意取,<MODE> 是 Macvlan 的模式。

能夠查看建立接口的詳細信息:

$ ip -d link show mac1

13: mac1@ens160: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 5a:94:85:a6:96:95 brd ff:ff:ff:ff:ff:ff promiscuity 0
    macvlan  mode bridge addrgenmode eui64
複製代碼

下面就是把建立的 Macvlan 接口放到 network namespace 中,配置好 IP 地址,而後啓用它:

$ ip link set mac1 netns ns1
$ ip netns exec ns1 ip addr add 192.168.179.12/16 dev mac1
$ ip netns exec ns1 ip link set dev mac1 up
複製代碼

同理能夠配置另一個 Macvlan 接口:

$ ip link add link ens160 mac2 type macvlan mode bridge
$ ip link set mac2 netns ns2
$ ip netns exec ns2 ip addr add 192.168.179.13/16 dev mac2
$ ip netns exec ns2 ip link set dev mac2 up
複製代碼

能夠測試兩個 IP 的連通性:

ns1 --> ns2

$ ip netns exec ns1 ping -c 3 192.168.179.13

PING 192.168.179.13 (192.168.179.13) 56(84) bytes of data.
64 bytes from 192.168.179.13: icmp_seq=1 ttl=64 time=0.090 ms
64 bytes from 192.168.179.13: icmp_seq=2 ttl=64 time=0.061 ms

--- 192.168.179.13 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.061/0.075/0.090/0.016 ms
複製代碼

ns2 --> ns1

$ ip netns exec ns2 ping -c 2 192.168.179.12

PING 192.168.179.12 (192.168.179.12) 56(84) bytes of data.
64 bytes from 192.168.179.12: icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from 192.168.179.12: icmp_seq=2 ttl=64 time=0.043 ms

--- 192.168.179.12 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.043/0.051/0.059/0.008 ms
複製代碼

ns1 --> 192.168/16

首先測試 ns1 與 node2 的連通性:

$ ip netns exec ns1 ping -c 2 192.168.179.10

PING 192.168.179.10 (192.168.179.10) 56(84) bytes of data.
64 bytes from 192.168.179.10: icmp_seq=1 ttl=64 time=0.976 ms
64 bytes from 192.168.179.10: icmp_seq=2 ttl=64 time=0.430 ms

--- 192.168.179.10 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.430/0.703/0.976/0.273 ms
複製代碼

下面測試 ns1 與 node2 中 network namespace 的連通性。

先在 node2 中配置一個 Macvlan 接口:

[root@node2 ~]# ip link set ens160 promisc on
[root@node2 ~]# ip netns add ns1
[root@node2 ~]# ip link add link ens160 mac1 type macvlan mode bridge
[root@node2 ~]# ip link set mac1 netns ns1
[root@node2 ~]# ip netns exec ns1 ip addr add 192.168.179.14/16 dev mac1
[root@node2 ~]# ip link set dev mac1 up
複製代碼

測試 node1 的 ns1 與 node2 的 ns1 的連通性:

[root@node1 ~]# ip netns exec ns1 ping -c 2 192.168.179.14

PING 192.168.179.14 (192.168.179.14) 56(84) bytes of data.
64 bytes from 192.168.179.14: icmp_seq=1 ttl=64 time=0.976 ms
64 bytes from 192.168.179.14: icmp_seq=2 ttl=64 time=0.430 ms

--- 192.168.179.14 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.430/0.703/0.976/0.273 ms
複製代碼

10.8/16 --> ns1

# 在本地的 MacOS 客戶端 ping 192.168.179.12
$ ping 192.168.179.12 -c 2

PING 192.168.179.12 (192.168.179.12): 56 data bytes
Request timeout for icmp_seq 0

--- 192.168.179.12 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss
複製代碼

發現跨三層網段是 ping 不通的。這個問題很好解決,咱們剛剛給 ns1ns2 分配 IP 的時候並無指定默認路由,指定個默認路由問題就迎刃而解了。

$ ip netns exec ns1 ip route add default via 192.168.1.1 dev mac1
複製代碼

若是你想開發 Macvlan cni 插件,這個地方須要注意一下,每次給 Pod 分配好 IP 之後要添加一條默認路由指向網關,否則沒法跨三層通訊。

ns1 --> ens160

$ ip netns exec ns1 ping -c 2 192.168.179.9

PING 192.168.179.9 (192.168.179.9) 56(84) bytes of data.

--- 192.168.179.9 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
複製代碼

這裏就遇到了我在上一篇文章開頭提到的問題。到目前爲止,整個實驗的拓撲結構以下:

其實也很好解決,額外建立一個 Macvlan 子接口,並把 ens160 的 IP 分給這個子接口,最後還要修改默認路由。

$ ip link add link ens160 mac0 type macvlan mode bridge
# 下面的命令必定要放在一塊兒執行,不然中間會失去鏈接
$ ip addr del 192.168.179.9/16 dev ens160 && \
  ip addr add 192.168.179.9/16 dev mac0 && \
  ip link set dev mac0 up && \
  ip route flush dev ens160 && \
  ip route flush dev mac0 && \
  ip route add 192.168.0.0/16 dev mac0 metric 0 && \
  ip route add default via 192.168.1.1 dev mac0 &
複製代碼

這裏必定不能 Down 掉 ens160,不然全部的子接口都將沒法工做。

如今就能 ping 通了:

$ ip netns exec ns1 ping -c 2 192.168.179.9

PING 192.168.179.9 (192.168.179.9) 56(84) bytes of data.
64 bytes from 192.168.179.9: icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from 192.168.179.9: icmp_seq=2 ttl=64 time=0.078 ms

--- 192.168.179.9 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.078/0.107/0.137/0.031 ms
複製代碼

相關文章
相關標籤/搜索