APRESIA Technical Blog

SONiCコンテナをContainerlabにて動かしてみた

最初に

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
このファイルを以下のコマンドにて、解凍します。
tar xzvf containerlab_0.69.3_linux_amd64.tar.gz
解凍すると、実行バイナリのcontainerlabが出力されます。これに以下のように実行権限を付与します。
chmod +x containerlab
SONiCのコンテナのイメージは、以下の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を手動で起動
上記も考慮して、各コンテナに設定を入れていきます。なお、設定投入時に、いくつかWarningメッセージが出力されることがありますが、今回は無視します。 まず、以下のコマンドにてsonic01コンテナに入ります。
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 terminal
FRRの設定変更モードに移行したら、以下の設定を投入します。
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 bash
sonic02の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 terminal
FRRの設定変更モードに移行したら、以下の設定を投入します。
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 bash
sonic03の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 terminal
FRRの設定変更モードに移行したら、以下の設定を投入します。
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を使った環境について記事にまとめたいと思います。