Intro to Clusters
Note
For more background information, make sure to check out the demos overview page.
See also the Local Cluster section of the quickstart docs
Obviously to demonstrate anything else with kubernetes, we're going to need a cluster! Clusters might be local or remote, but project-local clusters are part of the core capabilities for k8s.mk.
Actually using a cluster with k8s.mk just requires that KUBECONFIG is set in the environment as usual, whether you're in a scripting context or in tool mode.
For creating a project-local cluster, you can choose amongst what's supported by the toolbox, including some support for minikube, k3d, and kind.
For lifecycle management of remote clusters, k8s.mk can pretty much support whatever tooling you want to use, probably via the technique described here, and does ship with tool containers like eksctl and gcloud. You could also out-source the cluster management via ansible, or terraform, etc, and still use k8s.mk at an orchestration layer.
Manual Cluster Management
There are few ways to handle cluster lifecycle automation, ranging from pretty explicit to more magical, depending on your appetite for abstraction.
The most direct way to manage clusters is by using dispatch to run scripts inside the relevant tool containers. For example, with the kind container:
#!/usr/bin/env -S make -f
# Demonstrate explicit/manual cluster management with tool containers.
#
# USAGE:
# ./demos/kind.mk clean create
#
# REF:
# [1] https://robot-wranglers.github.io/k8s-tools/clusters/
#░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
include k8s.mk
$(call compose.import, file=k8s-tools.yml)
# Ignore any kubeconfig in an environment and start fresh
export KUBECONFIG:=./local.cluster.yml
$(shell umask 066; touch ${KUBECONFIG})
# Main entrypoint
__main__: clean create
# Cluster "clean" API from scripts that run in containers
clean:; $(call compose.bind.script, kind)
define clean
set -x
kind delete cluster --name kind-demo || true
endef
# Cluster "create" API from scripts that run in containers
create:; $(call compose.bind.script, kind)
define create
set -x
kind create cluster --name kind-demo --kubeconfig ${KUBECONFIG}
endef
Writing script for usage inside the cluster-management tool container is mostly a backup plan in case k8s.mk has no API that covers the use-case. In the case of kind, there is an API actually (see the next section), but this pattern comes up if you need more customized control, or want to drive the other tool-containers (like eksctl, or gcloud).
Cluster CRUD with API
For each of minikube, k3d, and kind, a basic create/read/update/delete api is available.
Amongst other thing this exposes targets like <cluster_type>.get_or_create/<cluster_name> for idempotent operations, and a tiny amount of boilerplate sets up everything:
#!/usr/bin/env -S make -f
# Demonstrate cluster management with API.
#
# USAGE:
# ./demos/kind-2.mk clean create
#
# REF:
# [1] https://robot-wranglers.github.io/k8s-tools/clusters/
#░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
include k8s.mk
# Setup scaffolding for tool containers
# Ignore any kubeconfig in an environment and start fresh
$(call compose.import, file=k8s-tools.yml)
$(call mk.declare, K8S_PROJECT_LOCAL_CLUSTER)
cluster.name=kind-demo
__main__: clean create
# Chain to clean from existing API primitives
clean: kind.delete/${cluster.name}
create: kind.get_or_create/${cluster.name}
Besides using kind.* above, note also the usage of stage/.. declarations, which adds a banner to automation output, and enables some support for artifact storage (like cluster connection details).2
Scaffolded Clusters
In cases where the underlying cluster API meets the cluster-interface, you can skip defining individual targets as seen in the last section, and scaffold clusters directly from metadata.
#!/usr/bin/env -S make -f
# Demonstrate cluster management with API.
#
# USAGE:
# ./demos/kind-3.mk clean create
#
# REF:
# [1] https://robot-wranglers.github.io/k8s-tools/clusters
#░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
include k8s.mk
# Setup scaffolding for tool containers
# Ignore any kubeconfig in an environment and start fresh
$(call compose.import, file=k8s-tools.yml)
$(call mk.declare, K8S_PROJECT_LOCAL_CLUSTER)
# Generate clean/create scaffolding from spec
$(call k8s.scaffold.minikube, name=ansible \
args='--driver=docker -v1 --wait=all --embed-certs')
__main__: clean create deploy
cluster.name=kind-demo
__main__: clean create
# Chain to clean from existing API primitives
# clean: kind.delete/${cluster.name}
# create: kind.get_or_create/${cluster.name}
For each of minikube, k3d, and kind, a basic create/read/update/delete api is available.
Amongst other thing this exposes targets like <cluster_type>.get_or_create/<cluster_name> for idempotent operations, and a tiny amount of boilerplate sets up everything:
#!/usr/bin/env -S make -f
# Demonstrate explicit/manual cluster management with tool containers.
#
# USAGE:
# ./demos/kind.mk clean create
#
# REF:
# [1] https://robot-wranglers.github.io/k8s-tools/clusters/
#░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
include k8s.mk
$(call compose.import, file=k8s-tools.yml)
# Ignore any kubeconfig in an environment and start fresh
export KUBECONFIG:=./local.cluster.yml
$(shell umask 066; touch ${KUBECONFIG})
# Main entrypoint
__main__: clean create
# Cluster "clean" API from scripts that run in containers
clean:; $(call compose.bind.script, kind)
define clean
set -x
kind delete cluster --name kind-demo || true
endef
# Cluster "create" API from scripts that run in containers
create:; $(call compose.bind.script, kind)
define create
set -x
kind create cluster --name kind-demo --kubeconfig ${KUBECONFIG}
endef
Besides using kind.* above, note also the usage of stage/.. declarations, which adds a banner to automation output, and enables some support for artifact storage (like cluster connection details).2