Skip to content

Conversation

@ipspace
Copy link
Owner

@ipspace ipspace commented Jan 3, 2026

The "kind" plugin implements Kubernetes in Docker (KinD) cluster for containerlab deployments

@ipspace
Copy link
Owner Author

ipspace commented Jan 3, 2026

@wnagele -- the "kind" plugin (documentation included in PR) successfully starts a single-node or multi-node KinD cluster, including attachments to LAN or P2P links.

The configuration of the cluster nodes (IP addresses and static routes) is still missing, but I think I know how I'll handle that. A few more days...

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new "kind" plugin that implements Kubernetes in Docker (KinD) cluster deployments for containerlab. The plugin creates multi-node Kubernetes clusters from a single node definition, automatically expanding it into control-plane and worker nodes with appropriate networking.

Changes:

  • Adds kind plugin with pre_node_transform hook to expand kind device nodes into KinD clusters
  • Adds kind and kind-node daemon definitions with Linux parent configuration
  • Extends clab provider with cp_sh mode for copying and executing scripts in containers
  • Adds comprehensive documentation for the plugin

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
netsim/providers/clab.py Adds cp_sh mode for copying files into containers before executing them
netsim/extra/kind/plugin.py Core plugin logic to expand kind nodes into control-plane and worker nodes with link replication
netsim/extra/kind/defaults.yml Device definitions for kind and kind-node daemons
netsim/daemons/kind/initial.j2 KinD cluster configuration template
docs/plugins/kind.md Plugin documentation with usage examples
docs/plugins.md Adds kind plugin to documentation index
docs/platforms.md Updates platform support tables and adds daemon-related notes

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@ipspace
Copy link
Owner Author

ipspace commented Jan 15, 2026

@wnagele -- This should be it. The cluster comes up and IP addresses and static routes are configured on cluster nodes.

Would love to hear your feedback before merging it. Thank you!

@ipspace ipspace marked this pull request as draft January 17, 2026 08:40
@ipspace
Copy link
Owner Author

ipspace commented Jan 17, 2026

Will change the way "kind" device is defined and tied to the "kind" plugin based on the kind remark by @jbemmel

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

@ipspace ipspace marked this pull request as ready for review January 20, 2026 09:27
@ipspace ipspace requested a review from jbemmel January 20, 2026 09:28
@ipspace
Copy link
Owner Author

ipspace commented Jan 20, 2026

@jbemmel -- this thing is now ready for review (including your suggestion)

@wnagele -- it would be nice to hear if this meets your needs

@wnagele
Copy link
Contributor

wnagele commented Jan 20, 2026

I'll try to find time this week to give it a spin. Thanks!

@wnagele
Copy link
Contributor

wnagele commented Jan 26, 2026

Did a test drive with this. I got stuck on the point of having to influence the configs inside the worker nodes started by the plugin. How would I be running exec statements in this new plugin?

@ipspace
Copy link
Owner Author

ipspace commented Jan 26, 2026

Did a test drive with this.

Thank you!

I got stuck on the point of having to influence the configs inside the worker nodes started by the plugin. How would I be running exec statements in this new plugin?

What exactly would you like to execute on those nodes? IP addresses and static routes are already configured.

@wnagele
Copy link
Contributor

wnagele commented Jan 26, 2026

As these are K8S nodes - without some further setup they are doing basically nothing. The main things to do here are not network related - applying K8S manifests to get Pods, etc. started. I would have liked to be able to provide those commands via exec statements as there is too broad a range here to abstract them into netlab.

@ipspace
Copy link
Owner Author

ipspace commented Jan 27, 2026

applying K8S manifests to get Pods, etc. started.

And I thought there would be some magic API exposed by the K8s control-plane node and a CLI command you could execute on the host to get the pods deployed.

I would have liked to be able to provide those commands via exec statements as there is too broad a range here to abstract them into netlab.

Here's a topology that executes a command on the control-plane node:

provider: clab
plugin: [ kind ]

nodes:
  kc:
    device: kind
    kind.workers: 2
  kc-control-plane:
    clab.exec:
    - echo "hello, world"
    device: kind-node

However, it's "a bit" hard to get a file into the KinD container as clab.binds does not work. If you insist on executing commands within the containers, it might be best to go with

docker cp some-file kc-control-plane:/etc/something
docker exec kc-control-plane some-command

Unfortunately, "netlab config" or "config" node attribute don't work because the KinD nodes are running systemd and thus have per-tty (or whatever) /tmp directory. I might have a solution for that, but it's in another branch, so I have to merge stuff first.

Let me know what works best for you, and I'll add that to the documentation.

@wnagele
Copy link
Contributor

wnagele commented Jan 27, 2026

Is there a way to influence this? My worker nodes in the cluster have to do forwarding but I cannot switch the role to router for Linux hosts.

initial: /tmp/kind
routing: /tmp/routing
image: kindest/node:v1.34.3
build: 'https://netlab.tools/netlab/clab/#netlab-clab-build'
Copy link
Contributor

@wnagele wnagele Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image here is available in Docker hub. No need to build locally. Remove the build parameter?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, copy-paste blunder.


def setup_kind_cluster(node: Box, topology: Box) -> None:
k_workers = node.get('kind.workers',0)
node.clab['startup-config'] = f'node_files/{node.name}/initial'
Copy link
Contributor

@wnagele wnagele Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any objection to making this conditional? I'd like to be able to set the startup-config in my topology in case I have more advanced configs. A simple if not node.clab.get('startup-config') around it would suffice.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely not a problem, although I'd recommend using a user template in that case.

@ipspace
Copy link
Owner Author

ipspace commented Jan 27, 2026

Is there a way to influence this? My worker nodes in the cluster have to do forwarding but I cannot switch the role to router for Linux hosts.

Allowing the role "router", or even having "kind.role" attribute would be easiest. Let me check how that works with loopbacks.

@wnagele
Copy link
Contributor

wnagele commented Jan 27, 2026

Thanks, aside from my remarks above - this works for my usecase.

@wnagele
Copy link
Contributor

wnagele commented Jan 27, 2026

Found one bug that seems to come somewhere from the kind plugin. Using the following topology - if you remove the plugin it works fine. Otherwise it doesn't seem to work with the defaults.device config anymore.

defaults:
  device: frr

provider: clab
plugin: [ kind ]

nodes:
  edge:
  core:

links: [ edge-core ]
Traceback (most recent call last):
  File "/usr/local/bin/netlab", line 15, in <module>
    netsim.cli.lab_commands(__file__)
  File "/usr/local/lib/python3.12/dist-packages/netsim/cli/__init__.py", line 524, in lab_commands
    mod.run(sys.argv[arg_start:])   # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/netsim/cli/up.py", line 416, in run
    run_up(cli_args)
  File "/usr/local/lib/python3.12/dist-packages/netsim/cli/up.py", line 342, in run_up
    topology = get_topology(args,cli_args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/netsim/cli/up.py", line 96, in get_topology
    topology = create.run(cli_args,'up','Create configuration files, start a virtual lab, and configure it',up_args_parser)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/netsim/cli/create.py", line 166, in run
    augment.main.transform(topology)
  File "/usr/local/lib/python3.12/dist-packages/netsim/augment/main.py", line 127, in transform
    transform_setup(topology)
  File "/usr/local/lib/python3.12/dist-packages/netsim/augment/main.py", line 60, in transform_setup
    augment.groups.copy_group_data(topology)
  File "/usr/local/lib/python3.12/dist-packages/netsim/augment/groups.py", line 741, in copy_group_data
    create_bgp_autogroups(topology)                   # Create AS-based groups
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/netsim/augment/groups.py", line 642, in create_bgp_autogroups
    g_propagate = propagate_global_modules(n_data,topology)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/netsim/modules/__init__.py", line 159, in propagate_global_modules
    if n.device not in topology.defaults.devices:             # Have to do one more check for valid device type
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/box/box.py", line 405, in __contains__
    in_me = super().__contains__(item)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/box/box.py", line 385, in __hash__
    raise BoxTypeError('unhashable type: "Box"')
box.exceptions.BoxTypeError: unhashable type: "Box"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants