Back to all posts

Custom Docker containers in Cisco Modeling Labs!


Banner Image
It's no surprise I'm very fascinated by Docker containers, just ask my wife! So when Cisco Modeling Labs (CML) added support for Docker, you can imagine I was excited for the possibilities that opened up. This new version 2.9 comes with some pretty cool baked-in images like TACPlus, FreeRadius, and even a Dnsmasq server! But what if you want to run your own docker image? Like maybe this same website??


What You Need

  1. An instance of CML
  2. A Docker image you'd like to use

Prepping The Image

I deploy this website in production using a Dockerfile and my own container registry, but for brevity's sake, let's assume you have either built your own image already or pulled one from some registry. Either way, we will need to bundle it up to use it in CML.

  1. First let's see what images we have locally. Run docker image ls to verify your image is available.

    docker image ls
    REPOSITORY                      TAG               IMAGE ID       CREATED        SIZE
    git.twk95.com/twk95/11ty-site   latest            11b0c9d9ec70   8 hours ago    131MB
    linuxserver/wireguard           latest            6c92a81d85f6   2 days ago     118MB
    moby/buildkit                   buildx-stable-1   44f5d48d5c6c   2 months ago   219MB
    

  2. Use the docker save command to archive the image for CML. We'll be using my twk95/11ty-site image for this example.

    docker save -o jesus.twk95.com.tar git.twk95.com/twk95/11ty-site:latest
    ls
    jesus.twk95.com.tar
    

  3. Before we leave the terminal we have to grab one more thing. Run docker image inspect to output the image's checksum. Keep this handy as we'll need it in CML.

    docker image inspect -f '{{ index .Id }}' git.twk95.com/twk95/11ty-site:latest
    sha256:11b0c9d9ec70cb97832fa98029cf0e3548466760646d7431c19a4cc427bc83e0
    


Upload to CML

Next, head to CML. Navigate to Tools > Node and Image Definitions > Image Definitions and upload the .tar file we just created. I'm running WSL2 so it is easy enough to open the linux folder in Windows and upload it to CML. Upload prompt in CML


Create a Node Definition

This next part is lengthy so feel free to download an existing Node definition and tweak as needed. Any options not mentioned here are optional. Refer to the CML Node Definition docs for more information.

General

Setting Value
ID jesus.twk95.com
Description My website (Docker)
Nature server

User Interface

Setting Value
Prefix jesus-
Icon server
Label jesus.twk95.com

Linux Native Simulation

Setting Value
Domain Driver Docker
Simulation Driver server
Disk Driver VirtIO
RAM 1024
CPUs 1

Interfaces

Setting Value
Has a Loopback Interface False
Number of serial ports 1
Interface 0 eth0

Boot

Setting Value
Timeout 30 seconds

Provisioning

Setting Value
Enable Provisioning Enabled
Media Type RAW
Configuration Disk Volume Name cfg
+ ADD FILE
Name config.json
Editable Enable
Content See below
+ ADD FILE
Name boot.sh
Editable Enable
Content See below

config.json

{
  "docker": {
    "image": "git.twk95.com/twk95/11ty-site:latest",
    "mounts": [
      "type=bind,source=cfg/boot.sh,target=/boot.sh"
    ]
  },
  "shell": "/bin/bash",
  "day0cmd": [ "/bin/bash", "/boot.sh" ],
  "busybox": true
}

boot.sh

# insert more commands here
# ip address add dev eth0 10.0.0.1/24
# ip link set dev eth0 up
#
# keep the next line to indicate that the machine is ready
echo "READY" >/dev/console
exit 0

Create an Image Definition

Click on the Create New Image Definition button then use the template below to fill out the form. Again, tweak as needed.

Setting Value
ID jesus.twk95.com-v1.4.3
Label jesus.twk95.com
Description My website in Docker!
Node Definition jesus.twk95.com
Disk Image jesus.twk95.com.tar
Disk Hash hash from earlier

Finally ready to test!

Here's the big moment! Create a new lab in CML and add a few things

  1. An external connector, I prefer to use a bridge with my actual network
  2. An unmanaged switch
  3. Your new docker node definition
  4. Optionally, a host to test the container! I'm using the Chrome container

Lab setup

Lab setup

Final test

Click the custom Docker container and check the IP address, then use that IP to test your new container! Hopefully all went well and you can connect to your container from the host machine like below! Website-ception


Conclusion

It was a lengthy setup but it is very rewarding seeing my website hosted locally in CML, even if its only purpose is to verify connectivity for my labs. Big shout out to Jens Albrecht from the Cisco Community Knowledge Base though. He made a very in-depth tutorial for Radius in CML 2.9 and this blog post relied heavily on that. Linked below, go mark his post as helpful! And as always, if you have any questions feel free to reach out!


References

  1. https://community.cisco.com/t5/cisco-modeling-labs-knowledge-base/how-to-create-your-own-docker-container-for-cml-2-9/ta-p/5322346#toc-hId-628485567
  2. https://developer.cisco.com/docs/modeling-labs/creating-a-new-node-definition/
  3. https://docs.docker.com/build/concepts/dockerfile/