docs: add VPP Container Testbench example and lab
Adding a "VPP container testbench" (pair of Docker containers plus helper scripts to test Linux and VPP interfaces). Will be part of a larger set of labs/exercises/tutorials. Putting this baseline setup up for review first to see if the community sees use/value in it. If so, additional exercises using the testbench will be added gradually. Type: improvement Signed-off-by: Matthew Giassa <mgiassa@cisco.com> Change-Id: I582310f7355419e907d575f640482ca49cbb282f
This commit is contained in:

committed by
Dave Wallace

parent
342a5d472f
commit
4a0dd383cf
257
docs/usecases/vpp_testbench/labs/intro_to_vpp/index.rst
Normal file
257
docs/usecases/vpp_testbench/labs/intro_to_vpp/index.rst
Normal file
@ -0,0 +1,257 @@
|
||||
.. _sec_lab_vpp_intro:
|
||||
|
||||
Lab: Taking the VPP Container Testbench for a Spin
|
||||
==================================================
|
||||
|
||||
Assuming the reader has already acquired the test bench build scripts, let's
|
||||
start with building it.
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> make
|
||||
# Client image.
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--file Dockerfile.vpp_testbench \
|
||||
--build-arg HEALTHCHECK_PORT=8123 \
|
||||
--tag vpp-testbench-client:local \
|
||||
--target client_img \
|
||||
.
|
||||
...
|
||||
...
|
||||
...
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
--file Dockerfile.vpp_testbench \
|
||||
--build-arg HEALTHCHECK_PORT=8123 \
|
||||
--tag vpp-testbench-server:local \
|
||||
--target server_img \
|
||||
.
|
||||
...
|
||||
...
|
||||
...
|
||||
=> exporting to image
|
||||
=> => exporting layers
|
||||
=> => writing image
|
||||
=> => naming to docker.io/library/vpp-testbench-server:local
|
||||
0.0s
|
||||
Done.
|
||||
|
||||
|
||||
Now, let's start up our newly built images as a pair of containers. The various
|
||||
hashes throughout this document will differ from those shown in your own
|
||||
console (perfectly fine). First, let's assume there are no running containers
|
||||
on your system. We'll verify via ``docker ps``:
|
||||
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
|
||||
|
||||
OK: good initial conditions. Now, let's launch the containers:
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> make start
|
||||
# Create Docker bridge network.
|
||||
bash -c " . vpp_testbench_helpers.sh; host_only_create_docker_networks; "
|
||||
6e071e533e239380b2fe92d6e0844c42736ec186226fbb20d89706f9a80f935f
|
||||
# Launch the containers.
|
||||
bash -c " . vpp_testbench_helpers.sh; host_only_run_testbench_client_container
|
||||
vpp-testbench-client:local; host_only_run_testbench_server_container
|
||||
vpp-testbench-server:local; "
|
||||
720fed0a94fd715694d73a41317f05a3f36860a6d5ae54db2d7cb7f2dcaf7924
|
||||
ccf166993d09e399f7b10d372c47cc9e72ce6092ef70ea206c699263da844e1b
|
||||
# Entrypoint scripts will bring up the various links.
|
||||
# Use "docker ps" to check status of containers, see if their health
|
||||
# probes are working as expected (i.e. "health"), etc.
|
||||
|
||||
|
||||
Now, we can use ``docker ps`` to verify if the containers are up and running:
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
7d8e3ab35111 vpp-testbench-server:local "/entrypoint.sh" 3 seconds ago Up 2 seconds (health: starting) vpp-testbench-server
|
||||
cc01e64b12da vpp-testbench-client:local "/entrypoint.sh" 4 seconds ago Up 3 seconds (health: starting) vpp-testbench-client
|
||||
|
||||
|
||||
Looking good so far. However, note the "health" status of the containers.
|
||||
They're not yet ready. We can re-execute the ``docker ps`` command occasionally
|
||||
until the containers are ready:
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> while true; do docker ps; sleep 1; done
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
42e9bcea7c58 vpp-testbench-server:local "/entrypoint.sh" 1 second ago Up Less than a second (health: starting) vpp-testbench-server
|
||||
710287b40bd3 vpp-testbench-client:local "/entrypoint.sh" 2 seconds ago Up Less than a second (health: starting) vpp-testbench-client
|
||||
42e9bcea7c58 vpp-testbench-server:local "/entrypoint.sh" 30 seconds ago Up 29 seconds (health: starting) vpp-testbench-server
|
||||
710287b40bd3 vpp-testbench-client:local "/entrypoint.sh" 31 seconds ago Up 30 seconds (healthy) vpp-testbench-client
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
42e9bcea7c58 vpp-testbench-server:local "/entrypoint.sh" 31 seconds ago Up 30 seconds (healthy) vpp-testbench-server
|
||||
710287b40bd3 vpp-testbench-client:local "/entrypoint.sh" 32 seconds ago Up 31 seconds (healthy) vpp-testbench-client
|
||||
|
||||
|
||||
Not the most elegant approach, but it works. Onward.
|
||||
|
||||
.. note::
|
||||
|
||||
How would one automate this step so that we're not having to manually watch
|
||||
the console until the containers are ready? What's something that we could
|
||||
put into a script our our ``Makefile`` to poll the containers until they're
|
||||
ready to use?
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary><a>Spoiler</a></summary>
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# "Direct" approach.
|
||||
while true; do
|
||||
[ '"healthy"' = docker inspect --format "{{json .State.Health.Status }}" vpp-testbench-client] && break
|
||||
done
|
||||
|
||||
# Could also use awk/grep/etc. against the output of "docker ps".
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Now that our containers are up and running, let's drop a shell into the
|
||||
"client" container:
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> make shell_client
|
||||
|
||||
First, let's take a look at the default network configuration.
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
root@478ab126035e:/work# 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
|
||||
2: vxlan-vid-42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
|
||||
link/ether 3a:2c:19:cb:ca:35 brd ff:ff:ff:ff:ff:ff
|
||||
inet 169.254.10.1/24 scope global vxlan-vid-42
|
||||
valid_lft forever preferred_lft forever
|
||||
3: vpp-tap-0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN group default qlen 1000
|
||||
link/ether 02:fe:c5:52:63:12 brd ff:ff:ff:ff:ff:ff
|
||||
inet 169.254.12.1/24 scope global vpp-tap-0
|
||||
valid_lft forever preferred_lft forever
|
||||
635: eth0@if636: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
|
||||
link/ether 02:42:a9:fe:00:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0
|
||||
inet 169.254.0.1/24 brd 169.254.0.255 scope global eth0
|
||||
valid_lft forever preferred_lft forever
|
||||
|
||||
Let's also enumerate the interfaces managed by VPP. For the help of the reader,
|
||||
there is a shell function, ``vc``, which just launches ``vppctl`` with some
|
||||
helpful default arguments.
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
root@478ab126035e:/work# type vc
|
||||
vc is a function
|
||||
vc ()
|
||||
{
|
||||
vppctl -s "${VPP_SOCK}" "${@}"
|
||||
}
|
||||
root@478ab126035e:/work# vc
|
||||
_______ _ _ _____ ___
|
||||
__/ __/ _ \ (_)__ | | / / _ \/ _ \
|
||||
_/ _// // / / / _ \ | |/ / ___/ ___/
|
||||
/_/ /____(_)_/\___/ |___/_/ /_/
|
||||
|
||||
vpp# show int
|
||||
Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
|
||||
local0 0 down 0/0/0/0
|
||||
memif0/0 1 up 9000/0/0/0 rx packets 7
|
||||
rx bytes 521
|
||||
tx packets 7
|
||||
tx bytes 503
|
||||
tap0 2 up 9000/0/0/0 rx packets 7
|
||||
rx bytes 503
|
||||
tx packets 7
|
||||
tx bytes 521
|
||||
vpp#
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
One more exercise for the reader:
|
||||
1. From the client container, how would you ping the server container on the
|
||||
Linux-managed VXLAN interface?
|
||||
2. From the client container, how would you ping the server container on the
|
||||
VPP-managed TAP interface?
|
||||
3. A couple trivial web servers (using ``netcat``) are running on the server
|
||||
container. Besides looking at the ``Makefile`` recipes, how could one
|
||||
determine what ports and interfaces these servers are bound to, and
|
||||
how would one issue an HTTP GET query against them from the client
|
||||
container? (hint: you're allowed to log-in to the server container via
|
||||
``make shell_server``, and the ``netstat`` command may be of use).
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary><a>Spoiler</a></summary>
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
1. ping 169.254.10.2
|
||||
2. ping 169.254.12.2
|
||||
3. make shell_server
|
||||
netstat -tulpn
|
||||
tcp 0 0 169.254.12.2:8000 0.0.0.0:*
|
||||
LISTEN 47/nc
|
||||
tcp 0 0 169.254.10.2:8000 0.0.0.0:*
|
||||
LISTEN 34/nc
|
||||
exit
|
||||
make shell_client
|
||||
root@478ab126035e:/work# curl 169.254.10.2:8000
|
||||
HOST:14f0df855445
|
||||
DATE:Fri Nov 19 16:36:57 UTC 2021
|
||||
Hello from the Linux interface.
|
||||
root@478ab126035e:/work# curl 169.254.12.2:8000
|
||||
HOST:14f0df855445
|
||||
DATE:Fri Nov 19 16:37:04 UTC 2021
|
||||
Hello from the VPP interface.
|
||||
exit
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Now that we've done some quick exercises, let's clean-up the containers and
|
||||
their associated resources.
|
||||
|
||||
|
||||
.. code-block:: shell
|
||||
:linenos:
|
||||
|
||||
vagrant@ubuntu-focal$> make stop
|
||||
# Terminate the containers.
|
||||
bash -c " . vpp_testbench_helpers.sh; host_only_kill_testbench_client_container vpp-testbench-client:local; host_only_kill_testbench_server_container vpp-testbench-server:local; "
|
||||
vpp-testbench-client
|
||||
Error: No such container: vpp-testbench-client
|
||||
vpp-testbench-server
|
||||
Error: No such container: vpp-testbench-server
|
||||
# Cleanup Docker bridge network.
|
||||
bash -c " . vpp_testbench_helpers.sh; host_only_destroy_docker_networks; "
|
||||
vpp-testbench-net
|
||||
|
||||
That's it for this section.
|
||||
|
Reference in New Issue
Block a user