vJunos Deployment on KVM¶
A comprehensive user guide on how to successfully deploy and use vJunos-switch and vJunosEvolved on KVM (one of the most popular virtualized environments in the community, alongside EVE-NG and GNS3).
Summary¶
Juniper is releasing a new virtual test product named vJunos that is targeted at data center and campus switching use cases.
vJunos comes in two flavours for the initial release: - vJunos-switch : based on the legacy Junos OS running on Free BSD, and targeted for data center and campus switching use cases - vJunosEvolved based on the newer Junos OS Evolved on top of Linux, and targeted for both routing and switching use cases
This post provides a comprehensive user guide on how to successfully deploy and use vJunos-switch and vJunosEvolved on KVM. This other post explains how to deploy vJunos-switch and vJunosEvolved on EVE-NG.
Introduction¶
The steps used on our setup and detailed in the rest of this post are:
- Prepare their KVM environment for vJunos deployment
- Deploy vJunos
- Troubleshoot some of the most common deployment issues
- Build a simple EVPN-VXLAN topology using multiple vJunos instances managed by Juniper Apstra
- Verify your work
We will try to provide comprehensive explanations about the procedure and explain all the steps. However, for the sake of brevity, we will not address a few topics that might be of interest for some users, like using vJunos with ZTP. This can be the topic of a separate post in the future.
Let's get started.
Prepare the Environment¶
The server we will use in our deployment has the following:
- Server: Supermicro SYS-220BT-HNC9R
- CPUs: 128 x Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz
- RAM: 256 GB DDR4
- SSD: 1 TB
- OS: Ubuntu 20.04.5 LTS
We will first verify that this server supports virtualization, then we will install KVM components.
Update packages¶
Check if the Server Supports Hardware Virtualization¶
In our case, our server has 128 CPUs that have "vmx" or "svm" flags enabled to support virtualization
Check if VT is Enabled in the BIOS¶
This is done by installing and using the "kvm-ok" tool, which is included in the cpu-checker package.
Now that we have checked that the server is ready, we can proceed and install KVM.
Install KVM¶
There are several packages that need to be installed, some are mandatory and some are optional
- qemu-kvm: software that provides hardware emulation for the KVM hypervisor.
- libvirt-bin: software for managing virtualization platforms.
- bridge-utils: a set of command-line tools for configuring ethernet bridges.
- virtinst : a set of command-line tools for creating virtual machines.
- virt-manager: provides an easy-to-use GUI interface and supporting command-line utilities for managing virtual machines through libvirt.
We included all mandatory and optional packages in the same install command
Verify installation¶
Now that KVM is installed and up and running, we can proceed and deploy vJunos.
Deploy vJunos-switch¶
Pre-requisite Tips¶
There are a few pieces of information to know about Juniper vJunos before you start building your virtual lab. These are the most important ones:
- vJunos is not an official Juniper Networks product, it is a test product, so it is neither sold nor officially supported by Juniper's TAC. If you run into any issues, we encourage you to report it in the Juniper community. Juniper Networks makes vJunos available for free to download and use with no official support.
- It is recommended to use vJunos for feature testing only, and not for any scaling or performance tests. For the same reasons, it is not recommended to use vJunos in production environments. It is recommended to join the Juniper Labs Community if you need further support on vJunos
- A vJunos instance is composed of one single VM that nests both Control and Data Planes, hence some limitations of deploying options of vJunos. Please see vJunos FAQ.
- Default login of vJunos is root with no password.
- vJunos must be provisioned with at least one vNIC for the management, and as many vNICs as there are data plane interfaces.
- It is our experience that vNICs are more reliable if you configure them to use virtio driver. We have not experienced any issue when using this driver, instead of the other ones, like e1000.
- There is no license to use vJunos, so all features should work without entering any license key, even though some features will trigger warnings about missing licenses. You can ignore those warning and move on.
- You need to have an account with Juniper support to have access to the download page. It is recommended to select "Evaluation User Access" that gives you access to evaluation software. If you are a new user, beware that creating a new user account is not immediate, as it goes through an approval process that might take up to 24 hours, so plan accordingly.
Now that all these notes are read and well understood, we're ready to deploy our first vJunos, knowing all limitations and restrictions.
Download vJunos Images¶
vJunos-switch image can be downloaded from the official Juniper support page https://support.juniper.net/support/downloads/?p=vjunos.
vJunosEvolved image can be downloaded from the official Juniper support page https://support.juniper.net/support/downloads/?p=vjunos-evolved
At the time of writing this post, the latest vJunos release is 23.1R1.8.
Note that in addition to vJunos images, you will also need a Linux image to deploy host VMs to be connected to vJunos instances for testing purposes. The exact type and version of these Linux instances are not important, but it must support installing specific packages to run protocols like LLDP and LACP. For this post, we used cirros-0.5.2.
Deploy vJunos-switch Instances¶
For this post, we will deploy the following fabric topology

Given that the downloaded vJunos files are disk images (.qcow2) it is a best practice to make as many copies as there are vJunos instances to avoid attaching all vJunos instances to the same disk image. This will take up some disk space, so plan your setup accordingly. We will put these disk image copies under the default directory /var/lib/libvirt/images. The following bash script will help make these copies.
copy-images.sh:
Using "qemu-img create" instead of a simple "cp" allows to have much smaller disk images, as shown below, which is good if you have a limited disk space.
We will start by creating the networks of the above topology first then the create the virtual machines after, because this way, VMs can be effectively connected to the appropriate networks immediately when they boot up. It is our experience that when we create the VMs first, then the networks after, we need to reboot the VMs once more for connections to networks to take effect.
To deploy a network, we start by creating its xml definition file. The following is a sample network xml file.
leaf1-spine1.xml:
then we execute the following commands to create a persistent network, and configure it to start automatically when libvirt daemon is restarted
Note that we used "net-define" and not "net-create" because the former makes the network persistent, whereas the latter makes it transient, that is non persistent across reboots.
The reverse commands to delete the above network are the following:
The previous commands will preserve the xml definition file, so you can edit it again and start over.
We used the following bash script to create all the networks we need in this lab setup
create-networks.sh:
The following bash script deletes all created networks with the previous script, in case you need to do so
delete-networks.sh:
After completing the previous task for all networks with your preferred method, you should see the following output
Deploy vJunos¶
There are multiple ways to deploy vJunos instances on KVM, one can name at least these three:
- virt-manager : deploy all VMs by using KVM GUI
- virsh-define: this method requires creating an XML definition file of each VM
- virt-install : CLI based method. One needs only to specify the deployment parameters of VMs
virt-manager procedure works fine for small setups. The GUI is very intuitive, which makes this method less error prone. However, like most GUI-based tools, it does not scale well if you need to create a large number of VMs.
virsh-define is very error prone because the XML file is quite large and it is very easy to make syntax mistakes. It is highly recommended that you start with an existing XML file from a previously created and working VM, and not start from scratch, if you use virsh-define. If you do not have any XML file to start with, you can create a VM by using the virt-manager, then copy its XML file located under /etc/libvirt/qemu/, or generate it by using the command
Even though all 3 methods would work just fine, depending on the user's familiarity with each method. In this port we're going to use virt-install, because we can put all commands inside a shell script, and repeat the operation if anything is not working as expected. Like with any new product, it might take a few tries before you get everything right with all the parameters.
Below is a sample virt-install command to deploy one of the vJunos-switch VMs:
Below is a sample virt-install command to deploy one of the vJunosEvolved VMs:
The highlighted lines are important for a successful deployment of a vJunosEvolved instance.
Below is a sample virt-install command to deploy one of the Cirros VMs:
A few comments about the command above:
--serial ptyallows you to access the guest VM's console from the host by usingvirsh console <vm_name>. Another alternative to allow access to guest VMs from the host is via telnet by specifying, for example--serial tcp,host=:4001,mode=bind,protocol=telnet, where 4001 is a tcp port that is specific to the VM, so it must be different for each guest VM.- The first interface of the VM is connected to
macvtapbridge that connects to host's interface eno1. This way the VM will be connected to the same management network than than the host itself, so we can reach it directly without jumping to the host. Other alternatives to how to manage the guest VM include the following:
--network type=direct,source=eno1,source_mode=bridge,model=virtio : this works the same way than macvtap bridge --network network=**default**,model=virtio : this way, the VM will be connected to KVM's internal default network and will get an IP address via DHCP from the default 192.168.122.0/24 subnet. To make the VM reachable from outside, we need to configure the host for port forwarding.
We used a bash script to create the VMs needed in this lab setup. The script is not provided here for brevity, but it executes the above virt-install command for as many times as there are VMs with the specific parameters and interfaces.
Note that we provisioned each vJunos with 4 vCPU and 5 GB of RAM.
You can delete a VM by using the following commands, for example
Once all VMs are deployed, you should see the following output:
At this point, all VMs should be up and running, and should be reachable directly from the outside without jumping on the host. However, vJunos management interfaces run DHCP by default, so we do not know at this point what IP addresses have been assigned to vJunos instances. To that end, we must console to the instances either from the host by using "virsh console" or telnet to the specific port, as explained above, or by using virt-manager.
The vJunos instances should reach each other once we complete the basic Junos configurations. Let's verify that.
Verifications¶
Try accessing the console of one of the vJunos-switch instances by using the following command
The default credentials are "root" and no password.
Enable Junos CLI and verify that the dataplane is online
Verify that 10 "ge" interfaces are present
A vJunos-switch instance comes up with 10 ge-x/x/x interfaces by default, but you can configure it with up to 96 ge-x/x/x interfaces by using the following command:
On the other hand, a vJunosEvolved instance comes up with 12 xe-x/x/x interfaces by default, and that cannot be changed by CLI.
Try accessing the console of one of the Cirros host VMs
If you used an Ubuntu image for the host VMs, you may not have access to the console with "virsh console". If that's the case, access the console with virt-manager and make the following changes in the guest VM:
edit file etc/default/grub of the guest VM and configure the following lines
then
At this point, you should be able to access the Ubuntu VMs with "virsh console".
Now that all looks good and we're ready to start configuring our devices to build the EVPN-VXLAN topology shown above.
Configuration¶
Base vJunos-switch Configuration¶
When a vJunos-switch instance comes up, it has a default configuration that needs to be cleaned up before we proceed further. For example, the default configuration is ready for ZTP, which we will not address in this post.
The following configuration should be the bare minimum needed to start using a vJunos-switch instance, and you can delete everything else:
A bare minimum vJunosEvolved configuration is very similar, except the management interface name, which is re0:mgmt-0 for vJunosEvolved instead of fxp0 for vJunos-switch.
Once all vJunos-switch instances have the minimum configuration above entered and committed, let us verify that the topology is built properly by verifying LLDP neighborship.
The output above shows that LLDP neighborship are not forming, and that the instance is transmitting LLDP packets but is not receiving any. This is expected because, by default, IEEE 802.1D compliant bridges Linux bridges do not forward frames of link local protocols, like LLDP and LACP. For reference, the destination MAC address used by LLDP is 01-80-C2-00-00-0E.
Let's checking the default value of the Group Forwarding Mask of one of the bridges
The zero value means that this bridge does not forward any link local protocol frames. To change the bridge's behavior and force it to forward LLDP frames we need to set the 15th bits of this 16-bit mask, specified by the rightmost 0xE in the MAC address, that is writing the hex value 0x4000, or decimal value 2^14=16,384, to group_fwd_mask. Let's try it on all bridges of this host.
We used the following shell script to accomplish that. Please adjust bridge and interface numbers to your specific case ; use "brctl show" command to get the number of virbrX bridges and vnetX interfaces
overwrite-mask.sh:
At this point, LLDP should be working fine on all vJunos-switch instances, as shown below
Note that LLDP neighborship is not forming between leaf-1 and host-1, and that's because Linux does not include LLDP package by default. It can be installed on some Linux distributions, but not on Cirros, that we used here.
Adding Apstra Controller¶
Now that all vJunos instances are deployed and working properly, we will onboard them on Apstra server and deploy the fabric.
Please note the following important requirements:
- You need Juniper Apstra version 4.1.1 or higher to manage vJunos instances ; at the time of writing this post, we used Juniper Apstra version 4.1.2-269
- By default, vJunos-switch comes up with 10 GbE interfaces, but you can configure it for up to 96 GbE interfaces. Also, Juniper Apstra has a default Device Profile for vJunos-switch, called vEX, that has 10 1GbE/10GbE interfaces, and this DP is automatically associated with all vJunos-switch instances. If your topology uses 10 or less dataplane interfaces, all should work just fine. However, if your topology requires more than 10 interfaces, then additional configuration both on vJunos-switch instances and Juniper Apstra will be required.
- vJunosEvolved instance is a virtual representation of the Juniper PTX10001-36MR, as shown below, and therefore we could just use the Device Profile of that platform that comes bundled with Juniper Apstra 4.1.2. However, because vJunos-switch and vJunosEvolved versions that we used in this lab, are release 23.1R1, we needed to create new Device Profiles to make the change necessary change in the Selector of the Device Profiles to include this version. We changed the RegEx from (1[89]|2[0-3])..* to (1[89]|2[0-3])..* for vJunos-switch and from (20.[34].|2[12]..)-EVO$ to (20.[34].|2[123]..)-EVO$ for vJunosEvolved.
And,
In our setup, leaf-1, leaf-2, spine-1 and spine-2 are running vJunos-switch and leaf-3, leaf-4, spine-3 and spine-4 are running vJunosEvolved, so we will create 2 separate interface maps and rack types, then create a template and a blueprint that includes both racks to build two 2 x leaf, 2-sapine EVPN-VXLAN fabrics. The fabrics will have routing on the leafs, in ERB style, and we will show that everything is working fine by testing connectivity between host-1 in subnet 10.1.1.0/24 and host-2 in subnet 10.1.2.0/24 on one fabric, and between host-3 in subnet 10.2.1.0/24 and host-4 in subnet 10.2.2.0/24 on the other fabric.
Note that because vJunos-switch simulates an EX9214 system with redundant Routine-Engine, you must add the following CLI commands to the pristine configuration before onboarding leaf-1 and spine-1 on Apstra
The other caveat to be aware of, is that vJunosEvolved leafs need the following command to be configured, so you need to push this configuration via an Apstra configlet
Apstra configuration steps for vJunos instances are no different than for all other hardware platforms so we will not share details here for the sake of brevity.
Conclusion¶
In this post, we shared the step to successfully deploy vJunos-switch and vJunosEvolved virtual appliances. Our purpose was to provide all the details to avoid running into running into issues that might cause long troubleshooting sessions.
We hope we achieved this goal.
Useful links¶
- vJunos-switch: https://support.juniper.net/support/downloads/?p=vjunos
- vJunosEvolved: https://support.juniper.net/support/downloads/?p=vjunos-evolved
- Juniper Apstra documentation: https://www.juniper.net/documentation/product/us/en/apstra/
- Deploying and Using Junos in a Bare Metal EVEN-NG Server: https://juniper.github.io/techposts/deploying-vjunos-in-a-bare-metal-eve-ng-server/article
Glossary¶
- DHCP : Dynamic Host Configuration Protocol
- ERB : Edge Routing and Bridging
- LACP : Link Aggregation Control Protocol
- LLDP : Link Layer Discovery Protocol
Acknowledgements¶
Special thanks to the following individuals who helped understand implementation details of vJunos-switch and vJunosEvolved, to those who helped in building and troubleshooting the setups we used in this post, and who also helped reviewing this post:
- Aninda Chatterjee
- Art Stine
- Hartmut Schroeder
- Kaveh Moezzi
- Shalini Mukherjee
- Yogesh Kumar
- Vignesh Shanmugaraju