最初に
Containerlabによって、コンテナベースのNOS (ネットワークOS) を起動して、ネットワークを仮想的に構築することが可能です。このContainerlabにて、コミュニティSONiCのコンテナを動かしてBGPネットワークを構築してみました。ただし、SONiCコンテナをContainerlab上にて動かすためには、いくつかコツが必要でしたので、それらも含めて、この記事にて紹介いたします。
Containerlab環境の準備
今回はContainerlabを実験するために、Ubuntu 24.04 サーバ(Linux kernel version: 6.8.0-79-generi)の仮想マシンを用意しました。Containerlabを用意する前に、予めDockerもインストールしておきました(バージョンは28.4.0を使用)。
Containerlabの実行環境を構築するために、以下の場所から "containerlab_0.69.3_linux_amd64.tar.gz" のファイルをダウンロードします。
https://github.com/srl-labs/containerlab/releases/tag/v0.69.3
このファイルを以下のコマンドにて、解凍します。
https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds/945877/artifacts/1043900?branchName=202411&artifactName=sonic-buildimage.vs
これを、Containerlabを実行する仮想マシンにコピーし、以下のようにして、dockerのイメージをインストールします。
https://github.com/srl-labs/containerlab/releases/tag/v0.69.3
このファイルを以下のコマンドにて、解凍します。
tar xzvf containerlab_0.69.3_linux_amd64.tar.gz解凍すると、実行バイナリのcontainerlabが出力されます。これに以下のように実行権限を付与します。
chmod +x containerlabSONiCのコンテナのイメージは、以下の202411ブランチのコミュニティSONiCのデイリービルドから、sonic-vs.img.gzをダウンロードしておきます。
https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds/945877/artifacts/1043900?branchName=202411&artifactName=sonic-buildimage.vs
これを、Containerlabを実行する仮想マシンにコピーし、以下のようにして、dockerのイメージをインストールします。
gunzip sonic-vs.gz docker load < sonic-vs以下のように、docker-sonic-vsのdockerイメージが登録されていればOKです。
~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker-sonic-vs latest 0de6bd8d0aa5 21 hours ago 806MB
SONiCコンテナ用のContainerlab環境の準備から起動まで
今回は、以下のようにSONiCのコンテナを3つ起動し、BGPにてルーティングする環境を用意することにします。

図1:SONiCコンテナの試験構成図
上記のテスト環境を構築するために、以下を記述した sonic.yml ファイルを用意します。name: sonic01 topology: nodes: sonic01: kind: sonic-vs image: docker-sonic-vs:latest sonic02: kind: sonic-vs image: docker-sonic-vs:latest sonic03: kind: sonic-vs image: docker-sonic-vs:latest links: - endpoints: ["sonic01:Ethernet0", "sonic02:Ethernet0"] - endpoints: ["sonic02:Ethernet4", "sonic03:Ethernet0"]上記の"node"の部分で、dockerに登録したSONiCイメージを"docker-sonic-vs:latest"として指定しています。また、リンク接続の定義の中で、endpointsには、SONiC内部にて認識するインタフェース名のEthernet0とEthernet4を指定しています。このsonic.ymlファイルと実行バイナリファイルのcontainerlabを同一ディレクトリに置きます。まず以下のコマンドにてトポロジーを表示させてみます。
sudo ./containerlab graph -t sonic.yml上記のコマンドを実行した後に、Containerlabの仮想マシンのIPアドレスを使って、以下のURLにブラウザでアクセスしてみます。
http://(仮想マシンのIPアドレス):50080そうすると、以下のようにトポロジーをブラウザ上にて確認することができます。

図2:SONiCコンテナの試験構成のトポロジー表示
次に以下のコマンドにて、Containerlabの仮想ネットワークを起動します。sudo ./containerlab deploy -t sonic.yml以下のようなスクリーンログが出力されれば、SONiCコンテナの起動が完了しています。
$ sudo ./containerlab deploy -t sonic.yml 15:06:48 INFO Containerlab started version=0.69.3 15:06:48 INFO Parsing & checking topology file=sonic.yml 15:06:48 INFO Creating docker network name=clab IPv4 subnet=172.20.20.0/24 IPv6 subnet=3fff:172:20:20::/64 MTU=1500 15:06:49 INFO Creating lab directory path=/home/adpro/work/clab-sonic01 15:06:49 INFO Creating container name=sonic01 15:06:49 INFO Creating container name=sonic03 15:06:49 INFO Creating container name=sonic02 15:06:49 INFO Created link: sonic01:Ethernet0 -- sonic02:Ethernet0 15:06:49 INFO Created link: sonic02:Ethernet4 -- sonic03:Ethernet0 15:06:49 INFO Adding host entries path=/etc/hosts 15:06:49 INFO Adding SSH config for nodes path=/etc/ssh/ssh_config.d/clab-sonic01.conf You are on the latest version (0.69.3) +----------------------+------------------------+---------+-------------------+ | Name | Kind/Image | State | IPv4/6 Address | +----------------------+------------------------+---------+-------------------+ | clab-sonic01-sonic01 | sonic-vs | running | 172.20.20.2 | | | docker-sonic-vs:latest | | 3fff:172:20:20::2 | +----------------------+------------------------+---------+-------------------+ | clab-sonic01-sonic02 | sonic-vs | running | 172.20.20.3 | | | docker-sonic-vs:latest | | 3fff:172:20:20::3 | +----------------------+------------------------+---------+-------------------+ | clab-sonic01-sonic03 | sonic-vs | running | 172.20.20.4 | | | docker-sonic-vs:latest | | 3fff:172:20:20::4 | +----------------------+------------------------+---------+-------------------+"docker ps"コマンドでも、以下のように、SONiCコンテナが起動していることを確認できます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d2aee6ffb42a docker-sonic-vs:latest "/bin/bash" 4 minutes ago Up 4 minutes clab-sonic01-sonic02 83042366f17c docker-sonic-vs:latest "/bin/bash" 4 minutes ago Up 4 minutes clab-sonic01-sonic03 4b8e71be5aca docker-sonic-vs:latest "/bin/bash" 4 minutes ago Up 4 minutes clab-sonic01-sonic01
起動したSONiCコンテナにBGPの設定を投入
今回は、SONiCコンテナを起動させた後に、各SONiCコンテナに設定を手動で投入していきます。ただし、注意点として、コミュニティSONiCのSONiCコンテナの環境は、SONiCをコンテナ向けに最適化できていない部分がいくつかありました。そのため、今回のBGPネットワークを動作させるために、以下の対処を実施する必要があります。
- SONiCコマンドとは別に、ip linkコマンドにてインタフェースをupに設定
- SONiCコマンドとは別に、ip addコマンドにてインタフェースにIPアドレスを設定
- bgpdを手動で起動
docker exec -ti clab-sonic01-sonic01 bash上記にてsonic01コンテナのshellが起動したら、以下のコマンドを実行します。
ip link set Ethernet0 up /usr/lib/frr/bgpd -A 127.0.0.1 & config loopback add Loopback0 config interface ip add Loopback0 1.1.1.1/32 config interface ip add Ethernet0 10.1.1.1/24 ip add add 10.1.1.1/24 dev Ethernet0さらに、以下のコマンドを入力して、FRRのshellを起動し、設定変更のモードに移行します。
vtysh configure terminalFRRの設定変更モードに移行したら、以下の設定を投入します。
router bgp 65001 bgp router-id 1.1.1.1 no bgp ebgp-requires-policy bgp bestpath as-path multipath-relax bgp bestpath compare-routerid neighbor 10.1.1.2 remote-as 65002 address-family ipv4 unicast network 1.1.1.1/32 exit-address-family exit route-map RM_SET_SRC permit 1 set src 1.1.1.1 exit ip protocol bgp route-map RM_SET_SRC次に、ホストのshellに戻り、以下のコマンドを実行して、sonic02のコンテナに入ります。
docker exec -ti clab-sonic01-sonic02 bashsonic02のshellにて、以下のコマンドを実行します。
ip link set Ethernet0 up ip link set Ethernet4 up /usr/lib/frr/bgpd -A 127.0.0.1 & config loopback add Loopback0 config interface ip add Loopback0 1.1.1.2/32 config interface ip add Ethernet0 10.1.1.2/24 config interface ip add Ethernet4 10.1.2.1/24 ip add add 10.1.1.2/24 dev Ethernet0 ip add add 10.1.2.1/24 dev Ethernet4さらに、以下のコマンドを入力して、FRRのshellを起動し、設定変更のモードに移行します。
vtysh configure terminalFRRの設定変更モードに移行したら、以下の設定を投入します。
router bgp 65002 bgp router-id 1.1.1.2 no bgp ebgp-requires-policy bgp bestpath as-path multipath-relax bgp bestpath compare-routerid neighbor 10.1.1.1 remote-as 65001 neighbor 10.1.2.2 remote-as 65003 address-family ipv4 unicast network 1.1.1.2/32 exit-address-family exit route-map RM_SET_SRC permit 1 set src 1.1.1.2 exit ip protocol bgp route-map RM_SET_SRC次に、ホストのshellに戻り、以下のコマンドを実行して、sonic03のコンテナに入ります。
docker exec -ti clab-sonic01-sonic03 bashsonic03のshellにて、以下のコマンドを実行します。
ip link set Ethernet0 up /usr/lib/frr/bgpd -A 127.0.0.1 & config loopback add Loopback0 config interface ip add Loopback0 1.1.1.3/32 config interface ip add Ethernet0 10.1.2.2/24 ip add add 10.1.2.2/24 dev Ethernet0さらに、以下のコマンドを入力して、FRRのshellを起動し、設定変更のモードに移行します。
vtysh configure terminalFRRの設定変更モードに移行したら、以下の設定を投入します。
router bgp 65003 bgp router-id 1.1.1.3 no bgp ebgp-requires-policy bgp bestpath as-path multipath-relax bgp bestpath compare-routerid neighbor 10.1.2.1 remote-as 65002 address-family ipv4 unicast network 1.1.1.3/32 exit-address-family exit route-map RM_SET_SRC permit 1 set src 1.1.1.3 exit ip protocol bgp route-map RM_SET_SRC以上にて、SONiCコンテナへの設定の投入が完了しました。
SONiCのBGPの動作確認
3つのSONiCのコンテナの設定投入が完了しましたので、BGPの動作を確認します。まず、以下のコマンドにて、sonic01のFRRのshellを起動します。
docker exec -ti clab-sonic01-sonic01 vtysh"show bgp summary"コマンドにて、以下のように、sonic02とBGPネイバーとのセッションが確立していることを確認できました。
sonic01# show bgp summary IPv4 Unicast Summary: BGP router identifier 1.1.1.1, local AS number 65001 VRF default vrf-id 0 BGP table version 3 RIB entries 5, using 640 bytes of memory Peers 1, using 20 KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc 10.1.1.2 4 65002 6 6 3 0 0 00:00:46 2 3 N/A Total number of neighbors 1"show ip route"を実行すると、以下のように、sonic03のLoopbackインタフェースのIPアドレスの"1.1.1.3/32"がsonic02を経由してBGPにて学習していることを確認できました。
sonic01# show ip route Codes: K - kernel route, C - connected, L - local, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, f - OpenFabric, t - Table-Direct, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 1.1.1.1/32 is directly connected, Loopback0, 00:01:33 B>* 1.1.1.2/32 [20/0] via 10.1.1.2, Ethernet0, weight 1, 00:00:48 B>* 1.1.1.3/32 [20/0] via 10.1.1.2, Ethernet0, weight 1, 00:00:21 C>* 10.1.1.0/24 is directly connected, Ethernet0, 00:01:05試しに、sonic01からsonic03のLoobackインタフェースのIPアドレスの"1.1.1.3"に対してpingを実行すると、以下のように成功しました。
sonic01# ping 1.1.1.3 PING 1.1.1.3 (1.1.1.3) 56(84) bytes of data. 64 bytes from 1.1.1.3: icmp_seq=1 ttl=63 time=0.197 ms 64 bytes from 1.1.1.3: icmp_seq=2 ttl=63 time=0.084 ms 64 bytes from 1.1.1.3: icmp_seq=3 ttl=63 time=0.067 ms ^C --- 1.1.1.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2072ms rtt min/avg/max/mdev = 0.067/0.116/0.197/0.057 ms以上のように、SONiCコンテナをContainerlabにて起動して、BGPでのルーティングを試験できることを確認しました。実験が完了したら、以下のコマンドにて、Containerlabの環境を終了させることができます。
$ sudo ./containerlab destroy -t sonic.yml 15:14:49 INFO Parsing & checking topology file=sonic.yml 15:14:49 INFO Parsing & checking topology file=sonic.yml 15:14:49 INFO Destroying lab name=sonic01 15:14:52 INFO Removed container name=clab-sonic01-sonic02 15:14:52 INFO Removed container name=clab-sonic01-sonic01 15:14:52 INFO Removed container name=clab-sonic01-sonic03 15:14:52 INFO Removing host entries path=/etc/hosts 15:14:52 INFO Removing SSH config path=/etc/ssh/ssh_config.d/clab-sonic01.conf
最後に
まずは、Containerlab上にてコミュニティSONiCのコンテナイメージを起動できることを確認できました。ただし、本記事の中にも記載しましたように、コミュニティSONiCがコンテナ環境に最適化されていない部分があり、いくつかコマンドを追加で実行する必要がありました。また、SONiCコンテナにてBGPの試験(本記事の試験)は実行できましたが、Containerlab上にてSONiCコンテナを使ったVLANやVXLANの通信を実現することは、まだ成功できておりません(他にも必要な追加設定があると考えています)。コンテナを使った仮想ネットワークは、ホストOSのカーネルを使って通信を模擬しておりますため、Containerlab上にてSONiCコンテナを使った通信試験を実施できるようにするためには、コンテナ環境向けに何らか最適化(改造)が必要なのだと考えます。
Containerlabでは、コンテナだけでなく、KVM仮想マシンを使った検証する環境(vrnetlab)も用意されています。こちらであれば、SONiCのKVM仮想マシンを使って、Containerlabで試験を実施できる可能性がありますため、次回はvrnetlabを使った環境について記事にまとめたいと思います。
Containerlabでは、コンテナだけでなく、KVM仮想マシンを使った検証する環境(vrnetlab)も用意されています。こちらであれば、SONiCのKVM仮想マシンを使って、Containerlabで試験を実施できる可能性がありますため、次回はvrnetlabを使った環境について記事にまとめたいと思います。