暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

认识SONiC

非资深老网工 2021-10-02
9044

SONiC是什么?

Software for Open Networking in the Cloud,根据Azure/SONiC Wiki:

SONiC is an open source network operating system based on Linux that runs on switches from multiple vendors and ASICs.

SONiC是一个基于Linux开发的,可以运行在多个厂商交换机设备上的,通用的网络操作系统。所谓的“白盒”,就是厂商仅提供ASIC芯片和/或交换机硬件,用户在交换机上自己安装SONiC软件,而不再需要使用IOS-XE、XR、NX-OS等商业网络操作系统。

SONiC之所以能够成为一种大趋势,至关重要的一个原因是它采用了云原生架构,具备模块化可观察可部署可测试可替换可处理的特征。

Cloud Native

Container即进程

商业网络操作系统已经统治了行业几十年,不得不承认它们确实有些笨重了。虽然厂商也会宣称自己的NOS是模块化的,但每次升级都要升级整个NOS。如果遇到bug,能通过热补丁来修复的也比较少。

在操作系统内部,具体的功能都是由相应的进程来实现的。而Container就是进程。那么,将网络操作系统的进程都微服务化,以容器来做载体,就是很自然的事情了。

如果要升级,只需替换容器;想换一种控制面工具,例如把FRR换成GoBGP,也只需换个容器;如果要为交换机添加功能,新增一个容器即可...所有这些需求,都不需要通过升级网络操作系统来实现。另外,也有很多CI/CD工具,Automation工具,编排工具等存在于容器的生态系统。相比于传统NOS的开发模式,SONiC要敏捷很多。

SONiC Architecture

在这些容器当中,Database Container无疑是最重要的一个。

Redis缓存数据库

交换机/路由器在运行过程中,需要存储/读取很多数据。例如MAC地址表,ARP表,路由表等等。这些数据都存储在内存中,设备重启数据就被清空。

这些需求,完全符合Redis数据库的特征。

Redis是REmote DIctionary Server的缩写。顾名思义,它其实就是个大字典,用来存储key/value键值对。同时,字典的键值又支持多种数据类型,非常适合用来存储网络设备的各种表项。例如:

  • {MAC Address: Interface}
  • {IP Address: MAC Address}
  • {Prefix: Next hop}

Redis的数据都存储在内存中,所以其性能可以满足高速网络设备的业务处理需求。Redis还可以为每个键设置生存时间,生存时间到期之后自动删除键,这也适合网络协议的各种计时器。

SONiC的各种容器通过TCP协议,向Redis-server容器更新并订阅自己感兴趣的数据,并根据数据的变化做出相应的Action。

可编程芯片和SAI

交换机作为一种工作在下三层的网络设备,其很多功能都依赖于ASIC的Pipeline。传统ASIC的Pipeline都是固定的,不能修改,将商用NOS换成SONiC的价值不大。但是可编程芯片和SONiC则是珠联璧合。

如果新增的网络功能需要修改ASIC的Driver和/或Pipeline才能实现,有2种方式来达成目的。一种是直接通过ASIC的SDK来修改;一种是通过调用SAI API来修改。

SAI and SDK

Switch Abstraction Interface就是一种API。SAI之于SDK,等同于Netconf/OpenConfig之于CLI。

各家芯片的SDK都不一样,但是SAI定义了一个标准的API,开发者不需要关心ASIC厂商的SDK是怎样定义的,通过标准的API就可以适配不同的ASIC。

怎样上手SONiC?

找台硬件交换机去安装SONiC显然不适合所有人,好在SONiC项目提供了Virtual Switch。目前有2个渠道下载SONiC Virtual Switch。

一个是Azure/SONiC官方的release,但是非常不推荐。首先,现在下载很麻烦。需要先访问:

https://github.com/Azure/sonic-buildimage

然后点击相应的release:

Official vSONiC release

然后点击下面截图的1 published

Azure DevOps

然后点击最右侧3个点,下载全部的buildimage,接近8GB。下载之后解压缩,再把sonic-vs.img.gz
文件挑出来。

buildimage download link

这还不是最坑的。最坑的是,Azure官方的Sonic-VS镜像有些问题,container很少,有些container无法running。

所以建议选择Broadcom提供的Sonic-VS image。目前是3.1.2版本。

如果你的模拟器是GNS3,可以看这个Blog:

https://www.linkedin.com/pulse/how-build-vsonic-lab-kamran-naqvi/

如果你和我一样使用EVE,请继续看下去。

Step 1

下载mssonic.yml
文件到templates
文件夹。注意,不要修改文件名!另外,如果你的EVE版本比较高,可能会看到子目录,例如/opt/unetlab/html/templates/intel
,或者/opt/unetlab/html/templates/amd
,取决于你的CPU架构。

root@bjlab-eve-ng:~# cd /opt/unetlab/html/templates/
root@bjlab-eve-ng:/opt/unetlab/html/templates# wget https://raw.githubusercontent.com/ercintorun/MsSonicEveNG/main/mssonic.yml

Step 2

/opt/unetlab/addons/qemu/
目录新建一个以mssonic
开头的文件夹,然后下载image。

root@bjlab-eve-ng:/opt/unetlab/html/templates# cd /opt/unetlab/addons/qemu/
root@bjlab-eve-ng:/opt/unetlab/addons/qemu# mkdir mssonic-bcm-3.1.2
root@bjlab-eve-ng:/opt/unetlab/addons/qemu# cd mssonic-bcm-3.1.2/
root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# wget https://github.com/Broadcom/sonic-VirtualSwitch/releases/download/3.1.2/sonic-vs-3.1.2.img.gz

Step 3

解压缩

root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# ls
sonic-vs-3.1.2.img.gz
root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# gunzip sonic-vs-3.1.2.img.gz 
root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# ls
sonic-vs-3.1.2.img

Step 4

重命名镜像文件为virtioa.qcow2

root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# mv sonic-vs-3.1.2.img virtioa.qcow2
root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# ls
virtioa.qcow2

Step 5

最后一步,修改权限。你有可能会看到下面的报错:

root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# /opt/unetlab/wrappers/unl_wrapper -a fixpermissions
PHP Warning:  scandir(/opt/unetlab/addons/iol/bin/): failed to open dir: No such file or directory in /opt/unetlab/html/includes/init.php on line 159
PHP Warning:  scandir(): (errno 2): No such file or directory in /opt/unetlab/html/includes/init.php on line 159
PHP Warning:  Invalid argument supplied for foreach() in /opt/unetlab/html/includes/init.php on line 169

打开/opt/unetlab/html/includes/init.php
文件查看,发现是第159行,在/opt/unetlab/addons/iol/
路径下找不到bin/
目录。进而导致第169行foreach()
运行失败。

        $ioldir=scandir("/opt/unetlab/addons/iol/bin/");

修改之:

        $ioldir=scandir("/opt/unetlab/addons/iol/");

顺便再给templates
增加一行mssonic

if (!isset($node_templates)) {
        $node_templates = Array(
//...(snip)
                'mssonic'               =>      'Azure SONiC',

再重新修改权限,Done!

root@bjlab-eve-ng:/opt/unetlab/addons/qemu/mssonic-bcm-3.1.2# /opt/unetlab/wrappers/unl_wrapper -a fixpermissions

SONiC Virtual Switch Get Started

可以在EVE里面添加SONiC节点了。

Add SONiC node on EVE

默认用户名/密码为admin
/YourPaSsWoRd

BCM的SONiC VS有一点不好,默认开启ZTP。在登陆之后,需要复制粘贴下面的命令,关闭ZTP。

sudo config ztp disable
y

另外要注意,这个VS镜像启动非常慢,大概需要3分钟左右。如果看不到CLI有输出,一定要保持耐心!

在看到下面的输出之后,说明系统启动成功,然后要保存刚才关闭ztp
的配置:

Verifying if all services have started
Services are started

Reload complete!

admin@sonic:~$ sudo config save -y
Running command: /usr/local/bin/sonic-cfggen -d --print-data > /run/tmpx8Va8K
Running command: mv -f /run/tmpx8Va8K /etc/sonic/config_db.json
Running command: sync;sync;sync
25740 Bytes written

我们可以看到SONiC运行了Docker Daemon Engine,并且有20个容器正在运行:

admin@sonic:~$ docker info
Client:
 Debug Mode: false

Server:
 Containers: 20
  Running: 20
  Paused: 0
  Stopped: 0
 Images: 20
 Server Version: 19.03.0-rc3
 Storage Driver: overlay2
...(Snip)
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
...(Snip)
 Kernel Version: 4.9.0-11-2-amd64
 Operating System: Debian GNU/Linux 9 (stretch)
...(Snip)

WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

20个容器都没有向外发布端口:

admin@sonic:~$ docker container ps -a
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS               NAMES
af39746f15a2        docker-snmp-sv2:latest               "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           snmp
5d376f9c1e23        docker-nat:latest                    "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           nat
28e2b5aecbf0        docker-lldp-sv2:latest               "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           lldp
9974af0d0d34        docker-l2mcd:latest                  "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           l2mcd
52e55abedcd3        docker-sflow:latest                  "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           sflow
74bf2f97ea88        docker-dhcp-relay:latest             "/usr/bin/docker_ini…"   56 minutes ago      Up 47 minutes                           dhcp_relay
17af023bcb29        docker-stp:latest                    "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           stp
21973d589166        docker-sonic-mgmt-framework:latest   "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           mgmt-framework
681c537fb9f9        docker-udld:latest                   "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           udld
ad9880041964        docker-tam:latest                    "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           tam
30c35c009b97        docker-sonic-telemetry:latest        "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           telemetry
d111bfc17cb0        docker-router-advertiser:latest      "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           radv
e77eae01a3d1        docker-syncd-vs:latest               "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           syncd
5a668b291c4d        docker-fpm-frr:latest                "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           bgp
32de08edb562        docker-teamd:latest                  "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           teamd
4968776bf0dd        docker-iccpd:latest                  "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           iccpd
fa0fd78e3f8e        docker-orchagent:latest              "/usr/bin/supervisord"   56 minutes ago      Up 48 minutes                           swss
fa5e6e97475f        docker-platform-monitor:latest       "/usr/bin/docker_ini…"   56 minutes ago      Up 47 minutes                           pmon
5c882b8b0136        docker-vrrp:latest                   "/usr/bin/supervisord"   56 minutes ago      Up 47 minutes                           vrrp
d0e87a1a91c3        docker-database:latest               "/usr/local/bin/dock…"   2 months ago        Up 50 minutes                           database

Docker的Network都是默认的:

admin@sonic:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
9034d41a3896        bridge              bridge              local
97abc007a292        host                host                local
5ce32d4ce005        none                null                local

来看看SONiC默认的接口和IP地址:

admin@sonic:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 50:07:00:02:00:00 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5207:ff:fe02:0/64 scope link flags 4000
       valid_lft forever preferred_lft forever
...(Snip)
23: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:05:be:b0:7a brd ff:ff:ff:ff:ff:ff
    inet 240.127.1.1/24 brd 240.127.1.255 scope global docker0
       valid_lft forever preferred_lft forever

进去database
容器,再看看它的接口和IP地址:

admin@sonic:~$ docker container exec -it database sh
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 50:07:00:02:00:00 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5207:ff:fe02:0/64 scope link flags 4000
       valid_lft forever preferred_lft forever
...(Snip)
23: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:05:be:b0:7a brd ff:ff:ff:ff:ff:ff
    inet 240.127.1.1/24 brd 240.127.1.255 scope global docker0
       valid_lft forever preferred_lft forever

和SONiC宿主机完全一样,说明这些容器的Network都是host
模式。那么lldp
bgp
等容器向Redis-server读写数据的时候,实际上就是用本地的回环地址来通信。进一步确认一下:

# ps -ef | grep redis
root        29     1  0 15:40 pts/0    00:00:00 /usr/bin/redis-server 127.0.0.1:63970
root        31     1  3 15:40 pts/0    00:00:12 /usr/bin/redis-server 127.0.0.1:6379
root        33     1  0 15:40 pts/0    00:00:01 /usr/bin/redis-server 127.0.0.1:63793
root        34     1  0 15:40 pts/0    00:00:01 /usr/bin/redis-server 127.0.0.1:63792
root        81    67  0 15:47 pts/1    00:00:00 grep redis

这说明SONiC就是一个有很多接口的Linux,它上面运行的容器都处于同一个网络命名空间。当然,如果有特定的需求,用户也可以创建bridge
网络模式的容器。

SONiC可以在Linux模式下完成管理和配置工作,如果要查看命令行帮助,需要使用-?
代替网工习惯使用的?

admin@sonic:~$ show -?
Usage: show [OPTIONS] COMMAND [ARGS]...

  SONiC command line - 'show' command

Options:
  -?, -h, --help  Show this message and exit.

Commands:
  aaa                   Show AAA configuration
  acl                   Show ACL related information
  arp                   Show IP ARP table
...(Snip)

也可以进入交换机CLI,操作起来就和商用交换机完全相同了:

admin@sonic:~$ sonic-cli
sonic#
  clear        Clear commands
  configure    Enter configuration mode
  copy         Perform file copy operations
...(Snip)
sonic# config t
sonic(config)# ?
  aaa                    AAA configuration
  authentication         Configure authentication modes
...(Snip)

如果要进一步学习,可以阅读SONiC Wiki

https://github.com/Azure/sonic-utilities/blob/master/doc/Command-Reference.md

还有这个Youtube频道:

https://www.youtube.com/love2network


文章转载自非资深老网工,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论