LoginSignup
0

posted at

updated at

さくらのクラウドでSONiCの検証環境を作ってみる

さくらのアドベントカレンダー2022 8日目の記事です。

この記事は、SONiCをつかった検証環境が急に欲しくなった人向けに、「さくらのクラウドだけで作れるよ!」という内容のネタ記事です。

SONiCとは

紹介記事などがたくさんあるため、詳しい説明は他の解説記事を参照していただきたいのですが、SONiCはホワイトボックススイッチ向けのオープンソースなOSです。基本的にはホワイトボックススイッチにインストールして利用しますが、検証用として仮想マシン上でも利用が可能です。

さくらのクラウドとSONiC

さくらのクラウドはIaaSなクラウドサービスなので、一般的にはサーバーOSをインストールして利用することが多いかと思いますが、今回はこのさくらのクラウド上にSONiCをデプロイし、SONiCの検証環境を構築することを目指します。

やってみる

SONiCイメージのダウンロード

SONiCのビルド済みイメージは以下のサイトにて一覧でまとめられており、ダウンロードが可能です。

様々なプラットフォーム向けのイメージがありますが、sonic-vs.img.gz が仮想マシン用イメージですので、これをダウンロードします。今回は ブランチ 202205 を利用しました。

SONiCイメージの変換

ダウンロードしたSONiCのイメージはgzipで圧縮されているので、まずはgunzipで伸長します。しかしながら配布されているイメージはqcow2フォーマットなので、そのままではさくらのクラウドにインポートできません。そのため qemu-img コマンドを使ってrawフォーマットに変換します。

イメージの変換
gunzip sonic-vs.img.gz 
qemu-img convert -f qcow2 -O raw sonic-vs.img sonic-vs.raw

さくらのクラウドでアーカイブを作成する

さくらのクラウドでは、rawイメージをアップロードしてクラウドインスタンスとして実行することができる機能がありますので、以下ドキュメントを参考にrawイメージのアップロードを行います。rawイメージは16GB程度あったので、今回は余裕をもって40GBのブランクアーカイブを作成しました。

コントロールパネル上でブランクのアーカイブを作成するとcurlコマンドのサンプルが表示されるので、このままファイル名だけ変更してコピペすると簡単にアップロードできます。
アーカイブ作成.png

サーバーを作成する

SONiCイメージのアーカイブができたら、サーバーを作成します。今回は2Core 2GBプランで作成しました。
作成したSONiCのアーカイブは、「マイアーカイブ」で選択できます。
image.png

サーバー作成するときに注意点

NICの準仮想化モードを無効化しておきます。準仮想化モードでもSONiC上でインターフェースはみえるのですが、スピード表示がおかしくなったりするので無効化するのが良いと思います。

またNICはサーバー作成後に追加するので、とりあえず「切断」しておきます。
image.png

もう1点、デフォルトでは「その他のオプション」の箇所に「作成後すぐに起動」のチェックボックスが有効になっていますが、前述した通りサーバー作成後にNICを追加するのでチェックを外しておきます。(サーバー起動中はNICの追加ができないため)

image.png

スイッチの作成

SONiCサーバー(さくらのクラウドにデプロイされたものということで、あえてサーバーと呼びます)に接続するためのスイッチを作成します。さくらのクラウドにおいては、サーバーとサーバーを直結することができないため、SONiCサーバー同士を直結したいのであれば、直結したいリンク数分のスイッチを作成しておきます。

スイッチの作成では難しいところはありません。

NICの追加

作成したSONiCサーバーにNICを追加し、前項で作成したスイッチの接続を行います。サーバーへのNIC追加についても難しいところは無いと思います。

NIC追加における注意点

仮想マシンのSONiCイメージでは、先頭のNICがマネジメントポート(eth0)として認識されます。そのため、さくらのクラウドでNICを作成する場合でもその点を念頭においた上でNICを追加してください。

例えば以下のようにNICを追加した場合、
image.png

SONiC内部での認識名との対応は以下のようになります。

SONiCでの認識名 クラウドコンパネで表示される番号
eth0 0
Ethernet0 1
Ethernet4 2
Ethernet8 3
Ethernet12 4
Ethernet16 5

起動

NICが追加できたら起動です!「電源操作」ボタンからサーバーを起動しましょう。起動後はコンソールからSONiCの操作ができます。なおデフォルトのユーザー名とパスワードは以下のドキュメントに記載していますので参考にしてください。
https://github.com/sonic-net/SONiC/blob/master/doc/SONiC-User-Manual.md

起動後

あとは自由にSONiCを使うだけです!... というわけにはいかず、さくらのクラウドで利用するためにはSONiCでいくつかの設定が必要です。

MACアドレスの罠

さくらのクラウドでは、NICを追加すると固定のMACアドレスが割り振られます。

SONiCのデフォルトでは、 eth0 のMACアドレスが Ethernet0Ethernet4 といったインターフェースのMACアドレスとして利用されるようなのですが、前述した通り eth0 は先頭のNIC、Ethernet0 は先頭から2番めのNICですので、送信元MACアドレスがさくらのクラウドによってアサインされたものと異なることになってしまい、結果パケットがSONiCサーバーから出ていけません。

まとめると、起動直後の初期状態では以下のようになります。

SONiCでの認識名 クラウドコンパネで表示される番号 MACアドレス
eth0 0 クラウドコンパネ番号に応じたMACアドレス
eth1 1 クラウドコンパネ番号に応じたMACアドレス
eth2 2 クラウドコンパネ番号に応じたMACアドレス
Ethernet0 1 eth0と同じMACアドレス
Ethernet4 2 eth0と同じMACアドレス

MACアドレスを変更しよう

さくらのクラウドで利用するにあたっては、 Ethernet*** インターフェースのMACアドレスがマズいことがわかりましたので、これを変更しましょう。MACアドレスの変更は、 config コマンドでは行えないようなので、/etc/sonic/config_db.json を直接編集する必要があります。

設定例
$ cat /etc/sonic/config_db.json
(途中略)
    "INTERFACE": {
        "Ethernet0": {
            "mac_addr": "12:34:56:78:90:ab"
        },
        "Ethernet4": {
            "mac_addr": "11:22:33:44:55:66"
        },
        "Ethernet8": {
            "mac_addr": "aa:bb:cc:dd:ee:ff"
        }
    },
(後略)

設定後はリロードして反映させます。

$ sudo config reload -y

設定反映後 ip link コマンド等でMACアドレスを確認すると、変更されたことが確認できるかと思います。

さらなるMACアドレスの罠

EthernetインターフェースのMACアドレス変更により、パケットがSONiCから出ていけるようになりました!
あとは自由にSONiCを使うだけです! ... というわけにもいかず、なんだか挙動がおかしい状態となっています。

pingを実行してみよう

この状態で、シンプルに以下のように接続し、pingを実行してみます。

 ┌────────────────┐               ┌────────────────┐
 │ SONiC          │               │ Ubuntu         │
 │ 192.168.1.1/24 ├───────────────┤ 192.168.1.2/24 │
 └────────────────┘               └────────────────┘

Ubuntu側から実行すると2つ応答があります。おかしいですね、直結しているはずなのに。

ubuntu@ubuntu:~$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.34 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.34 ms (DUP!)
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.695 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.748 ms (DUP!)
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.580 ms

ためしにUbuntu側から1つだけ投げ、SONiC側でパケットキャプチャしてみると、

ubuntu@ubuntu:~$ ping -c1 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=6.79 ms

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.793/6.793/6.793/0.000 ms
ubuntu@ubuntu:~$

確かにSONiC側から2つのreplyが返されているようです。おかしいですね。

admin@sonic:~$ sudo tcpdump -nei Ethernet0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on Ethernet0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:00:39.254735 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 36, seq 1, length 64
08:00:39.254923 9c:a3:ba:2b:79:20 > 9c:a3:ba:29:e7:33, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 36, seq 1, length 64
08:00:39.254947 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 36, seq 1, length 64

これは eth1 でキャプチャしてみても同様です。

admin@sonic:~$ sudo tcpdump -nei eth1 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:00:57.316927 9c:a3:ba:2b:79:20 > 9c:a3:ba:29:e7:33, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 37, seq 1, length 64
08:00:57.317258 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 37, seq 1, length 64
08:00:57.317407 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 37, seq 1, length 64

この挙動、pingだけならまだしも?、たとえばBGPで接続しようとしたときに、SONiC側からackとrstが同時に返ってくるみたいな動きになります。こわい!

回避策

結論からいうと、上記の場合 Ethernet0 に対応した eth1 インターフェースのMACアドレスを手動で変更すると改善します。SONiCのインターフェースを介してのethインターフェースのMACアドレス変更方法は不明だったため、ip link コマンドで変更しました。

MACアドレスを変更する
$ sudo ip link set dev eth1 address ff:ee:dd:cc:bb:aa

eth1 のMACアドレスを変更することで、 Ethernet0 からの応答が1つになりました。

ubuntu@ubuntu:~$ ping -c 1 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.20 ms

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.202/1.202/1.202/0.000 ms
admin@sonic:~$ sudo tcpdump -nei Ethernet0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on Ethernet0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:02:09.401079 9c:a3:ba:2b:79:20 > 9c:a3:ba:29:e7:33, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 38, seq 1, length 64
08:02:09.401170 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 38, seq 1, length 64

eth1 でキャプチャしても1つで見えます。

admin@sonic:~$ sudo tcpdump -nei eth1 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:02:17.292052 9c:a3:ba:2b:79:20 > 9c:a3:ba:29:e7:33, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 39, seq 1, length 64
08:02:17.292469 9c:a3:ba:29:e7:33 > 9c:a3:ba:2b:79:20, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 39, seq 1, length 64

どうも IPアドレスをアサインした Ethernet0 に加えて eth1 からも応答を返しているように見えなくもない挙動ですが、実際のところ原因はわかりません。もし詳しい方がいらっしゃいましたら教えてください...。

ともあれ

MACアドレスの罠はあったものの、これでさくらのクラウド上でSONiCが利用できるようになりました!
さくらのクラウド上でSONiCによるIP Closな検証環境もちゃんと作れます。

image.png

ただ、普通にGNS3とかeve-ngとか使うほうが私はいいと思います。

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
What you can do with signing up
0