Custom Docker containers in Cisco Modeling Labs!
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
- An instance of CML
- 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.
-
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
-
Use the
docker save
command to archive the image for CML. We'll be using mytwk95/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
-
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.
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
- An external connector, I prefer to use a bridge with my actual network
- An unmanaged switch
- Your new docker node definition
- Optionally, a host to test the container! I'm using the Chrome container
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!
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!