Skip to content

Kubernetes Cluster

The kubernetes_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 "kubernetes_cluster" "name" {
network {
id = resource.network.main.meta.id
}
}
resource "kubernetes_cluster" "name" {
nodes = 3
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"]
}
}
}
FieldRequiredTypeDescription
networkblockNetwork attachments (repeatable)
nodesnumberNumber of nodes in the cluster. Defaults to 1.
imageblockContainer image for cluster nodes. Defaults to latest K3s.
resourcesblockCPU and memory constraints
copy_imageblockLocal Docker images to copy to cluster (repeatable)
portblockPort mappings (repeatable)
port_rangeblockPort range mappings (repeatable)
volumeblockVolume mounts (repeatable)
environmentmap(string)Environment variables. Defaults to empty map.
configblockCluster configuration settings

kubernetes_cluster → network

Attaches the cluster to a network for connectivity.

FieldRequiredTypeDescription
idreference 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.

kubernetes_cluster → image

Specifies the container image for cluster nodes.

FieldRequiredTypeDescription
namestringDocker image name and tag
usernamestringUsername for private registry
passwordstringPassword for private registry

kubernetes_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

kubernetes_cluster → copy_image

Defines local Docker images to copy into the cluster.

FieldRequiredTypeDescription
namestringDocker image name and tag to copy from local cache

kubernetes_cluster → port

Maps container ports to host ports.

FieldRequiredTypeDescription
localstringContainer port number
hoststringHost port number. Auto-assigned if not specified.

kubernetes_cluster → port_range

Maps ranges of container ports to host ports.

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

kubernetes_cluster → volume

Mounts volumes into the cluster container.

FieldRequiredTypeDescription
sourcestringSource path on host
destinationstringDestination path in container
typestringVolume type: “bind”, “volume”, or “tmpfs”. Defaults to “bind”.
read_onlyboolMount as read-only. Defaults to false.

kubernetes_clusterresources → gpu

GPU configuration for the cluster.

FieldRequiredTypeDescription
driverstringGPU driver to use
device_idslist(string)GPU device IDs to assign

kubernetes_cluster → config

Cluster-specific configuration settings.

FieldRequiredTypeDescription
dockerblockDocker daemon configuration

kubernetes_clusterconfig → 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.

These attributes are available after cluster creation:

Field Type Description
kube_config block Kubernetes configuration details
api_port number Kubernetes API server port
connector_port number Internal connector port
container_name string Docker container name for the cluster
external_ip string External IP address

kubernetes_cluster → kube_config

Kubernetes configuration information for cluster access.

Field Type Description
path string Path to kubeconfig file
ca string Base64-encoded CA certificate
client_certificate string Base64-encoded client certificate
client_key string Base64-encoded client key

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 "kubernetes_cluster" "basic" {
network {
id = resource.network.k8s_net.meta.id
}
}
resource "kubernetes_cluster" "production" {
nodes = 3
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 "kubernetes_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 "kubernetes_cluster" "app_cluster" {
nodes = 2
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 kubernetes_cluster resources, use a container with kubectl:

resource "kubernetes_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.kubernetes_cluster.k8s.kube_config.path
destination = "/root/.kube/config"
type = "bind"
}
command = ["sleep", "infinity"]
}
resource "terminal" "k8s_terminal" {
target = resource.container.kubectl
}

Services cannot directly target kubernetes_cluster resources either. Use ingress resources or proxy containers:

resource "ingress" "k8s_dashboard" {
port = 8080
target {
resource = resource.kubernetes_cluster.k8s
port = 80
config = {
service = "kubernetes-dashboard"
namespace = "kubernetes-dashboard"
}
}
}
  1. Resource Planning: Allocate sufficient CPU and memory based on expected workload
  2. Multi-Node Setup: Use multiple nodes for realistic cluster scenarios
  3. Image Pre-loading: Use copy_image for applications that will be deployed
  4. Network Isolation: Create dedicated networks for cluster communication
  5. Configuration Management: Use volumes to provide custom configurations
  6. Registry Configuration: Configure insecure registries for internal/development use
  7. 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
}
}