SRv6实践项目(四):基于YANG的配置下发

 在本章节,主要是了解YANG是什么,以及基于YANG下发配置的工作原理:

1.什么是YANG

在介绍之前,为了给大家一个最直观的感受,我们打开yang工具,它被打包成一个容器了,可以轻松的使用,可以看到,docker run了一个yang工具容器:

make yang-tools

 当我们打开一个范例demo-port.yang和它的yml格式文件,我们可以看见它的一个格式:

pyang -f tree demo-port.yang
  • 里面的对象有的可读可写,有的只读
  • 加了一个*的表示这个对象是个序列
  • 在yang的树叶上可以看到,每一个叶子成员(leaf)都是最基本的单元,他们有被定义一些值,比如number或者boolean这些
  • 文件中,我们可以看到一个模型,就是一颗以树组织的结构,里面描述了每个节点是什么(description),每个节点的属性是什么以及这个属性基于什么属性(description,base)
  • 也包括了一些节点的其他信息(namespace,description)
  • 对于序列节点(list)它的每个成员的属性是什么(key),通过基本的属性(type)以及对属性的定义(typedef )可以得到任何属性,一些节点可能还有一些可重用的属性(grouping),定义时只需要使用(uses)即可
  • 在yang中,一个模型可以被理解为多个成员(container)的集成,每个成员包括了自身的一些属性等等

module demo-port {

    // YANG Boilerplate 
    yang-version "1";
    namespace "https://opennetworking.org/yang/demo";
    prefix "demo-port";
    description "Demo model for managing ports";
    revision "2019-09-10" {
      description "Initial version";
      reference "1.0.0";
    }

    // Identities and Typedefs
    identity SPEED {
      description "base type for port speeds";
    }

    identity SPEED_10GB {
      base SPEED;
      description "10 Gbps port speed";
    }

    typedef port-number {
      type uint16 {
        range 1..32;
      }
      description "New type for port number that ensure the number is between 1 and 32, inclusive";
    }


    // Reusable groupings for port config and state 
    grouping port-config {
        description "Set of configurable attributes / leaves";
        leaf speed {
            type identityref {
                base demo-port:SPEED;
            }
            description "Configurable speed of a switch port";
        }
    }

    grouping port-state {
        description "Set of read-only state";
        leaf status {
            type boolean;
            description "Number";
        }
    }

    // Top-level model definition
    container ports {
      description "The root container for port configuration and state";
        list port {
            key "port-number";
            description "List of ports on a switch";

            leaf port-number {
                type port-number;
                description "Port number (maps to the front panel port of a switch); also the key for the port list";
            }

            // each individual will have the elements defined in the grouping
            container config {
                description "Configuration data for a port";
                uses port-config; // reference to grouping above
            }
            container state {
                config false; // makes child nodes read-only
                description "Read-only state for a port";
                uses port-state; // reference to grouping above
            }
        }
    }
}

 让我来做个总结,YANG模型以一种树形结构描述了一个类的全面的性质,但是你一定很好奇,它只是描述了一个东西它应该有哪些属性,定义了这个属性是什么类型,比如,我们用一个YANG去描述一个网络设备,要对这个设备进行操作需要知晓设备的各个属性全貌,以及哪些是只读的(state),哪些是可以改的(config),但是,要对这个设备进行具体的操作,我们需要有值啊,所以,我们要对YANG定义出来的模型,为数据附上这些值。

bash-4.4# pyang -f tree \
    -p ietf \
    -p openconfig \
    -p hercules \
    openconfig/interfaces/openconfig-interfaces.yang \
    openconfig/interfaces/openconfig-if-ethernet.yang  \
    openconfig/platform/* \
    openconfig/qos/* \
    openconfig/system/openconfig-system.yang \
    hercules/openconfig-hercules-*.yang  | less

小插曲:在这里,我们可以看看openconfig-interfaces.yang的长相,openconfig-interfaces.yang是网络中对接口配置的一个模型描述,很长很长,可以看到里面有一些参数,比如in_pkts进数据包和enable使能。

 2.基于YANG的数据编码

刚刚我们知道,以面向对象的角度比喻:YANG它只是定义了一个类的格式,没有给他赋值,为了给这个类具体的值,我们需要实例化它,它被实例化出来的对象,它可以以XML的形式存在,也可以以JSON的形式存在,这无所谓,只要它的数据遵循类的规范即可。

pyang -f sample-xml-skeleton demo-port.yang

把YANG转换成xml的格式会是这样的(但是还是没有赋值):

 转成DSDL格式会是这样的: 

pyang -f dsdl demo-port.yang | xmllint --format -

接下来,我们将研究使用协议缓冲区(protobuf)对数据进行编码,protobuf编码是一种比XML更紧凑的二进制编码,并且可以为几十种语言自动生成库。我们可以使用ygot的proto_generator从我们的YANG模型中生成protobuf消息

proto_generator -output_dir=/proto -package_name=tutorial demo-port.yang

生成了两文件,一个用来紧凑的描述demo_port,一个用来描述属性

  • /proto/tutorial/demo_port/demo_port.proto
  • /proto/tutorial/enums/enums.proto
less /proto/tutorial/demo_port/demo_port.proto

less /proto/tutorial/enums/enums.proto

3.基于YANG的gNMI下发配置

在第二节中,我们知道了基于YANG的数据编码格式,在本小节中,我们讨论如何通过基于YANG的配置,操作数据平面。

首先make start打开我们的mininet,然后我们需要让两个主机ping通,不知道如何ping通的,可以回到上一个博客查看。

现在,我们来到gNMI client CLI,通过它实现对数据平面的配置,首先看看它的数据以及组织形式,这里的get只是总览一下数据平面中leaf1的信息。

util/gnmi-cli --grpc-addr localhost:50001 get /

 上面的命令没有对数据编码进行修正,通过以下指令进行解码

util/gnmi-cli --grpc-addr localhost:50001 get / | util/oc-pb-decoder | less

 在这里,我们看到了request中,我们要看的数据的类型是可config的,用的解码是PROTO

 

 现在来看看leaf1的eth3的接口的信息

util/gnmi-cli --grpc-addr localhost:50001 get \
    /interfaces/interface[name=leaf1-eth3]/config

 请求部分,可以看到客户端是如何请求的,请求的数据组织格式:

有3个信息,使能:true,健康监测:GOOD,loopback模式:false(它不是一个环回接口,它是一个实体接口,要转发到别的主机上的)

 

 接下来,我们订阅一些数据,我们用到如下指令:

util/gnmi-cli --grpc-addr localhost:50001 \
    --interval 1000 sub-sample \
    /interfaces/interface[name=leaf1-eth3]/state/counters/in-unicast-pkts
  •  util/gnmi-cli:gNMI的命令行
  • --grpc-addr localhost:50001 grpc的服务器也就是在leaf1的BMV2
  • --interval 1000 sub-sample 1000毫秒一次收集信息
  • /interfaces/interface[name=leaf1-eth3]/state/counters/in-unicast-pkts 记录接口leaf1-eth3它的状态栏中关于计数器的部分,这个计数器专门指的是in-unicast-pkts,顾名思义,进来leaf1-eth3的单播数据包

现在,每秒都在更新一次数据,因为我们订阅了它:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值