README
¶
Raven
Ry's Apparatus for Virtual Encodable Networks
Raven is a tool for rapidly designing, deploying and managing virtual networks. Raven networks are:
- designed programatically through a javascript API
- managed through a command line interface
- materialized and deployed by a libvirt enabled backend
When you need more infrastructure level fidelity than a Kubernetes deployment and more programmability than a collection of Vagrantfiles, raven may be of use to you.
Here is an example of a network model
zwitch = {
'name': 'nimbus',
'image': 'cumulusvx-3.7',
'os': 'linux',
'mounts': [{ 'source': env.PWD, 'point': '/tmp/here' }]
};
nodes = Range(2).map(i => ({
'name': `n${i}`,
'image': 'debian-buster',
'os': 'linux',
'mounts': [{ 'source': env.HOME, 'point': '/tmp/home'}]
}));
links = [
...Range(2).map(i => Link(`n${i}`, 'eth0', 'nimbus', `swp${i+3}`)),
]
topo = {
'name': '2net',
'nodes':[...nodes],
'switches': [zwitch],
'links': links
};
Getting started
Raven has been tested on
- Fedora 27, 28
- Ubuntu 16.04, 18.04, 18.10
- Debian stretch, buster
Contributions to support other distros welcome!
Installing on Debian / Ubuntu
The following works on Debian Bullseye
Add the following to /etc/apt/sources.list.d/mergetb.list
.
deb [arch=amd64] https://pkg.mergetb.net/debian bullseye main
and then
sudo apt update
sudo apt install raven
For Ubuntu the CI server kicks out Ubuntu packages for new release. You can browse to the package files here.
Installing on other Linux distros
You'll need to have Ansible installed on your system. SELinux systems (Fedora) will also need the SELinux python bindings. Raven is built primarily in Go and must be built from your systems GOPATH
.
git clone git@gitlab.com:mergetb/tech/raven
cd raven
# Ensure your distros packages are up to date before running this!
sudo ansible-playbook setup.yml
Warning: this process installs raven from the binary produced by the CI server associated with this repository. It is known to work for Ubuntu 18.04, Debian Buster and Fedora 28 but may not work on older platforms.
iptables / nftables
nftables
is beginning it's takeover. This is happening in debian-buster.
Systems running both the iptables and nftables kernel modules can run into
troubles. Connectivity issues have been observed on systems with both sets of
kernel modules running. Symptoms include
- no external nat
- no connectivity between hosts
Remedy 1 - Configure your distro to use the 'legacy' iptables toolchain
On Debian you can do this via.
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
This has the nice property that Docker still works, which is not the case in Remedy 2.
Remedy 2 - Go all in on nftables
Some features of Raven will likely not work correctly with this remedy, as Raven internally uses iptables for a few things. It may work on distros like Debian that have iptables to nftables translation systems in place such as iptables-legacy
sudo rmmod ip_tables --force
sudo rmmod iptable_nat
SELinux Considerations
If you are running an SELinux system, you will need to make sure that any directory you run raven from is traversable by root
. On Fedora this means chmod a+x $HOME
if you are running from within your home directory. Home directories on SELinux based systems are typically not traversable by root.
Building
You will need at least Go 1.11 to build. Raven uses Go modules for dependency management, so you will need a proper modules build environment setup.
make
sudo make install
Tinkering
First start the raven application (you must be root due to the way we use libvirt)
sudo su
cd raven/models/2net
# build the raven system (creates virtual machines and network descriptions)
rvn build
# deploy the virtual system
rvn deploy
# show the status of the virtual nodes
rvn status
# wait for the virtual nodes and switches to come up
rvn pingwait nimbus n0 n1
# show the status of the virtual nodes now that they are up
# (you will see IP addresses)
rvn status
# configure the virtual nodes and switches
rvn configure
# while configure is running, you can open up another shell window and type in
# rvn status to see how things are progressing
# run some ad-hoc config on a node
rvn ansible n1 config/n1.yml
# ssh into a node
eval $(rvn ssh n0)
# ping n1 from n0 through the switch nimbus (see config/n1.yml)
# to see how IP addresses re set up
rvn@n0: ping 10.47.0.2
To run a full build, test deploy cycle run the following.
./launch.sh
The launch.sh script is fairly self explanatory and concretely shows many of the capabilities of raven.
Cross-topology communication
A libvirt network is an island. Only the virtual machines defined on the network are allowed to speak to each other. This is the desired behavior in most cases. However, in some situations you may one on Raven topology to talk to another. Raven assigns /24 test-network subnets sequentially to topologies so if you have two topologies you'll have these two subnets.
- 172.22.0.0/24
- 172.22.1.0/24
If you want these subnets to be able to communicate, you can add the following rules on the host.
iptables -I FORWARD -s 172.22.1.0/24 -d 172.22.0.0/24 -j ACCEPT
iptables -I FORWARD -s 172.22.0.0/24 -d 172.22.1.0/24 -j ACCEPT
This will piggy-back on existing libvirt NAT rules, but allow comms between the two subnets across Raven topologies. A similar approach can be used for networks for which Raven does not assign IP addresses, just subsititue in the appropriate source/dest subnet info.