目录


文章目录

  • 目录
  • 部署架构
  • 安装步骤
  • 安装 ETCD
  • 容器部署 VPP & VPP Agent
  • 编译安装 VPP Agent
  • Managing the VPP Agent
  • etcdctl
  • REST API
  • NB Configuration
  • SB Dumps
  • Execute VPP CLI commands through a REST API
  • VPP CLI
  • Agentctl


部署架构

FD.io/VPP — VPP Agent — Quickstart_json

安装步骤

安装 ETCD

  • docker run on console
$ docker run --rm --name etcd -p 2379:2379 -e ETCDCTL_API=3 quay.io/coreos/etcd /usr/local/bin/etcd -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379
$ docker ps -f name=etcd
  • etcdctl
$ docker exec -it etcd etcdctl version
etcdctl version: 3.3.8
API version: 3.3

$ docker exec -it etcd etcdctl endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 571.723µs

容器部署 VPP & VPP Agent

$ docker pull ligato/vpp-agent

$ docker run -it --rm --name vpp-agent -p 5002:5002 -p 9191:9191 --privileged ligato/vpp-agent
INFO[0000] Starting agent version: v0.0.0-dev BuildDate= CommitHash= loc="agent/agent.go(134)" logger=agent
INFO[0000] Agent started with 2 plugins (took 1ms) loc="agent/agent.go(179)" logger=agent
__
_ _____ ___ _______ ____ ____ ___ / /_
| |/ / _ \/ _ /___/ _ '/ _ '/ -_/ _ / __/ vpp-agent v3.3.0-alpha-28-g412190182
|___/ .__/ .__/ \_'_/\_' /\__/_//_\__/ Wed May 12 15:07:23 UTC 2021 (24 days ago)
/_/ /_/ /___/ root@buildkitsandbox (go1.15.2 linux/amd64)
...

$ docker exec -it vpp-agent ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 15:11 pts/0 00:00:01 vpp-agent-init
root 16 1 8 15:11 pts/0 00:06:05 /usr/bin/vpp -c /etc/vpp/vpp.con
root 17 1 0 15:11 pts/0 00:00:05 /bin/vpp-agent --config-dir=/opt
root 838 0 0 16:21 pts/1 00:00:00 ps -ef

可见,VPP Data Plane 和 VPP Agent 都运行在容器中了。其中,

  • VPP CLI:5050
  • VPP Agent REST API:9191

编译安装 VPP Agent

编译安装适用开发环境。

  • 程序编译
$ git clone https://github.com/ligato/vpp-agent
$ git checkout release/3.2.x
$ make cmd

$ ll cmd/
total 24
drwxr-xr-x 5 root root 4096 Jun 7 15:58 ./
drwxr-xr-x 17 root root 4096 Jun 7 16:12 ../
drwxr-xr-x 6 root root 4096 Jun 7 16:15 agentctl/
drwxr-xr-x 3 root root 4096 Jun 7 16:15 vpp-agent/
drwxr-xr-x 2 root root 4096 Jun 7 16:15 vpp-agent-init/
...
  • 配置
$ mkdir /opt/vpp-agent-conf-dir/


$ cat /opt/vpp-agent-conf-dir/etcd.conf
insecure-transport: true
dial-timeout: 1s
endpoints:
- "<etcd-server-ipaddr>:2379"


$ cat /opt/vpp-agent-conf-dir/grpc.conf
endpoint: 0.0.0.0:9111


$ cat /opt/vpp-agent-conf-dir/supervisor.conf
programs:
- name: "vpp"
executable-path: "/usr/bin/vpp"
executable-args: ["-c", "/etc/vpp/vpp.conf"]
- name: "agent"
executable-path: "/opt/vpp-agent/cmd/vpp-agent/vpp-agent"
executable-args: ["--config-dir=/opt/vpp-agent-conf-dir"]
hooks:
- cmd: "/opt/vpp-agent-conf-dir/init_hook.sh"


$ cat /opt/vpp-agent-conf-dir/init_hook.sh
#!/usr/bin/env bash

terminate_process () {
PID=$(pidof $1)
if [[ ${PID} != "" ]]; then
kill ${PID}
echo "process $1 terminated"
fi
}

if [[ "${SUPERVISOR_PROCESS_NAME}" = "agent" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then
terminate_process vpp-agent-init
fi

if [[ "${SUPERVISOR_PROCESS_NAME}" = "vpp" && "${SUPERVISOR_PROCESS_STATE}" = "terminated" ]]; then
terminate_process vpp-agent-init
firoot
  • 启动 VPP Agent
$ ./vpp-agent -config-dir=/opt/vpp-agent-conf-dir
__
_ _____ ___ _______ ____ ____ ___ / /_
| |/ / _ \/ _ /___/ _ '/ _ '/ -_/ _ / __/ vpp-agent v3.2.0
|___/ .__/ .__/ \_'_/\_' /\__/_//_\__/ Mon Jun 7 16:12:39 CST 2021 (20 minutes ago)
/_/ /_/ /___/ root@upf1 (go1.14.2 linux/amd64)
...
  • 测试:又返回则表示 VPP Agent 和 VPP 连接成功。
$ curl -X POST 'http://localhost:9191/vpp/command?Content-Type=application/json' \
-H 'Content-Type: application/json' \
-d '{"vppclicommand":"show version"}'

Managing the VPP Agent

etcdctl

通过 etcdctl CLI 来操作 VPP Agent 在 ETCD 中的数据,继而来完成对 VPP Agent 的管理。在 ETCD 中,VPP Agent 相关的记录会使用 ​​/vnf-agent/​​ 前缀。

  • 查看 VPP Agent 相关的记录:
$ docker exec -it etcd etcdctl get --prefix /vnf-agent/

/vnf-agent/vpp1/check/status/v1/agent
{"build_version":"v3.3.0-alpha-28-g412190182","build_date":"Wed May 12 15:07:23 UTC 2021","state":"OK","start_time":"1622905897","last_change":"1622905903","last_update":"1622906057","commit_hash":"4121901","plugins":[{"name":"govpp","state":"OK"},{"name":"VPPAgent","state":"OK"},{"name":"etcd","state":"OK"},{"name":"vpp-ifplugin","state":"OK"}]}
/vnf-agent/vpp1/check/status/v1/plugin/VPPAgent
{"state":"OK","last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/etcd
{"state":"OK","last_change":"1622905902","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/govpp
{"state":"OK","last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-abfplugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-aclplugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-dnsplugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-ifplugin
{"state":"OK","last_change":"1622905903","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-ipsec-plugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-l2plugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-l3plugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-natplugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-srplugin
{"last_change":"1622905897","last_update":"1622906057"}
/vnf-agent/vpp1/check/status/v1/plugin/vpp-wg-plugin
{"last_change":"1622905897","last_update":"1622906057"}
  • 创建一个 loopback interface 并配置 IP address:
docker exec etcd etcdctl put /vnf-agent/vpp1/config/vpp/v2/interfaces/loop1 \
'{"name":"loop1","type":"SOFTWARE_LOOPBACK","enabled":true,"ip_addresses":["192.168.1.1/24"]}'

docker exec etcd etcdctl get /vnf-agent/vpp1/config/vpp/v2/interfaces/loop1
  • Configure a bridge domain.
docker exec etcd etcdctl put /vnf-agent/vpp1/config/vpp/l2/v2/bridge-domain/bd1 \
'{"name":"bd1","forward":true,"learn":true,"interfaces":[{"name":"loop1"}]}'

docker exec etcd etcdctl get /vnf-agent/vpp1/config/vpp/l2/v2/bridge-domain/bd1

REST API

  • API 文档:https://docs.ligato.io/en/latest/api/api-vpp-agent/

VPP Agent 实现了两个 API:

  1. NB API​:外部客户端与 VPP Agent 进行交互的接口,客户端可以完成 VPP configuration management。
  2. SB API​:VPP Agent 与 VPP Data Plane 进行交互的接口。完成 VPP Data Plane 的 Events、Notifications 和 Configuration Dumps 操作。

通过 VPP Agent 提供的 REST plugin 我们可以完成以下两类操作:

  1. NB configuration management
  2. SB VPP configuration dumps

NB Configuration

NB Configuration 用于完成对 VPP Data Plane 的查询、配置、验证等操作。

  • PUT /configuration
  • PUT /configuration?replace
  • GET /configuration
  • GET /info/configuration/jsonschema
  • POST /configuration/validate

例如:

$ cat loop-bd.yaml

vppConfig:
interfaces:
- name: "loop1"
type: SOFTWARE_LOOPBACK
enabled: true
ipAddresses:
- 192.168.1.1/24
bridgeDomains:
- name: bd1
forward: true
learn: true
interfaces:
- name: loop1

$ curl -X PUT -H "Content-Type: application/yaml" --data-binary @loop-bd.yaml http://localhost:9191/configuration

SB Dumps

SB Dumps 仅用于获取 VPP Data Plane 的运行时配置信息。详细见 API 文档。

例如:查询 VPP Interfaces 配置信息。

  • GET /dump/vpp/v2/interfaces
  • GET /dump/vpp/v2/interfaces/loopback
  • GET /dump/vpp/v2/interfaces/ethernet
  • GET /dump/vpp/v2/interfaces/vxlan
  • GET /dump/vpp/v2/interfaces/tap
  • GET /dump/vpp/v2/interfaces/memif
  • GET /dump/vpp/v2/interfaces/afpacket
$ curl -X GET http://localhost:9191/dump/vpp/v2/interfaces

{
"0": {
"interface": {
"name": "UNTAGGED-local0",
"type": "SOFTWARE_LOOPBACK",
"physAddress": "00:00:00:00:00:00"
},
"interface_meta": {
"sw_if_index": 0,
"sub_sw_if_index": 0,
"l2_address": "AAAAAAAA",
"internal_name": "local0",
"dev_type": "local",
"is_admin_state_up": false,
"is_link_state_up": false, # Link 状态信息。
"link_duplex": 0,
"link_mtu": 0,
"mtu": [
0,
0,
0,
0
],
"link_speed": 0,
"sub_id": 0,
"tag": "",
"dhcp": null,
"vrf_ipv4": 0,
"vrf_ipv6": 0,
"pci": 0
}
}
}

Execute VPP CLI commands through a REST API

VPP Agent REST Plugin 还支持通过 REST API 来执行 VPP CLI 指令,例如:

$ curl -X POST 'http://localhost:9191/vpp/command?Content-Type=application/json' \
-H 'Content-Type: application/json' \
-d '{"vppclicommand":"show version"}'

"vpp v20.09.0-63~g8b4bd27d6~b83 built by root on cec6be71f709 at 2021-04-21T19:48:17\n"

VPP CLI

通过 VPP CLI 直接操作 VPP Data Plane。

$ docker exec -it vpp-agent vppctl -s localhost:5002
_______ _ _ _____ ___
__/ __/ _ \ (_)__ | | / / _ \/ _ \
_/ _// // / / / _ \ | |/ / ___/ ___/
/_/ /____(_)_/\___/ |___/_/ /_/

vpp# show inter addr
local0 (dn):

# or
$ docker exec -it vpp-agent vppctl -s localhost:5002 show interface address
local0 (dn):

Agentctl

Agentctl 是 VPP Agent 的 CLI Tool,通过 Agentctl 来操作 VPP Agent,继而完成对 VPP Data Plane 的操作。

$ docker exec -it vpp-agent agentctl --help
Usage: agentctl [options] COMMAND


__ __ __
___ ____ ____ ___ / /_____/ /_/ /
/ _ '/ _ '/ -_) _ \/ __/ __/ __/ /
\_,_/\_, /\__/_//_/\__/\__/\__/_/
/___/

COMMANDS
config Manage agent configuration
dump Dump running state
generate Generate config samples
import Import config data from file
kvdb Manage agent data in KVDB
log Manage agent logging
metrics Get runtime metrics
model Manage known models
report Create error report
service Manage agent services
status Retrieve agent status and version info
values Retrieve values from scheduler
vpp Manage VPP instance

OPTIONS:
--config string Path to config file.
--config-dir string Path to directory with config file.
-D, --debug Enable debug mode
-e, --etcd-endpoints strings Etcd endpoints to connect to, default from ETCD_ENDPOINTS env var (default [127.0.0.1:2379])
--grpc-port int gRPC server port (default 9111)
-H, --host string Address on which agent is reachable, default from AGENT_HOST env var (default "127.0.0.1")
--http-basic-auth string Basic auth for HTTP connection in form "user:pass"
--http-port int HTTP server port (default 9191)
--insecure-tls Use TLS without server's certificate validation
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")
--service-label string Service label for specific agent instance, default from MICROSERVICE_LABEL env var
-v, --version Print version info and quit

Run 'agentctl COMMAND --help' for more information on a command.

$ docker exec -it vpp-agent agentctl config get
netallocConfig: {}
linuxConfig: {}
vppConfig: {}