LoginSignup
12
7

More than 5 years have passed since last update.

GoBGP + GoPlane を使って Linux Network Namespace (netns) で EVPN / VXLAN

Last updated at Posted at 2018-09-29

環境

以下のような VXLAN ネットワークを構築します.
2 台の物理マシンそれぞれに Linux Network Namespace (netns) を作成し,それらを EVPN / VXLAN で接続します.

Underlay: 192.168.40.0/24
Overlay:  10.0.1.0/24
    _____________________       _____________________
   |  host1              |     |  host2              |
   |     ___________     |     |     ___________     |
   |    | netns5    |    |     |    | netns6    |    |
   |    |           |    |     |    |           |    |
   |    |   _____   |    |     |    |   _____   |    |
   |    |__|VXLAN|__|    |     |    |__|VXLAN|__|    |
   |       |_____|       |     |       |_____|       |
   |  10.0.1.5:   ____   |     |  10.0.1.6:   ____   | 
   |__________:__|p1p1|__|     |__________:__|p1p1|__|
              :  |____|192.168.40.5       :  |____|192.168.40.6
  ____________:_____|_____________________:_____|_______________
              :...........................:

Go

GoBGP や GoPlane を使うために Golang や Glide をインストールしておきます.

Golang

Getting Started - The Go Programming Language
公式サイトからダウンロードしてインストールします.
apt install 等を使うと古いバージョンの go がインストールされてしまうそうです.

$ wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.11.linux-amd64.tar.gz
$ echo 'export GOPATH=$HOME/.golang' >> $HOME/.profile
$ echo 'export PATH=$PATH:$GOPATH/bin:/usr/local/go/bin' >> $HOME/.profile
$ source $HOME/.profile

Glide

GoPlane の依存関係を解決するのに必要です.

$ sudo apt install git gcc
$ go get github.com/Masterminds/glide

GoPlane, GoBGP

順番にインストールしていきます.最後に $GOPATH/bin を確認しましょう.
goplane は GoBGP のデーモンである gobgpd を含んでいますが,今回は gobgp コマンドを使用するために gobgp も別途インストールします.

# goplane
$ go get github.com/osrg/goplane   # 警告が出力される
$ cd $GOPATH/src/github.com/osrg/goplane; glide install
$ go get github.com/osrg/goplane   # 再度入力する

# gobgp
$ go get github.com/spf13/cobra
$ go get github.com/kr/pretty
$ cd vendor/github.com/osrg/gobgp/gobgp
$ go install .

$ ls $GOPATH/bin
glide  gobgp  goplane

設定ファイル

2 台の物理マシンそれぞれに対して,netns を作成するシェルスクリプトと goplane 用の TOML ファイルを用意します.goplane ではオプションによって YAML や JSON を使用することもできます.

netns

veth0 が netns 内の仮想インタフェース,veth1 が netns 外の仮想インタフェースとなっています.
veth (virtual Ethernet) で L2 的に接続されているイメージです.

netns5.sh
ip netns add netns5
ip link add veth0 type veth peer name veth1
ip link set veth0 mtu 1450
ip link set veth1 mtu 1450
ip link set veth0 netns netns5
ip netns exec netns5 ifconfig lo up
ip netns exec netns5 ifconfig veth0 10.0.10.5 netmask 255.255.255.0 broadcast 10.0.10.255 up
netns6.sh
ip netns add netns6
ip link add veth0 type veth peer name veth1
ip link set veth0 mtu 1450
ip link set veth1 mtu 1450
ip link set veth0 netns netns6
ip netns exec netns6 ifconfig lo up
ip netns exec netns6 ifconfig veth0 10.0.10.6 netmask 255.255.255.0 broadcast 10.0.10.255 up

goplane

BGP Peer を確立するための IP アドレス (Underlay) や,VXLAN の TEP (Tunnel End point) となる VTEP インタフェース名を指定します.
以下のように VNI (VXLAN Network Identifier) として 10 を指定すると,ホスト上に br10 が自動生成されます.

goplane5.toml
[bgp.global.config]
    as = 65000
    router-id = "192.168.40.5"

[[bgp.neighbors]]
    [bgp.neighbors.config]
        neighbor-address = "192.168.40.6"
        peer-as = 65000
    [bgp.neighbors.ebgp-multihop.config]
        enabled = true
        multihop-ttl = 100
    [[bgp.neighbors.afi-safis]]
        [bgp.neighbors.afi-safis.config]
            afi-safi-name = "l2vpn-evpn"

[dataplane]
    type = "netlink"
[[dataplane.virtual-network-list]]
    member-interfaces = [ "veth1", ]
    vni = 10
    vxlan-port = 8472
    rd = "65000:10"
    vtep-interface = "vtep10"
    etag = 10
    sniff-interfaces = [ "veth1", ]
goplane6.toml
[bgp.global.config]
    as = 65000
    router-id = "192.168.40.6"

[[bgp.neighbors]]
    [bgp.neighbors.config]
        neighbor-address = "192.168.40.5"
        peer-as = 65000
    [bgp.neighbors.ebgp-multihop.config]
        enabled = true
        multihop-ttl = 100
    [[bgp.neighbors.afi-safis]]
        [bgp.neighbors.afi-safis.config]
            afi-safi-name = "l2vpn-evpn"

[dataplane]
    type = "netlink"
[[dataplane.virtual-network-list]]
    member-interfaces = [ "veth1", ]
    vni = 10
    vxlan-port = 8472
    rd = "65000:10"
    vtep-interface = "vtep10"
    etag = 10
    sniff-interfaces = [ "veth1", ]

実行

では,これらの設定ファイルを用いて実行していきます.

準備

もし /etc/sysctl.conf において net.ipv4.ip_forward=1 がコメントアウトされていたら外してください.

- #net.ipv4.ip_forward=1
+ net.ipv4.ip_forward=1

以下のように表示されれば OK です.これを忘れると思ったようにパケットが転送されません.

$ sudo sysctl -p
net.ipv4.ip_forward = 1

設定を変更したらシステムの再起動をしましょう.

ちなみに sysctl はカーネル内のパラメータを変更してくれるコマンドです.
ユーザ空間の話では無いので,問題が生じた時に原因を突き止めるのが難しいですね.
何度これに気づけず時間を溶かしたかわかりません.

netns の作成 (host1)

$ sudo ./netns5.sh

host2 では netns6.sh を実行します.

goplane の起動 (host1)

$ sudo $HOME/.golang/bin/goplane -f ./goplane5.toml
{"level":"info","msg":"Peer 192.168.40.6 is added","time":"2018-09-29T16:04:15+09:00"}
{"Topic":"Peer","level":"info","msg":"Add a peer configuration for:192.168.40.6","time":"2018-09-29T16:04:15+09:00"}
{"level":"info","msg":"VirtualNetwork 65000:10 is added","time":"2018-09-29T16:04:15+09:00"}
{"Key":"192.168.40.6","State":"BGP_FSM_OPENCONFIRM","Topic":"Peer","level":"info","msg":"Peer Up","time":"2018-09-29T16:04:28+09:00"}

こちらも同様に,host2 では goplane6.toml を使用してください.
正常に設定ができていれば,最後の行で "msg":"Peer Up" が表示されるはずです.

検証

正しく環境を構築できているかどうか確認していきます.

Peer

確かに StateEstabl になっていますね.

$ gobgp neigh
Peer            AS  Up/Down State       |#Received  Accepted
192.168.40.6 65000 00:02:58 Establ      |        2         2

疎通確認

netns 内から ping を打つと,Overlay で疎通していることが確認できます.

$ sudo ip netns exec netns5 ping 10.0.10.6 -c 3
PING 10.0.10.6 (10.0.10.6) 56(84) bytes of data.
64 bytes from 10.0.10.6: icmp_seq=1 ttl=64 time=0.588 ms
64 bytes from 10.0.10.6: icmp_seq=2 ttl=64 time=0.690 ms
64 bytes from 10.0.10.6: icmp_seq=3 ttl=64 time=0.574 ms

--- 10.0.10.6 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2039ms
rtt min/avg/max/mdev = 0.574/0.617/0.690/0.055 ms

このとき,以下のようなコマンドを実行すると,MAC アドレス情報を学習できていることがわかります.

$ gobgp global rib -a evpn
    Network                                                                                       Next Hop             AS_PATH              Age        Attrs
*>  [type:macadv][rd:0:0][esi:single-homed][etag:10][mac:2a:1f:8f:52:1f:60][ip:<nil>][labels:[10]]192.168.40.6                              00:08:16   [{Origin: i} {LocalPref: 100} {Extcomms: [VXLAN]}]
*>  [type:macadv][rd:0:0][esi:single-homed][etag:10][mac:3e:96:f0:e6:db:e9][ip:<nil>][labels:[10]]0.0.0.0                                   00:08:29   [{Origin: i} {Extcomms: [VXLAN]}]
*>  [type:multicast][rd:65000:10][etag:10][ip:192.168.40.5]0.0.0.0                                   00:08:29   [{Origin: i} {Pmsi: type: ingress-repl, label: 0, tunnel-id: 192.168.40.5} {Extcomms: [65000:10]}]
*>  [type:multicast][rd:65000:10][etag:10][ip:192.168.40.6]192.168.40.6                              00:08:16   [{Origin: i} {LocalPref: 100} {Extcomms: [65000:10]} {Pmsi: type: ingress-repl, label: 0, tunnel-id: 192.168.40.6}]

Bridge

最後に brctl でブリッジの様子を見てみましょう.
goplane の実行によって生成された br10 というブリッジグループに,veth1vtep10 が含まれています.
vtep10 においてカプセル化を解除されたフレームが br10 に転送され,veth を介して netns の内部に届きます.

$ brctl show br10
bridge name     bridge id               STP enabled     interfaces
br10            8000.caaf73c60baf       no              veth1
                                                        vtep10

参考

12
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7