Skip to content

You are viewing documentation for Instruqt 2.0 Labs. For Tracks documentation, please visit docs.instruqt.com.

Kubernetes Cluster


Defined insandbox.hclAlso known askubernetes_cluster

The k8s_cluster resource creates Kubernetes clusters running in Docker containers using K3s. These clusters provide isolated Kubernetes environments for hands-on learning and testing scenarios.

As a lab author, you can use Kubernetes clusters to provide container orchestration environments:

  • Kubernetes Learning: Provide hands-on experience with kubectl, deployments, services, and other Kubernetes concepts
  • Application Deployment: Deploy and manage complex multi-tier applications using Kubernetes manifests
  • Cluster Administration: Learn cluster management, RBAC, networking policies, and resource management

Kubernetes clusters enable realistic container orchestration scenarios within controlled lab environments.

resource "k8s_cluster" "name" {
network {
id = resource.network.main.meta.id
}
}
resource "k8s_cluster" "name" {
image {
name = "rancher/k3s:latest"
}
network {
id = resource.network.main.meta.id
ip_address = "10.0.0.100"
}
resources {
cpu = 2000 # 2 CPUs
memory = 4096 # 4GB
}
copy_image {
name = "myapp:latest"
}
port {
local = 80
host = 8080
}
volume {
source = "./config"
destination = "/etc/config"
type = "bind"
}
environment = {
CLUSTER_INIT = "true"
}
config {
docker {
no_proxy = ["internal.registry.com"]
insecure_registries = ["internal.registry.com:5000"]
}
}
}

Fields

FieldTypeRequiredDescription
networkblock—Connect this resource to a specific network so it can communicate with other containers or servicesrepeatable
imageblock—Override the image the cluster nodes run. Leave empty to use the default K3s image.
client_nodesnumber—Add worker nodes for labs that teach scheduling, placement, or failover. 0 (default) is a single all-in-one node; 1 or more makes the server a dedicated control plane with that many workers. Each node adds startup time.
volumeblock—Share files from the lab repository into the cluster nodes, or persist data written by themrepeatable
copy_imageblock—Preload images into the cluster so pods start without pulling from a registry. Speeds up the lab and lets it run offline.repeatable
portblock—Expose specific ports so learners can reach services running in the clusterrepeatable
port_rangeblock—Specify a range of ports to open for applications that require multiple connections, such as node ports or multi-service environmentsrepeatable
resourcesblock—Cap the CPU, memory, and disk the cluster can consume
environmentmap(string)—Set environment variables to pass configuration values, API keys, or secrets to the cluster nodes
configblock—Low-level settings for the container runtime backing the cluster nodes

Network

k8s_cluster→Network

Network connections for the cluster

FieldTypeRequiredDescription
idstring—ID of the network to attach the container
targetreferencenetwork—The network to attach the container to
ip_addressstring—Static IP address to assign container for the network, the ip address must be within range defined by the network subnet. If this parameter is omitted an IP address will be automatically assigned.
ConstraintsMust be a valid IPv4 address (e.g., 192.168.1.10)
aliaseslist(string)—Aliases allow alternate names to specified for the container

Image

k8s_cluster→Image

Custom container image for the cluster nodes

FieldTypeRequiredDescription
namestring✓Full image reference, including the registry and an optional tag. Include a specific tag to ensure consistent lab environments.
usernamestring—Only required for private registries. Leave empty for public images.
passwordstring—Only required for private registries. Leave empty for public images.

Volume

k8s_cluster→Volume

Volume mounts for the cluster

FieldTypeRequiredDescription
sourcestring✓The path to mount into the cluster nodes. Can be relative to the file declaring the cluster (`./`) or absolute (`/usr/local/bin`).
destinationstring✓Absolute path inside the cluster nodes where the source is mounted
typestring—The type of the mount, can be one of the following values: - bind: bind the source path to the destination path in the node - volume: source is a Docker volume - tmpfs: create a temporary filesystem
read_onlybool—Prevent the cluster nodes from writing to this mount
bind_propagationstring—Configures bind propagation for Docker volume mounts, only applies to bind mounts, can be one of the following values: - shared - slave - private - rslave - rprivate For more information please see the Docker documentation
bind_propagation_non_recursivebool—Mount only the source directory itself, without the mounts nested below it. Leave off unless nested host mounts are leaking into the node.
selinux_relabelstring—Configures SELinux relabeling for the mount (usually specified as :z or :Z) and can be one of the following values: - shared (Equivalent to :z) - private (Equivalent to :Z)

Copy Image

k8s_cluster→Copy Image

Container images to pre-load into the cluster

FieldTypeRequiredDescription
namestring✓Full image reference, including the registry and an optional tag. Include a specific tag to ensure consistent lab environments.
usernamestring—Only required for private registries. Leave empty for public images.
passwordstring—Only required for private registries. Leave empty for public images.

Port

k8s_cluster→Port

Port mappings for the cluster

FieldTypeRequiredDescription
localstring✓The port the service listens on inside the cluster
hoststring—The host port to map the local port to
protocolstring—The protocol to use when exposing the port

Port Range

k8s_cluster→Port Range

Port range mappings for the cluster

FieldTypeRequiredDescription
rangestring✓The port range to expose, e.g. `8080-8082` would expose the ports `8080`, `8081`, `8082`
enable_hostbool—Expose the port range on the host
protocolstring—The protocol to use when exposing the port

Resources

k8s_cluster→Resources

Resource constraints for the cluster

FieldTypeRequiredDescription
cpunumber—Limit how much CPU power the cluster can use to optimize performance and cost. 1 CPU core = 1000.
cpu_pinlist(number)—Pin the cluster to specific CPU cores for more predictable performance or isolation
memorynumber—Specify how much memory the cluster can use to prevent crashes or resource contention
disknumber—Cap the disk space the cluster can consume
gpublock—Give the cluster access to GPU hardware for accelerated workloads

GPU

k8s_cluster→Resources→GPU

GPU resource constraints

FieldTypeRequiredDescription
driverstring—Select the GPU driver to use for hardware acceleration or GPU-based workloads
device_idslist(string)—Specify which GPU devices the cluster can access when running GPU-based tasks

Config

k8s_cluster→Config

Cluster configuration

FieldTypeRequiredDescription
dockerblock—Configure the Docker daemon inside the cluster nodes

Docker

k8s_cluster→Config→Docker

Docker daemon configuration

FieldTypeRequiredDescription
no_proxylist(string)—Hosts that should bypass the proxy, for example an internal registry reachable directly
insecure_registrieslist(string)—Registries the nodes may pull from over plain HTTP or with an untrusted certificate

KubeConfig

k8s_cluster→KubeConfig

Kubernetes configuration details

Computed Attributes

These attributes are set by the system and are read-only.

AttributeTypeDescription
network[].namestringName will equal the name of the network as created by jumppad
network[].assigned_addressstringAssignedAddress will equal if IPAddress is set, else it will be the value automatically assigned from the network
copy_image[].idstringImage ID from local registry
api_portnumberKubernetes API server port
connector_portnumberConnector service port
container_namestringFQDN of the cluster container
client_container_namelist(string)Fully qualified docker addresses for the client nodes
external_ipstringExternal IP address of the Docker host
kube_config.pathstringPath to kubeconfig file
kube_config.castringCertificate authority data
kube_config.client_certificatestringClient certificate data
kube_config.client_keystringClient key data

k8s_cluster → network

Attaches the cluster to a network for connectivity.

FieldRequiredTypeDescription
id✓reference to networkReference to the ID of a network resource
ip_addressstringStatic IP address for the cluster. Auto-assigned if not specified.
aliaseslist(string)Network aliases. Defaults to empty list.

k8s_cluster → image

Specifies the container image for cluster nodes.

FieldRequiredTypeDescription
name✓stringDocker image name and tag
usernamestringUsername for private registry
passwordstringPassword for private registry

k8s_cluster → resources

Defines resource constraints for the cluster.

FieldRequiredTypeDescription
cpunumberCPU limit in MHz (1000 = 1 CPU)
cpu_pinlist(number)Pin to specific CPU cores
memorynumberMemory limit in MB
gpublockGPU configuration

k8s_cluster → copy_image

Defines local Docker images to copy into the cluster.

FieldRequiredTypeDescription
name✓stringDocker image name and tag to copy from local cache

k8s_cluster → port

Maps container ports to host ports.

FieldRequiredTypeDescription
local✓stringContainer port number
hoststringHost port number. Auto-assigned if not specified.

k8s_cluster → port_range

Maps ranges of container ports to host ports.

FieldRequiredTypeDescription
range✓stringPort range (e.g. “8000-9000”)
enable_hostboolEnable host port mapping. Defaults to false.

k8s_cluster → volume

Mounts volumes into the cluster container.

FieldRequiredTypeDescription
source✓stringSource path on host
destination✓stringDestination path in container
typestringVolume type: “bind”, “volume”, or “tmpfs”. Defaults to “bind”.
read_onlyboolMount as read-only. Defaults to false.

k8s_cluster → resources → gpu

GPU configuration for the cluster.

FieldRequiredTypeDescription
driver✓stringGPU driver to use
device_ids✓list(string)GPU device IDs to assign

k8s_cluster → config

Cluster-specific configuration settings.

FieldRequiredTypeDescription
dockerblockDocker daemon configuration

k8s_cluster → config → docker

Docker daemon settings for the cluster.

FieldRequiredTypeDescription
no_proxylist(string)Registries to exclude from proxy. Defaults to empty list.
insecure_registrieslist(string)Insecure registries to allow. Defaults to empty list.

Kubernetes clusters use a global image cache to optimize bandwidth and performance:

  • Each cluster node has its own Docker image cache
  • Images are pulled through a shared cache proxy
  • After the first pull, subsequent pulls come from the cache
  • Use copy_image blocks to pre-populate cluster with local images
resource "network" "k8s_net" {
subnet = "10.0.0.0/24"
}
resource "k8s_cluster" "basic" {
network {
id = resource.network.k8s_net.meta.id
}
}
resource "k8s_cluster" "production" {
network {
id = resource.network.cluster_network.meta.id
}
resources {
cpu = 4000 # 4 CPUs per node
memory = 8192 # 8GB per node
}
volume {
source = "./k8s-config"
destination = "/etc/kubernetes"
type = "bind"
read_only = true
}
environment = {
K3S_TOKEN = "my-cluster-token"
}
}
resource "k8s_cluster" "custom" {
image {
name = "rancher/k3s:v1.25.3-k3s1"
username = "registry_user"
password = "registry_pass"
}
network {
id = resource.network.secure_network.meta.id
}
config {
docker {
insecure_registries = ["internal.company.com:5000"]
no_proxy = ["internal.company.com"]
}
}
copy_image {
name = "internal.company.com:5000/myapp:v1.2.3"
}
}
resource "k8s_cluster" "app_cluster" {
network {
id = resource.network.app_network.meta.id
}
# Pre-load application images
copy_image {
name = "nginx:1.21"
}
copy_image {
name = "redis:7-alpine"
}
copy_image {
name = "postgres:14"
}
# Expose common ports
port {
local = 80
host = 8080
}
port {
local = 443
host = 8443
}
}

Since terminals cannot directly target k8s_cluster resources, use a container with kubectl:

resource "k8s_cluster" "k8s" {
network {
id = resource.network.main.meta.id
}
}
resource "container" "kubectl" {
image {
name = "bitnami/kubectl:latest"
}
network {
id = resource.network.main.meta.id
}
volume {
source = resource.k8s_cluster.k8s.kube_config.path
destination = "/root/.kube/config"
type = "bind"
}
command = ["sleep", "infinity"]
}
resource "terminal" "k8s_terminal" {
target = resource.container.kubectl
}

The common way to expose cluster workloads is an ingress resource or a proxy container:

resource "ingress" "k8s_dashboard" {
port = 8080
target {
resource = resource.k8s_cluster.k8s
port = 80
config = {
service = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
}
}
}
  1. Resource Planning: Allocate sufficient CPU and memory based on expected workload
  2. Image Pre-loading: Use copy_image for applications that will be deployed
  3. Network Isolation: Create dedicated networks for cluster communication
  4. Configuration Management: Use volumes to provide custom configurations
  5. Registry Configuration: Configure insecure registries for internal/development use
  6. Access Patterns: Use proxy containers for terminal and service access
## Ensure adequate resources for multi-node clusters
resources {
cpu = 2000 # Minimum 2 CPUs for production-like workloads
memory = 4096 # Minimum 4GB for realistic scenarios
}
# Configure registry access for private images
config {
docker {
insecure_registries = ["your-registry:5000"]
}
}
# Ensure cluster is on the same network as accessing resources
resource "container" "client" {
network {
id = resource.network.main.meta.id # Same network as cluster
}
}