├── .gitignore
├── 10-basics
├── basic.clab.yml
└── README.md
├── 20-vm
├── vm.clab.yml
└── README.md
├── 15-startup
├── startup.clab.yml
├── ceos.cfg
├── srl.cfg
└── README.md
├── README.md
├── 05-install
└── README.md
├── 45-streaming-telemetry
└── README.md
├── 40-packet-capture
└── README.md
├── 30-registry
└── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | sync.sh
--------------------------------------------------------------------------------
/10-basics/basic.clab.yml:
--------------------------------------------------------------------------------
1 | name: basic
2 |
3 | topology:
4 | nodes:
5 | srl:
6 | kind: nokia_srlinux
7 | image: ghcr.io/nokia/srlinux
8 |
9 | ceos:
10 | kind: arista_ceos
11 | image: ceos:4.32.0F
12 |
13 | links:
14 | - endpoints: [srl:e1-1, ceos:eth1]
15 |
--------------------------------------------------------------------------------
/20-vm/vm.clab.yml:
--------------------------------------------------------------------------------
1 | name: vm
2 | topology:
3 | nodes:
4 | sros:
5 | kind: nokia_sros
6 | image: vrnetlab/nokia_sros:24.7.R1
7 | license: ~/images/sros-24.lic
8 |
9 | c8000v:
10 | kind: cisco_c8000v
11 | image: vrnetlab/cisco_c8000v:17.11.01a
12 |
13 | links:
14 | - endpoints: [sros:eth1, c8000v:eth1]
15 |
--------------------------------------------------------------------------------
/15-startup/startup.clab.yml:
--------------------------------------------------------------------------------
1 | name: startup
2 | topology:
3 | nodes:
4 | srl:
5 | kind: nokia_srlinux
6 | image: ghcr.io/nokia/srlinux
7 | startup-config: srl.cfg
8 | ceos:
9 | kind: arista_ceos
10 | image: ceos:4.32.0F
11 | startup-config: ceos.cfg
12 |
13 | links:
14 | - endpoints: [srl:e1-1, ceos:eth1]
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Containerlab Workshop at DENOG 16
2 |
3 | A list of workshop modules. Each module is a self-contained guide that can be followed independently, but it is recommended to go through them in order if you are new to Containerlab.
4 |
5 | Use the [official slide deck](https://gitlab.com/rdodin/pics/-/wikis/uploads/419c501863a492c9016f0e7b345b1c68/Containerlab_DENOG16_Workshop-export.pdf) to follow along with the workshop.
6 |
7 | 1. [Containerlab Installation](05-install/README.md) guide
8 | 2. [Basics first](10-basics/README.md)
9 | 3. [Dealing with startup config](15-startup/README.md)
10 | 4. [VM-based nodes](20-vm/README.md)
11 | 5. [Container registry](30-registry/README.md)
12 | 6. [Packet capture](40-packet-capture/README.md)
13 | 7. [A lab that has it ~all](45-streaming-telemetry/README.md)
14 |
15 | Did you love this workshop? Let us know in the comments of this [LinkedIn post](TBD).
16 |
--------------------------------------------------------------------------------
/05-install/README.md:
--------------------------------------------------------------------------------
1 | # Containerlab Installation
2 |
3 | ## All In One installer
4 |
5 | Installs
6 |
7 | * docker
8 | * latest containerlab,
9 | * `gh` cli
10 |
11 | all in one, multi-OS installer:
12 |
13 | ```bash
14 | curl -L http://containerlab.dev/setup | \
15 | sudo bash -s "all"
16 | ```
17 |
18 | The automation script adds the `docker` group to your `user`, in order for these changes to take effect, log out from the current session and log back in.
19 |
20 | Check that docker is installed and running:
21 |
22 | ```bash
23 | docker run --rm hello-world
24 | # Expected output: Hello from Docker!
25 | ```
26 |
27 | Check that containerlab is installed successfully:
28 |
29 | ```bash
30 | sudo containerlab version
31 | ```
32 |
33 | * Alternative Containerlab installation options are available [here](https://containerlab.dev/install/).
34 | * Alternative Docker installation options can be found [here](https://docs.docker.com/engine/install/).
35 |
--------------------------------------------------------------------------------
/15-startup/ceos.cfg:
--------------------------------------------------------------------------------
1 | hostname {{ .ShortName }}
2 | username admin privilege 15 secret admin
3 | !
4 | service routing protocols model multi-agent
5 | !
6 | {{- if .Env.CLAB_MGMT_VRF }}
7 | vrf instance {{ .Env.CLAB_MGMT_VRF }}
8 | !
9 | {{end}}
10 | {{ if .MgmtIPv4Gateway }}ip route {{ if .Env.CLAB_MGMT_VRF }}vrf {{ .Env.CLAB_MGMT_VRF }} {{end}}0.0.0.0/0 {{ .MgmtIPv4Gateway }}{{end}}
11 | {{ if .MgmtIPv6Gateway }}ipv6 route {{ if .Env.CLAB_MGMT_VRF }}vrf {{ .Env.CLAB_MGMT_VRF }} {{end}}::0/0 {{ .MgmtIPv6Gateway }}{{end}}
12 | !
13 | interface {{ .MgmtIntf }}
14 | {{ if .Env.CLAB_MGMT_VRF }} vrf {{ .Env.CLAB_MGMT_VRF }}{{end}}
15 | {{ if .MgmtIPv4Address }}ip address {{ .MgmtIPv4Address }}/{{.MgmtIPv4PrefixLength}}{{end}}
16 | {{ if .MgmtIPv6Address }}ipv6 address {{ .MgmtIPv6Address }}/{{.MgmtIPv6PrefixLength}}{{end}}
17 | !
18 | management api gnmi
19 | transport grpc default
20 | {{ if .Env.CLAB_MGMT_VRF }} vrf {{ .Env.CLAB_MGMT_VRF }}{{end}}
21 | !
22 | management api netconf
23 | transport ssh default
24 | {{ if .Env.CLAB_MGMT_VRF }} vrf {{ .Env.CLAB_MGMT_VRF }}{{end}}
25 | !
26 | management api http-commands
27 | no shutdown
28 | {{- if .Env.CLAB_MGMT_VRF }}
29 | !
30 | vrf {{ .Env.CLAB_MGMT_VRF }}
31 | no shutdown
32 | {{end}}
33 | !
34 |
35 |
36 | interface Ethernet1
37 | no switchport
38 | ip address 192.168.1.2/24
39 | !
40 | interface Loopback0
41 | ip address 10.10.10.2/32
42 | !
43 | ip routing
44 | !
45 | router bgp 65001
46 | router-id 10.10.10.2
47 | neighbor 192.168.1.1 remote-as 65001
48 | network 10.10.10.2/32
49 | !
50 |
51 | end
--------------------------------------------------------------------------------
/15-startup/srl.cfg:
--------------------------------------------------------------------------------
1 | interface ethernet-1/1 {
2 | subinterface 0 {
3 | admin-state enable
4 | ipv4 {
5 | admin-state enable
6 | address 192.168.1.1/24 {
7 | }
8 | }
9 | }
10 | }
11 | interface lo0 {
12 | subinterface 0 {
13 | admin-state enable
14 | ipv4 {
15 | admin-state enable
16 | address 10.10.10.1/32 {
17 | }
18 | }
19 | }
20 | }
21 | network-instance default {
22 | interface ethernet-1/1.0 {
23 | }
24 | interface lo0.0 {
25 | }
26 | protocols {
27 | bgp {
28 | admin-state enable
29 | autonomous-system 65001
30 | router-id 10.10.10.1
31 | afi-safi ipv4-unicast {
32 | admin-state enable
33 | }
34 | group ibgp {
35 | export-policy [ export-lo ]
36 | afi-safi ipv4-unicast {
37 | admin-state enable
38 | }
39 | }
40 | neighbor 192.168.1.2 {
41 | admin-state enable
42 | peer-as 65001
43 | peer-group ibgp
44 | }
45 | }
46 | }
47 | }
48 | routing-policy {
49 | prefix-set loopback {
50 | prefix 10.10.10.1/32 mask-length-range exact {
51 | }
52 | }
53 | policy export-lo {
54 | statement 10 {
55 | match {
56 | prefix-set loopback
57 | }
58 | action {
59 | policy-result accept
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/15-startup/README.md:
--------------------------------------------------------------------------------
1 | # Startup configuration
2 |
3 | This exercise demonstrates how to provide startup configuration to the lab nodes by means of the [`startup-config`](https://containerlab.dev/manual/nodes/#startup-config) node parameter in the topology file.
4 |
5 | Startup configuration is a way to provide initial configuration to the lab nodes when they boot up. This is useful when you want to automate the configuration of the nodes and avoid manual intervention. It also brings your lab to a desired state when you need to test a specific scenario.
6 |
7 | To enter the lab directory, run the following command from anywhere in your terminal:
8 |
9 | ```bash
10 | [*]─[rd-13]─[~]
11 | └──> cd ~/clab-workshop/15-startup/
12 |
13 | [*]─[rd-13]─[~/clab-workshop/15-startup]
14 | └──>
15 | ```
16 |
17 | We start by deploying a lab defined in the `startup.clab.yml` topology file. The lab consists of two nodes: `srl` (Nokia SR Linux) and `ceos` (Arista cEOS). Both nodes are configured with a startup configuration file that resides in the same directory as the topology file.
18 |
19 | We will use the shortened syntax when deploying the lab; less typing and more fun!
20 |
21 | ```bash
22 | sudo clab dep -c
23 | ```
24 |
25 | > Note, that when calling `clab dep -c` the containerlab will try to find the `*.clab.yml` file in the current working directory. If the file is located elsewhere, you can specify the path to the file as an argument to the `clab dep` command.
26 | > The `-c` flag stands for `--cleanup` and it will ensure that if the lab is already running, it will be stopped and removed before deploying a new one.
27 |
28 | The startup configuration files - [srl.cfg](srl.cfg) and [ceos.cfg](ceos.cfg) - configure the interfaces, IP addressing, loopbacks and BGP peering between SR Linux and cEOS nodes respectively.
29 |
30 | In particular, the `srl` node is configured to announce its loopback address `10.10.10.1/32` towards the `ceos` node and the `ceos` node is configured to announce its loopback address `10.10.10.2/32` towards the `srl` node.
31 |
32 | After the lab is deployed, we can expect that the nodes will boot up and apply the startup configuration snippets provided in the topology file. Consequently, it is fair to assume that the nodes will establish BGP peering and exchange routes.
33 |
34 | Let's connect to the `clab-startup-srl` node and check the BGP peering status:
35 |
36 | ```bash
37 | ssh clab-startup-srl
38 | ```
39 |
40 | ```
41 | --{ running }--[ ]--
42 | A:srl# show network-instance default protocols bgp neighbor 192.168.1.2
43 | ```
44 |
45 | You should see 1 route sent/received for the aforementioned BGP neighbor.
46 |
47 | Now, let's connect to the `clab-startup-ceos` node and make sure that it can reach the loopback address announced by the `srl` node.
48 |
49 | ```bash
50 | ssh clab-startup-ceos
51 | ```
52 |
53 | When in the EOS shell, issue a ping towards the `srl` node's loopback address:
54 |
55 | ```
56 | ping 10.10.10.1
57 | ```
58 |
59 | You should see a successful ping response.
60 |
61 | You have successfully deployed the lab with the nodes equipped with the startup configuration. This is a powerful feature that can be used to provision the nodes with the desired configuration when they boot up.
62 |
--------------------------------------------------------------------------------
/45-streaming-telemetry/README.md:
--------------------------------------------------------------------------------
1 | # Streaming Telemetry Lab
2 |
3 | > [!CAUTION]
4 | > Before proceeding, please destroy all other labs to free up the memory
5 | > `sudo clab des -c -a` - destroys all running labs and removes their respective lab dirs
6 |
7 | When pulling together what we have learned so far, we can build a lab that embodies a lot of what containerlab has to offer. One of the labs that we've built to demonstrate the power of containerlab is the [Streaming Telemetry Lab](https://github.com/srl-labs/srl-telemetry-lab).
8 |
9 | To deploy this lab we will use another neat containerlab feature - the ability to deploy a lab by specifying lab's remote URL. For the labs stored as a repo on GitHub we could even use the shorthand syntax:
10 |
11 | ```bash
12 | cd ~
13 | sudo containerlab deploy -t srl-labs/srl-telemetry-lab
14 | ```
15 |
16 | This will pull down the repository and deploy the lab right away.
17 |
18 | ## Exploring the topology file
19 |
20 | The streaming telemetry lab' [topology file](https://github.com/srl-labs/srl-telemetry-lab/blob/main/st.clab.yml) is worth a closer look. It features:
21 |
22 | - customization of the management network
23 | - use of `defaults` and `kinds` sections to simplify the topology file
24 | - static management IPs for consistency
25 | - combination of network OSes and "regular" containerized workloads like iperf clients, streaming telemetry and logging stack
26 | - use of the bind mounts to load the configuration files
27 | - use of env vars to parametrize the started containers
28 | - `exec` command to run commands in the started containers
29 | - port exposure to the host to make the lab services accessible from the outside
30 | - using of `group` parameter to influence lab nodes ordering in the graph products
31 |
32 | As you can see, this topo file is not a joke, and once the deployment finishes, you might want to understand what exactly was deployed and how the topology is structured. Enter graphs.
33 |
34 | ## Containerlab and graphing options
35 |
36 | When your topology has 3-5 nodes and a few links, you can easily visualize the topology in your head, but once your lab grows bigger, with more nodes involved and more links created, it becomes harder to remember what is what and where.
37 |
38 | To help you with visualizing the topology, containerlab provides a few graphing options () that we will explore briefly.
39 |
40 | ### Web graph
41 |
42 | After you deployed the lab, run the `graph` command:
43 |
44 | ```
45 | sudo clab graph
46 | ```
47 |
48 | The local web server provided by containerlab will be welcoming you at `http://d.srexperts.net:50080` where `` is your ID. The web server will render the deployed topology in an interactive graph that you can sort vertically or horizontally.
49 |
50 | The `group` options on the node level help you to order the lab nodes in the graph.
51 |
52 | ### Drawio export
53 |
54 | The web graph is great, but has a number of limitations:
55 |
56 | - Not editable
57 | - Opinionated
58 | - Only one ”pane” - physical
59 |
60 | To combat these limitations, another project has been created in the containerlab ecosystem - [clab-io-draw](https://github.com/srl-labs/clab-io-draw).
61 |
62 | It allows to generate a drawio topology from a containerlab topology and does so with style!
63 |
64 | ```bash
65 | sudo clab graph --drawio --drawio-args "--theme grafana_dark"
66 | ```
67 |
68 | It has many neat options, so please go checkout the readme file at the projects' repo.
69 |
70 | ### Mermaid
71 |
72 | And last graphing option is the mermaid graph that can be very handy when embedding the mermaid graphs in your markdown docs.
73 |
--------------------------------------------------------------------------------
/40-packet-capture/README.md:
--------------------------------------------------------------------------------
1 | # Packet capture
2 |
3 | Every lab emulation software must provide its users with the packet capturing abilities. Looking at the frames as they traverse the network links is not only educational, but also helps to troubleshoot the issues that might arise during the lab development.
4 |
5 | Containerlab offers a simple way to capture the packets from any interface of any node in the lab since every interface is exposed to the underlying Linux OS. This article will explain how to do that.
6 |
7 | Everything we are going to do in this exercise is explained in details in the [Containerlab documentation](https://containerlab.dev/manual/wireshark/).
8 |
9 | ## Remote capture
10 |
11 | The first way to capture the packets from a containerlab node running on a remote host that we are going to explore is called "remote capture". In this scenario a user has a network connectivity (ssh) to the host that runs containerlab topology and wishes to get the packet capture displayed in the Wireshark running locally.
12 |
13 | To achieve this, we will execute the `tcpdump` command on the remote host and pipe the output to the local Wireshark app. Here is a command that does it all for the host `d1` which is the instructors host.
14 |
15 | It captures the traffic from SR OS (`clab-vm-sros`) port `eth1` (`1/1/1`) running on `d1` host and displaying the capture in the Wireshark.
16 |
17 | The command is provided for WSL and Mac systems, assuming default Wireshark installation path
18 |
19 | Windows/WSL:
20 |
21 | ```bash
22 | ssh user@d1.srexperts.net \
23 | "ip netns exec clab-vm-sros tcpdump -U -nni eth1 -w -" | \
24 | /mnt/c/Program\ Files/Wireshark/wireshark.exe -k -i -
25 | ```
26 |
27 | macOS:
28 |
29 | ```
30 | ssh user@d1.srexperts.net \
31 | "ip netns exec clab-vm-sros tcpdump -U -nni eth1 -w -" | \
32 | /Applications/Wireshark.app/Contents/MacOS/Wireshark -k -i -
33 | ```
34 |
35 | ## Edgeshark
36 |
37 | [Edgeshark](https://edgeshark.siemens.io/#/) is a set of tools that offer (among many things) a Web UI that displays every interface of every container and can start a wireshark as easy as clicking a button.
38 |
39 | Edgeshark installation consists of two parts:
40 |
41 | 1. A service that runs on the host that runs containerlab topologies
42 | 2. A wireshark capture plugin that runs next to the Wireshark on a user's PC
43 |
44 | To install the service, past the installer command that uses docker compose to deploy the service:
45 |
46 | ```bash
47 | curl -sL \
48 | https://github.com/siemens/edgeshark/raw/main/deployments/wget/docker-compose.yaml | \
49 | docker compose -f - up -d
50 | ```
51 |
52 | Now, you have to install the client plugin based on the OS of your PC.
53 |
54 | ### Windows
55 |
56 | Windows users get to enjoy a simple installer-based workflow that installs the URL handler and the Wireshark plugin in one go.
57 |
58 | Download the installer file -
59 |
60 | Unzip the archive and launch the installer script.
61 |
62 | ### MacOs
63 |
64 | MacOs users have to suffer a little. But it is not that bad either.
65 |
66 | To install the URL handler paste the following in the Mac terminal app:
67 |
68 | ```bash
69 | mkdir -p /tmp/pflix-handler && cd /tmp/pflix-handler && \
70 | rm -rf packetflix-handler.zip packetflix-handler.app __MACOSX && \
71 | curl -sLO https://github.com/srl-labs/containerlab/files/14278951/packetflix-handler.zip && \
72 | unzip packetflix-handler.zip && \
73 | sudo mv packetflix-handler.app /Applications
74 | ```
75 |
76 | To install the extpcap wireshark plugin execute in the Mac terminal:
77 |
78 | ```bash
79 | # for x86_64 MacOS use https://github.com/siemens/cshargextcap/releases/download/v0.10.7/cshargextcap_0.10.7_darwin_amd64.tar.gz
80 | DOWNLOAD_URL=https://github.com/siemens/cshargextcap/releases/download/v0.10.7/cshargextcap_0.10.7_darwin_arm64.tar.gz
81 | mkdir -p /tmp/pflix-handler && curl -sL $DOWNLOAD_URL | tar -xz -C /tmp/pflix-handler && \
82 | open /tmp/pflix-handler && open /Applications/Wireshark.app/Contents/MacOS/extcap
83 | ```
84 |
85 | The command above will open two Finder windows, one with the `cshargextcap` binary and the other with the Wireshark's existing plugins. Move the `cshargextcap` file over to the window with Wireshark plugins.
86 |
87 | ### Web UI
88 |
89 | To access the Edgeshark UI, open a browser and navigate to the following URL (substitute the hostname with your assigned VM):
90 |
91 |
92 |
93 | Note, the http schema is important, since https is not enabled.
94 |
--------------------------------------------------------------------------------
/30-registry/README.md:
--------------------------------------------------------------------------------
1 | # Container registry and Containerlab
2 |
3 | Containerlab is better when used with a container registry. No one loved to witness the uncontrolled proliferation of unversioned disk image (qcow2, vmdk) files shared via ftps, one drives and IM attachments.
4 |
5 | We can do better!
6 |
7 | Since containerlab deals with container images, it is natural to use a container registry to store them. Versioned, immutable, tagged and easily shareable with granular access control.
8 |
9 | Whether you choose to use one of the public registries or a run a private one, the workflow is the same. Let's see what it looks like.
10 |
11 | ## Harbor registry
12 |
13 | In this workshop we make use of an open-source registry called [Harbor](https://goharbor.io/). It is a CNCF graduated project and is a great choice for a private registry.
14 |
15 | The registry has been already deployed in the workshop environment, but it is quite easy to deploy yourself in your own organization. It is a single docker compose stack that can be deployed in a few minutes.
16 |
17 | The Harbor registry offers a neat Web UI to browse the registry contents, manage users and tune access control. You can log in to the registry UI like this:
18 |
19 |
20 |
21 | using the `admin` user and the password available in your workshop handout.
22 |
23 | When logged in as `admin` you can created users, repositories, browse the registry contents and many more. Managing the harbor registry is out of the scope of this workshop.
24 |
25 | ## Pushing images to the registry
26 |
27 | We will push one of the images that we've built in the previous section to the registry effectively saving it and making it available and reusable to other users who have access to this registry.
28 |
29 | ### 1 Logging in to the registry
30 |
31 | To be able to push and pull the images from the workshop's registry, you need to login to the registry.
32 |
33 | ```bash
34 | # username: admin
35 | # password: as per your workshop handout
36 | docker login registry-d16.srexperts.net
37 | ```
38 |
39 | ### 2 Listing local images
40 |
41 | First, we need to identify the name of the image that we want to push to the registry. By listing the images in the local image store we can reliably identify the name of the image that we want to push.
42 |
43 | ```
44 | docker images
45 | ```
46 |
47 | On your system you will see a list of images, among which you will see:
48 |
49 | ```
50 | REPOSITORY TAG IMAGE ID CREATED SIZE
51 | vrnetlab/nokia_sros 24.7.R1 d45128fc2914 2 hours ago 889MB
52 | ```
53 |
54 | This is the image that we built before and that we want to push to the registry so that next time we want to use it we won't have to build it again.
55 |
56 | The image name consists of two parts:
57 |
58 | - `vrnetlab/nokia_sros` - the repository name
59 | - `24.7.R1` - the tag
60 |
61 | Catenating these two parts together we get the full name of the image that we want to push to the registry.
62 |
63 | ### 3 Pushing the image to the registry
64 |
65 | Now that we know the name of the image that we want to push to the registry, we can push it. Usually you will see a sequence of `docker tag` and `docker push` commands being executed, but we are cool kids here so we will do it in one go.
66 |
67 | Using the skopeo tool - - we can push the image to the registry in one go. The command to use has the following format:
68 |
69 | ```
70 | skopeo copy docker-deamon:// docker:///:
71 | ```
72 |
73 | Since everyone would want to push their own image to the registry we will need to append a user id to the tag name so that you won't overwrite each other's images. Like the below command pushes the image to the user with ID=1:
74 |
75 | ```bash
76 | # note the appended -1 at the end of the tag
77 | skopeo copy \
78 | docker-daemon:vrnetlab/nokia_sros:24.7.R1 \
79 | docker://registry-d16.srexperts.net/library/nokia_sros:24.7.R1-1
80 | ```
81 |
82 | ## Listing images from the registry
83 |
84 | Once the image is copied, you can see it in the registry UI.
85 |
86 | 
87 |
88 | If you want to get the list of available repositories/tags in the registry, you can use registry API and skopeo.
89 |
90 | Listing available repositories:
91 |
92 | ```bash
93 | curl -s -u 'admin:d16ClabW$' https://registry-d16.srexperts.net/v2/_catalog | jq
94 | {
95 | "repositories": [
96 | "admin/nokia_sros",
97 | "library/nokia_sros"
98 | ]
99 | }
100 | ```
101 |
102 | Listing available tags for a given repository:
103 |
104 | ```bash
105 | skopeo list-tags docker://registry-d16.srexperts.net/library/nokia_sros
106 | {
107 | "Repository": "registry-d16.srexperts.net/library/nokia_sros",
108 | "Tags": [
109 | "24.7.R1-1"
110 | ]
111 | }
112 | ```
113 |
114 | ## Using images from the registry
115 |
116 | The whole point of pushing the image to the registry is to be able to use it in the future yourself and also to share it with others. And now that we have the image in the registry, we can modify the `20-vm.clab.yml` file to make use of it:
117 |
118 | ```diff
119 | name: vm
120 | topology:
121 | nodes:
122 | sros:
123 | kind: nokia_sros
124 | - image: vrnetlab/nokia_sros:24.7.R1
125 | + image: registry-d16.srexperts.net/library/nokia_sros:24.7.R1-1
126 | license: ~/images/sros-24.lic
127 |
128 | c8000v:
129 | kind: cisco_c8000v
130 | image: vrnetlab/cisco_c8000v:17.11.01a
131 |
132 | links:
133 | - endpoints: [sros:eth1, c8000v:eth1]
134 | ```
135 |
136 | Not only this gives us an easy way to share images with others, but also it enables stronger reproducibility of the lab, as the users of our lab would use exactly the same image that we built.
137 |
--------------------------------------------------------------------------------
/10-basics/README.md:
--------------------------------------------------------------------------------
1 | # Containerlab Basics
2 |
3 | This workshop section introduces you to containerlab basics - topology file, image management workflows and lab lifecycle. It is loosely based on the official [Containerlab quickstart](https://containerlab.dev/quickstart/).
4 |
5 | ## Repository
6 |
7 | Clone the repository to your workshop VM at DENOG16 tag:
8 |
9 | ```bash
10 | cd ~
11 | git clone https://github.com/srl-labs/clab-workshop.git -b denog16
12 | cd clab-workshop/10-basics
13 | ```
14 |
15 | The repo should be cloned and you should be in the `ac1-workshop` directory as per the output below:
16 |
17 | ```
18 | [*]─[rd-13]─[~/clab-workshop/10-basics]
19 | └──>
20 | ```
21 |
22 | ## Topology
23 |
24 | The topology file `basic.clab.yml` defines the lab we are going to use in this basics exercise. It consists of the two nodes:
25 |
26 | * Nokia SR Linux
27 | * Arista cEOS
28 |
29 | The nodes are interconnected with a single link over their respective first Ethernet interfaces.
30 |
31 | ```yaml
32 | name: basic
33 | topology:
34 | nodes:
35 | srl:
36 | kind: nokia_srlinux
37 | image: ghcr.io/nokia/srlinux
38 | ceos:
39 | kind: arista_ceos
40 | image: ceos:4.32.0F
41 |
42 | links:
43 | - endpoints: [srl:e1-1, ceos:eth1]
44 | ```
45 |
46 | ## Deployment attempt #1
47 |
48 | Try to deploy the lab:
49 |
50 | ```bash
51 | sudo containerlab deploy -t basic.clab.yml
52 | ```
53 |
54 | Deployment fails, why?
55 |
56 | ## Image management
57 |
58 | Check what images are available on the system:
59 |
60 | ```bash
61 | docker images
62 | ```
63 |
64 | Pull SR Linux container image (if it has not been pulled during attempt #1):
65 |
66 | ```bash
67 | docker pull ghcr.io/nokia/srlinux
68 | ```
69 |
70 | Import cEOS image and pay attention to the 2nd argument for the `docker import` command where you have to specify the image:
71 |
72 | ```bash
73 | docker import ~/images/cEOS64-lab-4.32.0F.tar.xz ceos:4.32.0F
74 | ```
75 |
76 | Check the local image store again:
77 |
78 | ```bash
79 | docker images
80 | ```
81 |
82 | ## Deployment attempt #2
83 |
84 | Now that the images are available, try to deploy the lab again:
85 |
86 | ```bash
87 | sudo containerlab deploy -t basic.clab.yml
88 | ```
89 |
90 | Note, you can use a shortcut version of the same command - `sudo clab dep -t basic.clab.yml`.
91 |
92 | The deployment should succeed.
93 |
94 | ## Connecting to the nodes
95 |
96 | Connect to the Nokia SR Linux node using the container name:
97 |
98 | ```bash
99 | ssh clab-basic-srl
100 | ```
101 |
102 | Connect to the cEOS node using its IP address (note, the IP might be different in your lab):
103 |
104 | ```bash
105 | ssh admin@172.20.20.3
106 | ```
107 |
108 | ## Containerlab hosts automation
109 |
110 | Containerlab creates `/etc/hosts` entries for each deployed lab so that you can access the nodes using their names. Check the entries:
111 |
112 | ```bash
113 | cat /etc/hosts
114 | ```
115 |
116 | ## Containerlab ssh config automation
117 |
118 | Containerlab creates ssh config entries in `/etc/ssh/ssh_config.d/clab-.conf` file to provide easy access to the nodes. Check the entries:
119 |
120 | ```bash
121 | cat /etc/ssh/ssh_config.d/clab-basic.conf
122 | ```
123 |
124 | ## Checking network connectivity
125 |
126 | SR Linux and cEOS are started with their first Ethernet interfaces connected. Check the connectivity between the nodes:
127 |
128 | The nodes also come up with LLDP enabled, our goal is to verify that the basic network connectivity is working by inspecting
129 |
130 | ```bash
131 | ssh clab-basic-srl
132 | ```
133 |
134 | and checking the LLDP neighbors on ethernet-1/1 interface
135 |
136 | ```
137 | show /system lldp neighbor interface ethernet-1/1
138 | ```
139 |
140 | The expected output should be:
141 |
142 | ```
143 | --{ running }--[ ]--
144 | A:srl# show /system lldp neighbor interface ethernet-1/1
145 | +----------+----------+---------+---------+---------+---------+---------+
146 | | Name | Neighbor | Neighbo | Neighbo | Neighbo | Neighbo | Neighbo |
147 | | | | r | r | r First | r Last | r Port |
148 | | | | System | Chassis | Message | Update | |
149 | | | | Name | ID | | | |
150 | +==========+==========+=========+=========+=========+=========+=========+
151 | | ethernet | 00:1C:73 | ceos | 00:1C:7 | 20 | 16 | Etherne |
152 | | -1/1 | :46:95:5 | | 3:46:95 | hours | seconds | t1 |
153 | | | C | | :5C | ago | ago | |
154 | +----------+----------+---------+---------+---------+---------+---------+
155 | ```
156 |
157 | ## Listing running labs
158 |
159 | When you are in the directory that contains the lab file, you can list the nodes of that lab simply by running:
160 |
161 | ```bash
162 | [*]─[rd-13]─[~/clab-workshop/10-basics]
163 | └──> sudo containerlab inspect
164 | INFO[0000] Parsing & checking topology file: basic.clab.yml
165 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
166 | | # | Name | Container ID | Image | Kind | State | IPv4 Address | IPv6 Address |
167 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
168 | | 1 | clab-basic-ceos | c279d892ea22 | ceos:4.32.0F | arista_ceos | running | 172.20.20.2/24 | 2001:172:20:20::2/64 |
169 | | 2 | clab-basic-srl | 7c46eb454f51 | ghcr.io/nokia/srlinux | nokia_srlinux | running | 172.20.20.3/24 | 2001:172:20:20::3/64 |
170 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
171 | ```
172 |
173 | If the topology file is located in a different directory, you can specify the path to the topology file:
174 |
175 | ```bash
176 | [*]─[rd-13]─[/tmp]
177 | └──> sudo containerlab inspect -t ~/clab-workshop/10-basics/
178 | INFO[0000] Parsing & checking topology file: basic.clab.yml
179 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
180 | | # | Name | Container ID | Image | Kind | State | IPv4 Address | IPv6 Address |
181 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
182 | | 1 | clab-basic-ceos | c279d892ea22 | ceos:4.32.0F | arista_ceos | running | 172.20.20.2/24 | 2001:172:20:20::2/64 |
183 | | 2 | clab-basic-srl | 7c46eb454f51 | ghcr.io/nokia/srlinux | nokia_srlinux | running | 172.20.20.3/24 | 2001:172:20:20::3/64 |
184 | +---+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
185 | ```
186 |
187 | You can also list all running labs regardless of where their topology files are located:
188 |
189 | ```bash
190 | [*]─[rd-13]─[~/clab-workshop/10-basics]
191 | └──> sudo containerlab inspect --all
192 | +---+----------------+----------+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
193 | | # | Topo Path | Lab Name | Name | Container ID | Image | Kind | State | IPv4 Address | IPv6 Address |
194 | +---+----------------+----------+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
195 | | 1 | basic.clab.yml | basic | clab-basic-ceos | c279d892ea22 | ceos:4.32.0F | arista_ceos | running | 172.20.20.2/24 | 2001:172:20:20::2/64 |
196 | | 2 | | | clab-basic-srl | 7c46eb454f51 | ghcr.io/nokia/srlinux | nokia_srlinux | running | 172.20.20.3/24 | 2001:172:20:20::3/64 |
197 | +---+----------------+----------+-----------------+--------------+-----------------------+---------------+---------+----------------+----------------------+
198 | ```
199 |
200 | The output will contain all labs and their nodes.
201 |
202 | Shortcuts:
203 |
204 | * `sudo clab ins` == `sudo containerlab inspect`
205 | * `sudo clab ins -a` == `sudo containerlab inspect --all`
206 |
207 | ## Lab directory
208 |
209 | Lab directory stores the artifacts generated by containerlab that are related to the lab:
210 |
211 | * tls certificates
212 | * startup configurations
213 | * inventory files
214 | * topology export json file
215 | * bind mounted directories
216 |
217 | To list the contents of the lab directory, run:
218 |
219 | ```
220 | [*]─[rd-13]─[~/clab-workshop/10-basics]
221 | └──> tree -L 3 clab-basic/
222 | ```
223 |
224 | ## Destroying the lab
225 |
226 | When you are done with the lab, you can destroy it. Containerlab can try and find the `*.clab.yml` file in the current directory and use it so that you don't have to type it out.
227 | Try it:
228 |
229 | ```bash
230 | sudo clab des --cleanup
231 | ```
232 |
233 | Alternatively, you could specify the topology file explicitly:
234 |
235 | ```bash
236 | sudo clab des -t basic.clab.yml --cleanup
237 | ```
238 |
239 | The `--cleanup` flag ensures that the lab directory gets removed as well.
240 |
241 | You finished the basics lab exercise!
242 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/20-vm/README.md:
--------------------------------------------------------------------------------
1 | # VM-based nodes in containerlab
2 |
3 | VM nodes integration in containerlab is based on the [hellt/vrnetlab](https://github.com/hellt/vrnetlab) project which is a **fork** of `vrnetlab/vrnetlab` where things were added to make it work with the container networking.
4 |
5 | Start with cloning the project:
6 |
7 | ```bash
8 | cd ~
9 | git clone https://github.com/hellt/vrnetlab.git
10 | cd ~/vrnetlab
11 | ```
12 |
13 | ## Building Cisco Catalyst 8000v image
14 |
15 | Cisco c8000v qcow image is located at `~/images/c8000v-universalk9_16G_serial.17.11.01a.qcow2` and should be copied to the `~/vrnetlab/c8000v/` directory before building the container image.
16 |
17 | ```bash
18 | cp ~/images/c8000v-universalk9_16G_serial.17.11.01a.qcow2 ~/vrnetlab/c8000v/
19 | ```
20 |
21 | Once copied, we can enter in the `~/vrnetlab/c8000v` image and build the container image:
22 |
23 | ```bash
24 | cd ~/vrnetlab/c8000v
25 | make
26 | ```
27 |
28 | Note, that c8000v image will run the VM during the container build time. This is to unpack the image once at build time, instead of doing it every time a container is started. That is why the build time is longer than for SR OS image.
29 |
30 | While it is building the image, open another terminal window and proceed with building the SR OS image
31 |
32 | The resulting image will be tagged as `vrnetlab/cisco_c8000v:17.11.01a`.
33 |
34 | ## Building Nokia SR OS image
35 |
36 | SR OS qcow image is located at `~/images/sros-vm-24.3.R1.qcow2` and should be copied to the `~/vrnetlab/sros/` directory before building the container image.
37 |
38 | ```bash
39 | cp ~/images/sros-vm-24.7.R1.qcow2 ~/vrnetlab/sros/
40 | ```
41 |
42 | Once copied, we can enter in the `~/vrnetlab/sros` image and build the container image:
43 |
44 | ```bash
45 | cd ~/vrnetlab/sros
46 | make
47 | ```
48 |
49 | The image will be built and tagged as `vrnetlab/nokia_sros:24.7.R1`. The tag is auto-derived from the file name.
50 |
51 | ## Deploying the VM-based nodes lab
52 |
53 | With the images built, we can proceed with the lab deployment. First, let's switch back to the lab directory:
54 |
55 | ```bash
56 | cd ~/clab-workshop/20-vm
57 | ```
58 |
59 | Now lets deploy the lab:
60 |
61 | ```bash
62 | sudo clab dep -c
63 | ```
64 |
65 | ### Monitoring the boot process
66 |
67 | You will notice that the lab deployment log will show the following message and the deployment process will appear stuck:
68 |
69 | ```
70 | Waiting for clab-vm-sros to be ready. This may take a while. Monitor boot log with `sudo docker logs -f clab-vm-sros`
71 | ```
72 |
73 | This is because containerlab waits for SR OS node to boot and become ready for containerlab to inject SSH keys to enabled passwordless SSH access. To monitor the boot process, you can open a new terminal and run the following command:
74 |
75 | ```bash
76 | docker logs -f clab-vm-sros
77 | ```
78 |
79 | > the SR OS boot time is approx 3 minutes.
80 |
81 | You will see the boot process of the SR OS node as it would have been seen in a terminal connected to the real hardware console.
82 |
83 | The same `docker logs` command can be used for the `clab-vm-c8000v` node to monitor the boot log of the Cisco Catalyst 8000v node.
84 |
85 | > The c8000v boot time is approx 3 minutes.
86 |
87 | ## Connecting to the nodes
88 |
89 | To connect to SR OS node:
90 |
91 | ```
92 | ssh clab-vm-sros
93 | ```
94 |
95 | No user/password is needed, since username is injected by containerlab as well as the local public key for passwordless SSH access.
96 |
97 | To connect to the c8000v node use `admin:admin` credentials:
98 |
99 | ```bash
100 | ssh clab-vm-c8000v
101 | ```
102 |
103 | ## Configuring the nodes
104 |
105 | ### SR OS
106 |
107 | If not logged in yet, open a new terminal and connect to the SR OS node:
108 |
109 | ```
110 | ssh clab-vm-sros
111 | ```
112 |
113 | While logged in in the SR OS CLI paste the following snippet to configure SR OS:
114 |
115 | ```
116 | edit-config private
117 | /configure port 1/1/c1 admin-state enable
118 | /configure port 1/1/c1 connector breakout c1-100g
119 | /configure port 1/1/c1/1 admin-state enable
120 | /configure port 1/1/c1/1 description "port 1/1/c1/1"
121 | /configure port 1/1/c1/1 ethernet mode hybrid
122 | /configure port 1/1/c1/1 { ethernet lldp }
123 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge notification true
124 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge port-id-subtype tx-if-name
125 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge receive true
126 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge transmit true
127 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-tlvs port-desc true
128 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-tlvs sys-name true
129 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-tlvs sys-desc true
130 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-tlvs sys-cap true
131 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-mgmt-address oob admin-state enable
132 | /configure port 1/1/c1/1 ethernet lldp dest-mac nearest-bridge tx-mgmt-address system admin-state enable
133 |
134 | /configure router "Base" interface "toC8kv" { admin-state enable }
135 | /configure router "Base" interface "toC8kv" { port 1/1/c1/1:0 }
136 | /configure router "Base" interface "toC8kv" { ipv4 primary address 192.168.1.2 }
137 | /configure router "Base" interface "toC8kv" { ipv4 primary prefix-length 24 }
138 | commit
139 | exit all
140 | ```
141 |
142 | ### Cisco Catalyst 8000v
143 |
144 | If not logged in yet, open a new terminal and connect to the SR OS node:
145 |
146 | ```bash
147 | # password admin
148 | ssh clab-vm-c8000v
149 | ```
150 |
151 | And paste the following configuration:
152 |
153 | ```
154 | conf t
155 | lldp run
156 | interface GigabitEthernet2
157 | ip address 192.168.1.1 255.255.255.0
158 | lldp receive
159 | lldp transmit
160 | no shutdown
161 | ```
162 |
163 | Now we configured the two systems to be able to communicate with each other and enabled LLDP on both sides. Perform a ping from SR OS towards the c8000v node and let it run:
164 |
165 | ### Verify the connectivity
166 |
167 | While in SR OS CLI, let's check a few things. First, let's see if LLDP is working and we detect the c8000v node:
168 |
169 | ```
170 | (pr)[/]
171 | A:admin@sros# / show port "1/1/c1/1" ethernet lldp remote-info
172 |
173 | ==============================================================================
174 | Link Layer Discovery Protocol (LLDP) Port Information
175 | ==============================================================================
176 | Port 1/1/c1/1 Bridge nearest-bridge Remote Peer Information
177 | -------------------------------------------------------------------------------
178 | Remote Peer Index 1 at timestamp 11/07/2024 13:36:07:
179 | Supported Caps : bridge router
180 | Enabled Caps : router
181 | Chassis Id Subtype : 4 (macAddress)
182 | Chassis Id : 00:1E:BD:D7:38:00
183 | PortId Subtype : 5 (interfaceName)
184 | Port Id : 47:69:32
185 | "Gi2"
186 | Port Description : GigabitEthernet2
187 | System Name : c8000v.example.com
188 | System Description : Cisco IOS Software [Dublin], Virtual XE Software
189 | (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 17.11.1a,
190 | RELEASE SOFTWARE (fc3)
191 | Technical Support: http://www.cisco.com/techsupport
192 | Copyright (c) 1986-2023 by Cisco Systems, Inc.
193 | Compiled Wed 05-Apr-23 06:54 by
194 | Age : 213 seconds
195 |
196 |
197 | Port 1/1/c1/1 Bridge nearest-non-tpmr Remote Peer Information
198 | -------------------------------------------------------------------------------
199 | No remote peers found
200 |
201 | Port 1/1/c1/1 Bridge nearest-customer Remote Peer Information
202 | -------------------------------------------------------------------------------
203 | No remote peers found
204 |
205 | ==============================================================================
206 | ```
207 |
208 | Great, the neighboring router is detected, which means that L2 protocols such as LLDP are working fine.
209 |
210 | Next, check the configuration status of the interface towards the c8000v node:
211 |
212 | ```
213 | (pr)[/]
214 | A:admin@sros# / show router "Base" interface "toC8kv"
215 |
216 | ===============================================================================
217 | Interface Table (Router: Base)
218 | ===============================================================================
219 | Interface-Name Adm Opr(v4/v6) Mode Port/SapId
220 | IP-Address PfxState
221 | -------------------------------------------------------------------------------
222 | toC8kv Up Up/Down Network 1/1/c1/1:0
223 | 192.168.1.2/24 n/a
224 | -------------------------------------------------------------------------------
225 | Interfaces : 1
226 | ===============================================================================
227 | ```
228 |
229 | The interface is up and the remote IP address is 192.168.1.1, let's start the ping it to verify the datapath and make it run for a while with thousands of probes requested:
230 |
231 | ```
232 | [/]
233 | A:admin@sros# ping 192.168.1.1 count 2000
234 | PING 192.168.1.1 56 data bytes
235 | 64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=50.4ms.
236 | 64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=1.57ms.
237 | ```
238 |
239 | Pings are flowing, neat. Let them run in this terminal window, we will need them later.
240 |
241 | ## Exploring the VM networking setup
242 |
243 | In a new terminal window open c8000v node's container shell:
244 |
245 | ```bash
246 | docker exec -it clab-vm-c8000v bash
247 | ```
248 |
249 | Explore the Linux link interfaces available in the container:
250 |
251 | ```bash
252 | ip link
253 | ```
254 |
255 | the `tap1` interface corresponds to the VM's interfaces and it is transparently "stitched" (with `tc mirred` rules)
256 |
257 | You can sniff the traffic on both `eth1` and `tap1` interface, and see that they carry the same traffic, as they are merely two ends of the same virtual link.
258 |
259 | ```bash
260 | tcpdump -nni tap1
261 | ```
262 |
263 | The management interface doesn't use the `tapX` interface, but rather leverage the qemu user mode networking, where qemu is instructed to forward connections made to certain ports on the localhost to a special qemu-managed interface that represents the VM's management interface.
264 |
265 | You can see those host forward rules created by vrnetlab, when you list the qemu process:
266 |
267 | ```bash
268 | root@c8000v:/# ps auxw | grep qemu
269 | root 13 99.9 25.8 4667132 4231652 pts/0 Sl+ 14:11 126:16 qemu-system-x86_64 -enable-kvm -display none -machine pc -monitor tcp:0.0.0.0:4000,server,nowait -serial telnet:0.0.0.0:5000,server,nowait -m 4096 -cpu host -smp 1 -drive if=ide,file=/c8000v-universalk9_16G_serial.17.11.01a-overlay-overlay-overlay.qcow2 -device pci-bridge,chassis_nr=1,id=pci.1 -device virtio-net-pci,netdev=p00,mac=0C:00:ed:ba:55:00 -netdev user,id=p00,net=10.0.0.0/24,tftp=/tftpboot,hostfwd=tcp:0.0.0.0:22-10.0.0.15:22,hostfwd=udp:0.0.0.0:161-10.0.0.15:161,hostfwd=tcp:0.0.0.0:830-10.0.0.15:830,hostfwd=tcp:0.0.0.0:80-10.0.0.15:80,hostfwd=tcp:0.0.0.0:443-10.0.0.15:443,hostfwd=tcp:0.0.0.0:9339-10.0.0.15:9339,hostfwd=tcp:0.0.0.0:57400-10.0.0.15:57400,hostfwd=tcp:0.0.0.0:6030-10.0.0.15:6030,hostfwd=tcp:0.0.0.0:32767-10.0.0.15:32767,hostfwd=tcp:0.0.0.0:8080-10.0.0.15:8080 -device virtio-net-pci,netdev=p01,mac=0C:00:7e:5c:84:01,bus=pci.1,addr=0x2 -netdev tap,id=p01,ifname=tap1,script=/etc/tc-tap-ifup,downscript=no
270 | root 1622 0.0 0.0 3324 1596 pts/1 S+ 16:17 0:00 grep qemu
271 | ```
272 |
273 | Look for `hostfwd` options in the qemu command line. Those are the port forwarding rules that qemu uses to forward the connections to the VM's management interface. For example, as per the output above, the `hostfwd=tcp:0.0.0.0:22-10.0.0.15:22` rule forwards connections made to the localhost:22 to the VM's interface 10.0.0.15:22.
274 |
--------------------------------------------------------------------------------