Project Structure

    The kind project is composed of two parts: the CLI and the packages that implement kind's functionality.We will go more in depth below.

    kind's CLI commands are defined in cmd/kind.Each subdirectory corresponds to a command, and each of their subdirectoriesimplements a subcommand.The CLI is built using and you can see the app's entrypoint,

    commands rely on the functionality of the packages directory.Here, you will find everything needed to build container images for kind;create clusters from these images; interact with the Docker engine and file system; customize configuration files; and logging.

    Developer Tooling

    Kind includes some tools to help developers maintain the source code compliant to Go best coding practices using tools such as Go fmt, Go lint, and Go vet. It also includes utility scripts that will generate code necessary for kind to make use of Kubernetes-style resource definitions.

    Tools are included in the hack/ directory and fall in one of two categories:

    • verify-* : verify that source code is in a good state

    We will proceed by describing all of the current tooling in .

    You can check the compliance of the entire project by running the verify-all.sh script. This script will do the following:

    • check spelling using client9/misspell
    • check that the code is properly formatted using Go fmt
    • check that all source code (except vendored and generated code) successfully passes Go lint’s style rules
    • verify that all code successfully passes Go vet’s tests
    • verify that any of the generated files is up to date
    • runs update-deps.sh to obtain all of the project’s dependencies
    • runs update-generated.sh to generate code necessary to generate Kubernetes API code for kind, see
    • runs update-gofmt.sh which formats all Go source code using the Go fmt tool.

    Let’s go a little in depth on each of these files.

    update-deps.sh performs the following steps:

    • runs to remove any no-longer-needed dependencies from go.mod and add any dependencies needed for other combinations of OS, architecture, and build tags
    • runs go mod vendor, which re-populates the vendor directory, resets the main module's vendor directory to include all packages needed to build and test all of the module's packages based on the state of the go.mod files and Go source code.
    • finally, it prunes the vendor directory of any unnecessary files (keeps code source files, licenses, author files, etc).

    runs gofmt on all nonvendored source code to format and simplify the code.

    update-generated.sh in short, generates Go source code that is necessary to use a Kubernetes-style resource definition to define a schema that can be use to configure Kind.

    Going a bit more in depth, update-generated.sh does the following:

    • Installs the deepcopy-gen, defaulter-gen, and conversion-gen tools from .

    These programs are used to generate Kubernetes-like APIs. These programs are run in the following sequence: deepcopy -> defaulter -> conversion.

    To understand this process better, we need to keep in mind that kind’s configuration schema dictates how to bootstrap a Kubernetes cluster. The schema is defined inkind/pkg/cluster/config.In this directory, currently, you will see two subdirectories:.Each of these subdirectories corresponds to a version of kind’s cluster configuration.

    The way this is implemented is by running deepcopy-gen and defaulter-gen inkind/pkg/cluster/config,followed by running deepcopy-gen, defaulter-gen, and conversion-gen on all version subdirectories(i.e. ).

    The kubernetes/code-generator tools work by comment tags which are specified in the doc.go file for each directory. For example, all doc.go files within have the following tags:

    Additionally, pkg/cluster/config/types.go has an additional tag:

    Let’s see how this tags work with thebinaries deepcopy-gen, defaulter-gen, and conversion-gen.

    For each of the directories related to defining a configuration for kind, we start by running deepcopy-gen. deepcopy-gen generates functions that efficiently perform a full deep-copy of each type that is part of the configuration.

    Once we have these utility functions in place then we will need to runto generate efficient defaulters (functions that will fill in default value for configuration fields) for the configuration schema based on theConfigand the types.The way this works is that the// +k8s:defaulter-gen=TypeMetacomment tag will generate a defaulter for the Config type as this possesses a TypeMeta field.

    The TypeMeta field is defined ink8s.io/apimachinery/pkg/apis/meta/v1. is a struct with a Kind and APIVersion fields. Structures that are versioned or persisted should inline TypeMeta.

    which introduces a conversion task for which the destination package (the top level configuration definition in ) is the one containing the file with the tag.This last step builds on the deep copy generators and defaulters previously created to enable kind to understand any known configuration version.