自学内容网 自学内容网

Frrouting快速入门——北向接口事务cli与gRPC(二)

FRR北向接口架构

在前文《Frrouting快速入门——OSPF组网(一)》中我们使用frrouting内置的CLI工具vtysh实现了ospf组网通信。
old-nw-api
使用cli的方式配置网络的过程稍微有一点繁琐,但它整体还算简单且可靠,也是目前配置frrouting使用最多的方式。比如在sonic中,sonic的配置模块与FRR通信也使用的是CLI的方式进行配置的传递。
sonic介绍文档中的通信图如下:
sonic-frr

The Management framework will convert the YANG-based config data into requests that will write the configs into Redis DB. Redis DB events will trigger frrcfgd when the field frr_mgmt_framework_config set to “true” in the DEVICE_METADATA table, and then frrcfgd will configure FRR-ISIS using FRR CLI commands.

同时为了应对日益剧增的复杂网络环境,Frrouting也推出了新一代的北向接口来迎接挑战,FRR新北向架构为:
new-frr-api

在新的北向接口中,将原有的CLI直接调用daemon模块分成为单独的北向层,保留了原vtysh的同时还引入了YANG接口,使得上层无论是NETCONF、RESTCONF、VTY还是gRPC(openConfig)都能进行调用。

rollback-cli
同时还提供了事务CLI以支持命令的回滚与提交,彻底实现cli用的随心、敲的放心。

FRR-事务cli

熟悉数据库的小伙伴都知道,ACID是数据库事务的4大特性(Atomicity、Consistency、Isolation、Durability),确保数据库中的数据始终保持可靠和一致。

在frr中的Transactional Cli也具备着与数据库事物类似的功能。当开启frr的事务cli后,向cli中输入的命令将不会立即生效,直到输入commit命令才会真正进行提交。
未提交(commit)的配置命令frr的文档中称为candidate configuration。

开启事务cli

在frr的daemons配置中添加"–tcli"以代表此对应daemon将开启事务cli。
以ospfd为例,开启方式为:

vi /etc/frr/daemons
---
……
ospfd_options="  -A 0.0.0.0 --tcli"
……

即,在原ospfd_options后面添加--tcli,后再重启frr使得ospf的事务cli生效。

/etc/init.d/frr restart

再次查看ospf进程看到后面添加了tcli参数。

e603f681209f:/# ps -ef|grep ospf
   11 root      0:00 /usr/lib/frr/watchfrr zebra mgmtd ospfd staticd
   32 frr       0:00 /usr/lib/frr/ospfd -d -F traditional -A 127.0.0.1 --tcli

验证(VTY接口/telnet)

frr的事务cli提供了一些命令对配置进行操作,比如:

commit check
discard
configuration database max-transactions (1-100)
configuration load <file [<json|xml> [translate WORD]] FILENAME|transaction (1-4294967296)> [replace]
rollback configuration (1-4294967296)
show configuration candidate [<json|xml> [translate WORD]] [<with-defaults|changes>]
……

使用时需要的注意的是,以上事务cli的命令是无法在vtysh中使用的,如需要验证可以使用vty接口或其他北向接口。

官方描述为:The commands are available when a daemon is started using the transactional CLI (–tcli). Currently vtysh doesn’t support any of these new commands.

这里以VTY(Virtual Teletype lines,虚拟终端线路 )验证。各daemons提供的对应的vty端口为:

zebrasrv      2600/tcp                 # zebra service
zebra         2601/tcp                 # zebra vty
ripd          2602/tcp                 # RIPd vty
ripngd        2603/tcp                 # RIPngd vty
ospfd         2604/tcp                 # OSPFd vty
bgpd          2605/tcp                 # BGPd vty
ospf6d        2606/tcp                 # OSPF6d vty
ospfapi       2607/tcp                 # ospfapi
isisd         2608/tcp                 # ISISd vty
babeld        2609/tcp                 # BABELd vty
nhrpd         2610/tcp                 # nhrpd vty
pimd          2611/tcp                 # PIMd vty
ldpd          2612/tcp                 # LDPd vty
eigprd        2613/tcp                 # EIGRPd vty
bfdd          2617/tcp                 # bfdd vty
fabricd       2618/tcp                 # fabricd vty
vrrpd         2619/tcp                 # vrrpd vty

访问VTY接口前需要确保frr已开启了VTY密码认证,未配置密码的VTY无法连接到VTY接口。修改VTY接口配置可参照:Basic Config Commands
示例:

vi /etc/frr/frr.conf
---
hostname HyRouter
password 123456
enable password 123456

之后重启frr使配置生效,然后就可以使用telnet(vty)输入frr机器的ip访问frr的cli了。

frr容器与主机网络联通(可选)

本文中使用的frr为前文《Frrouting快速入门——OSPF组网(一)》中的容器frr,使用的是ovs桥接网络,访问时需确保网络可达。

root@puhaiyang-Computer:/home/puhaiyang# docker exec -it frr-01 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
10: eth1@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 12:83:29:86:68:65 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 11.11.0.2/24 scope global eth1
       valid_lft forever preferred_lft forever

root@puhaiyang-Computer:/home/puhaiyang# ovs-vsctl show
99985505-5873-467d-be09-54cc3a5b6eb7
    Bridge brConn
        Port brConn
            Interface brConn
                type: internal
        Port "76437ba4a63a4_l"
            Interface "76437ba4a63a4_l"
    ovs_version: "2.17.9"

给brConn网桥配置一个与frr容器同网段的ip

ip link set brConn up
ip addr add 11.11.0.1/24 dev brConn

并验证网络可达

root@puhaiyang-Computer:/home/puhaiyang# ping 11.11.0.2
PING 11.11.0.2 (11.11.0.2) 56(84) bytes of data.
64 bytes from 11.11.0.2: icmp_seq=1 ttl=64 time=0.445 ms
64 bytes from 11.11.0.2: icmp_seq=2 ttl=64 time=0.044 ms
64 bytes from 11.11.0.2: icmp_seq=3 ttl=64 time=0.072 ms

telnet验证tcli

使用telnet访问frr的cli,输入对应的ip、端口、密码。示例如下:

root@puhaiyang-Computer:/home/puhaiyang# telnet 11.11.0.2 2604
Trying 11.11.0.2...
Connected to 11.11.0.2.
Escape character is '^]'.

Hello, this is FRRouting (version 10.0_git).
Copyright 1996-2005 Kunihiro Ishiguro, et al.


User Access Verification

Password: 
e603f681209f> who
 vty[14] connected from 11.11.0.1.
e603f681209f> enable
Password: 
e603f681209f# configure private 
Warning: uncommitted changes will be discarded on exit.

e603f681209f(config)# commit check
% Candidate configuration validated successfully.

e603f681209f(config)# 

commit命令可以正确使用。

FRR-gRPC接口

frr-grpc

在新北向接口的加持下,frr中的gRPC接口的支持也为众多语言调用提供了方便,frr官方示例中也提供了c++、python、ruby语言的调用示例。

frr-gRPC接口配置需参考官方描述进行操作,不过这里有点坑的是:如果使用的是frr官方容器是无法正常运行gRPC的,因为缺少gRPC相关依赖。

开启FRR中gRPC的正确方式为:

To enable gRPC support one needs to add –enable-grpc when running configure. Additionally, when launching each daemon one needs to request the gRPC module be loaded and which port to bind to.

即,有两个条件:

  1. 运行configure时指定--enable-grpc参数
  2. 在对应的daemon参数中指定-M grpc:<port> 参数

否则可能会报如下错误信息:

frr_init: loader error: dlopen(/usr/lib/frr/modules/grpc.so): Error loading shared library /usr/lib/frr/modules/grpc.so: No such file or directory
frr_init: loader error: dlopen(grpc): Error loading shared library grpc: No such file or directory

--enable-grpc参数的设置则需要在使用frr源码编译才可以配置

源码编译frr

frr官方开发手册中介绍了Building FRR各操作系统的详细编译细节,笔者这里使用的是ubuntu20.04,找到对应的章节一步一步操作就行。
build-frr
步骤如下:

  1. 更新源并安装基础依赖
sudo apt update
sudo apt-get install \
   git autoconf automake libtool make libreadline-dev texinfo \
   pkg-config libpam0g-dev libjson-c-dev bison flex \
   libc-ares-dev python3-dev python3-sphinx \
   install-info build-essential libsnmp-dev perl \
   protobuf-c-compiler libprotobuf-c-dev \
   libcap-dev libelf-dev libunwind-dev
  1. 安装frr插件所需依赖

sudo apt-get install libgrpc+±dev protobuf-compiler-grpc
sudo apt install libsqlite3-dev
sudo apt-get install libzmq5 libzmq3-dev

  1. 源码编译安装libyang

apt install cmake
apt install libpcre2-dev

git clone https://github.com/CESNET/libyang.git
cd libyang
git checkout v2.1.148
mkdir build; cd build
cmake --install-prefix /usr \
      -D CMAKE_BUILD_TYPE:String="Release" ..
make
sudo make install

libyang安装截图如下:
libyang-build

安装成功后输入yangre -v进行验证

# yangre -v
yangre 2.1.148
  1. 源码编译安装sysrepo
git clone https://github.com/sysrepo/sysrepo.git
cd sysrepo/
git checkout v2.2.150
mkdir build; cd build
cmake --install-prefix /usr \
      -DCMAKE_BUILD_TYPE:String="Release" ..
make
sudo make install

执行sysrepoctl -l验证:sudo sysrepoctl -l
sysrepoctl
如报错:sysrepoctl: error while loading shared libraries: libsysrepo.so.7: cannot open shared object file: No such file or directory
可尝试使用ldd /usr/local/bin/sysrepoctl解决

在opendaylight中的MD-SAL类似于sysrepo,都可以对配置文件进行监听与通知。ODL-MD-SAL

  1. frr所需用户创建
sudo groupadd -r -g 92 frr
sudo groupadd -r -g 85 frrvty
sudo adduser --system --ingroup frr --home /var/run/frr/ \
   --gecos "FRR suite" --shell /sbin/nologin frr
sudo usermod -a -G frrvty frr

6. 配置并安装frr

git clone https://github.com/frrouting/frr.git frr
cd frr
./bootstrap.sh
./configure \
    --prefix=/usr \
    --includedir=\${prefix}/include \
    --bindir=\${prefix}/bin \
    --sbindir=\${prefix}/lib/frr \
    --libdir=\${prefix}/lib/frr \
    --libexecdir=\${prefix}/lib/frr \
    --sysconfdir=/etc \
    --localstatedir=/var \
    --with-moduledir=\${prefix}/lib/frr/modules \
    --enable-configfile-mask=0640 \
    --enable-logfile-mask=0640 \
    --enable-snmp=agentx \
    --enable-multipath=64 \
    --enable-user=frr \
    --enable-group=frr \
    --enable-vty-group=frrvty \
    --enable-grpc \
    --enable-config-rollbacks \
--enable-fpm \
    --enable-sysrepo \
    --with-pkg-git-version \
    --with-pkg-extra-version=-HaiyangFRRVersion
make
sudo make install

build-frr-gen

  1. 创建frr配置文件
sudo install -m 775 -o frr -g frr -d /var/log/frr
sudo install -m 775 -o frr -g frrvty -d /etc/frr
sudo install -m 640 -o frr -g frrvty tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
sudo install -m 640 -o frr -g frr tools/etc/frr/frr.conf /etc/frr/frr.conf
sudo install -m 640 -o frr -g frr tools/etc/frr/daemons.conf /etc/frr/daemons.conf
sudo install -m 640 -o frr -g frr tools/etc/frr/daemons /etc/frr/daemons
  1. 安装frr服务并启动
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo systemctl enable frr
systemctl start frr
  1. 验证frr状态

最后验证下frr是否启动成功

systemctl status frr.service
status-frr

显示active (running) 则代表frr源码编译并启动成功了

此时再来查看frr的模块目录,grpc等相关的包也会出现在/usr/lib/frr/modules/目录下

ls /usr/lib/frr/modules/
frr-modules

daemon开启gRPC

配置方式为在对应的daemon后面添加-M grpc:<port>参数,如port不填则默认为50051。配置示例如下:

vi /etc/frr/daemons
---
ospfd_options="  -A 127.0.0.1 -M grpc"

enable-grpc

配置完毕后可使用netstat命令验证gRPC服务端端口是否被监听

root@ubuntu20:~# netstat -anlp|grep 50051
tcp6       0      0 :::50051                :::*                    LISTEN      119269/ospfd  

python-gRPC远程管理frr

在frr的gRPC端口就绪后,就可以使用一种gRPC支持的编程语言进行连接访问了。尽管frr官网只提供了c++、python、ruby这3种语言的示例,实际上gRPC支持的语言远不止这些,感兴趣者可异步https://grpc.io/进行了解。
为了演示,笔者这里也选择python语言作为gRPC客户端进行调用。参考文档为:
https://docs.frrouting.org/projects/dev-guide/en/latest/grpc.html#python-example

涉及到的gRPC接口源码文件为:https://github.com/FRRouting/frr/blob/master/grpc/frr-northbound.proto

主要步骤如下:

  1. 安装python的grpc依赖

pip3 install grpcio grpcio-tools

  1. 使用frr/grpc目录中的frr-northbound.proto生成python代码
python3 -m grpc_tools.protoc  \
        --python_out=/tmp/frr-python \
        --grpc_python_out=/tmp/frr-python \
        -I $(pwd) \
        frr-northbound.proto

windows下替换为:

python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I $(pwd) frr-northbound.proto

执行后会生成如下两个python文件:

gen-grpc

接着编写客户端代码

import grpc
import frr_northbound_pb2
import frr_northbound_pb2_grpc

# 此处的ip填入frrouting服务的具体ip
channel = grpc.insecure_channel('192.168.2.10:50051')
stub = frr_northbound_pb2_grpc.NorthboundStub(channel)

# Print Capabilities
request = frr_northbound_pb2.GetCapabilitiesRequest()
response = stub.GetCapabilities(request)
print(response)

# Print Interface State and Config
request = frr_northbound_pb2.GetRequest()
request.path.append("/frr-interface:lib")
request.type = frr_northbound_pb2.GetRequest.ALL
request.encoding = frr_northbound_pb2.XML

for r in stub.Get(request):
    print(r.data.data)

Run一下:
grpc-code


原文地址:https://blog.csdn.net/puhaiyang/article/details/140449617

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!