GNS3 is a great tool to visualize your (home-)lab environment and simulate all kinds of network topologies using different virtualization and isolation technologies. It has been widely used to create environments using vEOS-lab, but because vEOS-lab requires quite some resources (e.g. 2GB of RAM is required) the scale of these labs was often quite limited, especially on low-memory devices.
Arista’s cEOS-lab is a new way of packaging the EOS-lab suite. Using the Docker container daemon, it is possible to use the kernel of the host machine and to only run the EOS processes that are required on the machine, making it possible to vastly reduce the memory footprint of each node.
With cEOS-lab 4.22.0F and above, it is also possible to simulate a Management port, providing for full support of scale-testing your configuration using exactly the same automation flow you would use in your production environment.
Importing cEOS-lab as a Docker image
To be able to add cEOS-lab nodes into a GNS3 topology, we first have to import the cEOS-lab archive into the Docker daemon on the machine running GNS3. The cEOS-lab software can be obtained through the Arista Software Download portal, listed under the “cEOS-lab” folder. In this example we’ll be using version cEOS-lab-220.127.116.11F.tar.xz, which has been copied to the working folder when executing these commands.
Please note the –change ‘VOLUME /mnt/flash/’ parameter, which accounts for persistence throughout cEOS-lab instance restarts.
gns3@gns3vm:~$ docker import --change 'VOLUME /mnt/flash/' cEOS-lab-18.104.22.168F.tar.xz ceoslab:22.214.171.124F
After this, we can verify that the image has been correctly added by running the following command:
gns3@gns3vm:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ceosimage 126.96.36.199F c21bf829c606 6 hours ago 1.68GB
Adding cEOS-lab as a GNS3 appliance
Then, we add cEOS-lab to GNS through the GUI. Go to “GNS3 –> Preferences” to open the settings page. Then move to the “Docker Containers” view. Click “New” to add the entry, if the only image available in Docker is ceosimage:188.8.131.52F, it will be chosen by default.
Click “Next” and enter the desired name.
Select the number of Adapters that you would like cEOS-lab to have. The first adapter will be linked to the Management0 port, so in this example we will have 8 Ethernet ports available in EOS by using a total of 9 adapters.
Select which command has to be executed when the container boots. This has to be the Linux init process which in turn launches the rest of EOS.
As of version 4.23.0F, we need to supply the variables to systemd by changing the start command to the following:
/sbin/init systemd.setenv=INTFTYPE=eth systemd.setenv=ETBA=1 systemd.setenv=SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 systemd.setenv=CEOS=1 systemd.setenv=EOS_PLATFORM=ceoslab systemd.setenv=container=docker systemd.setenv=MGMT_INTF=eth0
Select the console type that GNS3 makes the node available on. Using the telnet console we can see the status of the init process, while we can use an auxiliary console if there is need to enter the CLI.
Enter the environment variables. These are of vital importance for cEOS-lab to work. Note that when not passing the “MGMT_INTF” variable, eth0 will will not be linked to Management0, and the first port visible from cEOS will be Ethernet1 (mapped to eth1) instead.
INTFTYPE=eth ETBA=1 SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 CEOS=1 EOS_PLATFORM=ceoslab container=docker MGMT_INTF=eth0
Click “Finish” and don’t forget to click “OK” (make sure not to hit “Cancel”) on the Preferences page.
Adding cEOS-lab node(s) to your GNS3 topology
Drag the node to the canvas, then start it. Right-click and click “Console” to see the boot process of the node.
Wait until the boot process has completed (it will tell you that it has reached the target “Graphical Interface”.
Right-click again and click “Auxiliary Console” to open a second console, then run the command “FastCli” to enter the CLI of the node.
To test if this all works we can add another node, then connect the two ends together and do a ping test.
cEOS1>enable cEOS1#configure cEOS1(config)#interface ethernet 1 cEOS1(config-if-Et1)#no switchport cEOS1(config-if-Et1)#ip address 10.0.0.1/24
cEOS2>enable cEOS2#configure cEOS2(config)#interface ethernet 1 cEOS2(config-if-Et1)#no switchport cEOS2(config-if-Et1)#ip address 10.0.0.2/24
cEOS1#ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 72(100) bytes of data. 80 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.310 ms 80 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.139 ms 80 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.253 ms 80 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.083 ms 80 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=0.361 ms --- 10.0.0.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 1ms rtt min/avg/max/mdev = 0.083/0.229/0.361/0.104 ms, ipg/ewma 0.270/0.271 ms
cEOS2#ping 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 72(100) bytes of data. 80 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=3.80 ms 80 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.211 ms 80 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=1.22 ms 80 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.280 ms 80 bytes from 10.0.0.1: icmp_seq=5 ttl=64 time=0.214 ms --- 10.0.0.1 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 13ms rtt min/avg/max/mdev = 0.211/1.145/3.803/1.383 ms, ipg/ewma 3.252/2.421 ms
In order for MLAG to function properly, each cEOS-lab node must have a unique system MAC which helps specify the correct system-id. You can accomplish this by creating a file named “ceos-config” that defines the system MAC address along with a serial number (optional). First, we’ll drop into the bash shell and create the file and modify permissions so we can write to the file:
cEOS1#bash bash-4.2# cd /mnt/flash/ bash-4.2# touch ceos-config bash-4.2#chmod 755 ceos-config
We’ll then define our SERIALNUMBER and SYSTEMMACADDR variables and write them to ceos-config:
bash-4.2#printf "%s\n" $'SERIALNUMBER=<serial_number>' >> ceos-config bash-4.2#printf "%s\n" $'SYSTEMMACADDR=<system_mac_addr>' >> ceos-config
Again, each node will need a unique system MAC address (i.e. 001c.7300.0001, 001c.7300.0002, etc). The serial number can be any arbitrary value (i.e. cEOS-lab-host1) but should also be unique per node.
cEOS1#sh ver cEOSLab Hardware version: Serial number: cEOS-lab-host1 Hardware MAC address: 001c.7300.0001 System MAC address: 001c.7300.0001
MLAG configuration will now function properly using your cEOS-lab nodes.
cEOS1#sh mlag MLAG Configuration: domain-id : MLAG local-interface : Vlan4094 peer-address : 10.100.100.2 peer-link : Port-Channel1000 peer-config : consistent MLAG Status: state : Active negotiation status : Connected peer-link status : Up local-int status : Up system-id : 02:1c:73:00:00:01
In order for OSPF and/or ISIS to work with cEOS-lab, the INTFTYPE needs to be set to ‘et’ rather than ‘eth’. We’ll change our start command to ‘INTFTYPE=et’ (as of 4.25.1F):
sbin/init --privileged /sbin/init systemd.setenv=INTFTYPE=et systemd.setenv=ETBA=4 systemd.setenv=SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 systemd.setenv=CEOS=1 systemd.setenv=EOS_PLATFORM=ceoslab systemd.setenv=container=docker systemd.setenv=MAPETH0=1 systemd.setenv=MGMT_INTF=eth0
We’ll also update our environment variables to include ‘INTFTYPE=et’:
INTFTYPE=et ETBA=1 SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 CEOS=1 EOS_PLATFORM=ceoslab container=docker MGMT_INTF=eth0
After the node boots, you’ll notice that the CLI only recognizes the management interface (Ma0):
cEOS1#show interface status Port Name Status Vlan Duplex Speed Type Flags Encapsulation Ma0 connected routed full unconf 10/100/1000
However, running ‘bash ifconfig’ shows all interfaces:
cEOS1#bash ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether b6:4f:63:03:24:80 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 3e:64:a4:24:f5:23 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether c2:ad:b0:f4:78:94 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 etc…
We’re going to create a script that converts the Linux interface names from ‘eth(x)’ to ‘et(x)’. Here are the commands:
cEOS1#bash bash-4.2# cd /mnt/flash bash-4.2#vi afterStartup.sh
We’ll use the following text in the script to change the names of the interfaces:
#!/usr/bin/env bash #Rename interfaces bash << INTFCMDS sudo ip link set dev eth1 down sudo ip link set dev eth1 name et1 sudo ip link set dev et1 up sudo ip link set dev eth2 down sudo ip link set dev eth1 name et2 sudo ip link set dev et2 up etc... INTFCMDS sleep2 #Reset Interfaces Cli -A << CLICMDS enable agent Fru terminate agent Etba terminate CLICMDS
Now that we have our script created, we’ll setup an Event-Handler to run the script on-boot:
cEOS1(config)#event-handler Update-Ints cEOS1(config-handler-Update-Ints)#trigger on-boot cEOS1(config-handler-Update-Ints)#action bash /mnt/flash/afterStartup.sh cEOS1(config-handler-Update-Ints)#delay 30
The next time you start your cEOS-lab node, the interfaces will be recognized via the CLI:
cEOS1#show interface status Port Name Status Vlan Duplex Speed Type Flags Encapsulation Et1 connected routed full unconf EbraTestPhyPort Et2 connected routed full unconf EbraTestPhyPort Et3 connected in Po10 full unconf EbraTestPhyPort Et4 connected 110 full unconf EbraTestPhyPort Et5 connected 110 full unconf EbraTestPhyPort Et6 connected 10 full unconf EbraTestPhyPort Ma0 connected routed full unconf 10/100/1000
You can then setup OSPF and/or ISIS on your cEOS-lab nodes:
cEOS1#sh isis network topology IS-IS Instance: lab VRF: default IS-IS paths to level-2 routers System Id Metric IA Metric Next-Hop Interface SNPA mpls1 10 0 mpls1 Ethernet1 9a:91:5d:c5:5e:cb R3-P2a 10 0 R3-P2a Ethernet2 32:aa:1d:ef:71:c2 R4-ARBa 20 0 R3-P2a Ethernet2 32:aa:1d:ef:71:c2
Last but not least we’ll also verify that the APIs are working to do some automation testing. First we’ll put an IP address on the management port:
cEOS1(config)#interface management 0 cEOS1(config-if-Ma0)#ip addr 192.168.0.91/24
Then we’ll enable the API on the node:
cEOS1(config)#management api http-commands cEOS1(config-mgmt-api-http-cmds)#no shut
Make sure that you can reach the GNS3 cloud instance using your browser. This can be if it is directly bridged to your network, or if you are running GNS3 on another server by using an SSH tunnel. For more information on setting up tunnels through SSH, visit https://www.ssh.com/ssh/tunneling/example
After we set up the connectivity to the GNS3 cloud instance, we can test eAPI through the web GUI (located at https://<Management0-IP>/explorer.html):
Checking that that the commands have succeeded, showing the Management0 interface from the eAPI (using json output):
You’ve now got cEOS-lab up and running in GNS3. Enjoy creating virtualized labs which are much more scalable than when using regular vEOS-lab instances!