### Start Tilt Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/docs/tilt-setup.md Run the `tilt up` command in the `cluster-api` directory to start the Tilt development environment. ```bash tilt up ``` -------------------------------- ### Install CRDs from Source Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Install the Custom Resource Definitions (CRDs) for the control plane and bootstrap controllers into the management cluster using `make install`. ```bash # Install CRDs make install-controlplane make install-bootstrap ``` -------------------------------- ### Generate Cloud-Init for Initial Control Plane Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use `NewInitControlPlane` to render a cloud-init user-data script for the first control-plane node. This script installs k3s server, embeds TLS certificates, and runs the installer with a pinned version. It supports pre/post k3s commands and additional files like registry configurations. ```go package main import ( "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/cloudinit" "github.com/k3s-io/cluster-api-k3s/pkg/secret" ) func main() { certs := secret.Certificates{} // populated by secret.NewCertificatesForInitialControlPlane input := &cloudinit.ControlPlaneInput{ BaseUserData: cloudinit.BaseUserData{ PreK3sCommands: []string{"apt-get install -y nfs-common"}, PostK3sCommands: []string{"echo done > /tmp/k3s-done"}, K3sVersion: "v1.30.2+k3s2", AirGapped: false, ConfigFile: bootstrapv1.File{ Path: "/etc/rancher/k3s/config.yaml", Content: "cluster-init: true\ntoken: abc123\n", Owner: "root:root", Permissions: "0640", }, AdditionalFiles: []bootstrapv1.File{ { Path: "/etc/rancher/k3s/registries.yaml", Content: "mirrors:\n docker.io:\n endpoint:\n - https://my-registry.example.com\n", Owner: "root:root", Permissions: "0640", }, }, }, Certificates: certs, } userData, err := cloudinit.NewInitControlPlane(input) if err != nil { panic(err) } // userData is a []byte cloud-init YAML; store it in a Secret "value" key fmt.Printf("cloud-init size: %d bytes\n", len(userData)) // Output: cloud-init size: bytes // The rendered cloud-init includes write_files for all certs and runcmd entries like: // - curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.30.2+k3s2 sh -s - server && touch /run/cluster-api/bootstrap-success.complete } ``` -------------------------------- ### Install Cluster API K3s Providers Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Installs Cluster API providers (Bootstrap and Control Plane) for K3s onto a management cluster using `clusterctl`. Requires a `clusterctl.yaml` configuration file and a kind management cluster with Docker socket mounted. ```bash # 1. Create the clusterctl configuration file mkdir -p ~/.config/cluster-api cat > ~/.config/cluster-api/clusterctl.yaml < kind-cluster-with-extramounts.yaml < cluster.yaml # 3. Dry-run to validate kubectl apply -f cluster.yaml --dry-run=server # 4. Apply kubectl apply -f cluster.yaml # 5. Watch machines come up kubectl get machines -w # 6. Retrieve the workload kubeconfig clusterctl get kubeconfig "${CLUSTER_NAME}" > workload-kubeconfig.yaml # 7. Verify the workload cluster kubectl --kubeconfig workload-kubeconfig.yaml get nodes # 8. Delete the cluster (always delete via the top-level Cluster object) kubectl delete cluster "${CLUSTER_NAME}" ``` -------------------------------- ### Monitor Control Plane Rollout Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Monitor the status of the KThreesControlPlane rollout using `kubectl get` with the watch flag. ```bash # Monitor rollout kubectl get kthreescontrolplane my-cluster-control-plane -w ``` -------------------------------- ### KThreesControlPlane Air-Gapped Configuration Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Example of a rendered KThreesControlPlane spec showing air-gapped configuration for etcd proxy and agent. ```yaml spec: kthreesConfigSpec: serverConfig: etcdProxyImage: "my-registry.example.com/alpine/socat:latest" agentConfig: airGapped: true airGappedInstallScriptPath: /opt/install.sh ``` -------------------------------- ### Run Specific E2E Tests with GINKGO_FOCUS Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/test/e2e/README.md To execute a subset of e2e tests, use the `GINKGO_FOCUS` environment variable to filter tests by their spec name. This example runs only tests with '[PR-Blocking]' in their name. ```shell make GINKGO_FOCUS="\[PR-Blocking\]" test-e2e ``` -------------------------------- ### KThreesConfigTemplate for Air-Gapped Worker Nodes Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Defines a KThreesConfigTemplate for air-gapped worker nodes, specifying node labels, taints, Kubelet and KubeProxy arguments, private registry, and an air-gapped installation script. ```yaml apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KThreesConfigTemplate metadata: name: airgapped-workers namespace: default spec: template: spec: agentConfig: nodeLabels: - "node.kubernetes.io/role=worker" - "topology.kubernetes.io/zone=dc1" nodeTaints: - "dedicated=batch:NoSchedule" kubeletArgs: - "max-pods=110" - "node-status-update-frequency=10s" kubeProxyArgs: - "proxy-mode=ipvs" privateRegistry: "/etc/rancher/k3s/registries.yaml" nodeName: "custom-node-name" # Air-gapped: skip online installer; use pre-staged binary airGapped: true airGappedInstallScriptPath: "/opt/install.sh" ``` -------------------------------- ### Get Workload Cluster Kubeconfig Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Retrieves the kubeconfig file for the created workload cluster. ```bash clusterctl get kubeconfig test1 > workload-kubeconfig.yaml ``` -------------------------------- ### Configure Air-Gapped Cluster Deployment Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Sets environment variables for an air-gapped K3s cluster deployment. This requires pre-staging the k3s binary and install script on nodes and setting `agentConfig.airGapped: true`. ```bash # Environment variables for the air-gapped template export CLUSTER_NAME=airgap-cluster export NAMESPACE=default export KUBERNETES_VERSION=v1.30.2+k3s2 export KIND_IMAGE_VERSION=v1.30.0 export WORKER_MACHINE_COUNT=2 export CONTROL_PLANE_MACHINE_COUNT=3 export AIRGAPPED_KIND_IMAGE=my-registry.example.com/kindest/node:v1.30.0 export AIRGAPPED_ALPINE_SOCAT_IMAGE=my-registry.example.com/alpine/socat:latest export AIRGAPPED_INSTALL_SCRIPT_PATH=/opt/install.sh ``` -------------------------------- ### Clone Cluster API Repository Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/docs/tilt-setup.md Clone the Cluster API repository to your local machine. This repository is needed for the development setup. ```bash git clone https://github.com/kubernetes-sigs/cluster-api.git ``` -------------------------------- ### Check Remediation Status Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Retrieve the last remediation event details for a KThreesControlPlane using `kubectl get` and JSONPath. ```bash # Check remediation status kubectl get kthreescontrolplane ha-cluster-control-plane \ -o jsonpath='{.status.lastRemediation}' ``` -------------------------------- ### Deploy Controllers from Source Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Deploy the control plane and bootstrap controllers to the management cluster using `make deploy`. Ensure the `REGISTRY` and image tags are correctly set. ```bash # Deploy controllers to the management cluster make CONTROLPLANE_IMG=${REGISTRY}/controlplane-controller \ CONTROLPLANE_IMG_TAG=dev \ deploy-controlplane make BOOTSTRAP_IMG=${REGISTRY}/bootstrap-controller \ BOOTSTRAP_IMG_TAG=dev \ deploy-bootstrap ``` -------------------------------- ### Import Ubuntu 22.04 VM Template to Proxmox Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/samples/proxmox/README.md Use this script to download an Ubuntu 22.04 cloud image, create a new VM, import the disk, and configure its hardware settings. Ensure the specified storage is available in your Proxmox environment. ```bash TEMPLATE_URL=https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64-disk-kvm.img TEMPLATE_VMID=10000 TEMPLATE_NAME=ubuntu-22.04 TEMPLATE_STORAGE=tank TEMPLATE_DISK_OPTIONS="discard=on,iothread=1,ssd=1" curl -o template.img ${TEMPLATE_URL} qm create "${TEMPLATE_VMID}" --name ${TEMPLATE_NAME} --memory 16 qm importdisk "${TEMPLATE_VMID}" template.img "${TEMPLATE_STORAGE}" qm set "${TEMPLATE_VMID}" \ --scsihw virtio-scsi-single \ --scsi0 ${TEMPLATE_STORAGE}:vm-${TEMPLATE_VMID}-disk-0,${TEMPLATE_DISK_OPTIONS} \ --boot order=scsi0 \ --cpu host \ --rng0 source=/dev/urandom \ --template 1 \ --agent 1 \ --onboot 1 ``` -------------------------------- ### Create Kind Management Cluster Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Creates a management cluster using kind with a specified configuration file. ```bash kind create cluster --config kind-cluster-with-extramounts.yaml ``` -------------------------------- ### Configure Tilt Settings Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/docs/tilt-setup.md Create and configure the `tilt-settings.yaml` file to define allowed contexts, trigger modes, default registry, provider repositories, enabled providers, and debugging settings. ```yaml # refer to https://cluster-api.sigs.k8s.io/developer/core/tilt for documentation allowed_contexts: - kind-capi-test trigger_mode: manual # set to auto to enable auto-rebuilding default_registry: '' # empty means use local registry provider_repos: - ../cluster-api-k3s # load k3s as a provider, change to a different path if needed enable_providers: - docker - k3s-bootstrap - k3s-control-plane deploy_observability: - visualizer kustomize_substitutions: # enable some experiment features CLUSTER_TOPOLOGY: "true" EXP_MACHINE_POOL: "true" EXP_CLUSTER_RESOURCE_SET: "true" EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION: "true" EXP_RUNTIME_SDK: "true" # add variables for workload cluster template KUBERNETES_VERSION: "v1.28.6+k3s2" KIND_IMAGE_VERSION: "v1.28.0" WORKER_MACHINE_COUNT: "1" CONTROL_PLANE_MACHINE_COUNT: "1" # Note: kustomize substitutions expects the values to be strings. This can be achieved by wrapping the values in quotation marks. # also, can use this to provide credentials kind_cluster_name: capi-test extra_args: # add extra arguments when launching the binary k3s-bootstrap: - --enable-leader-election=false k3s-control-plane: - --enable-leader-election=false debug: # enable delve for debugging docker: continue: true # change to false if you need the service to be running after the delve has been connected port: 30000 profiler_port: 30001 metrics_port: 30002 core: continue: true port: 31000 profiler_port: 31001 metrics_port: 31002 k3s-bootstrap: continue: true port: 32000 k3s-control-plane: continue: true port: 33000 template_dirs: # add template for fast workload cluster creation, change to a different path if needed # you could also add more templates k3s-bootstrap: # please run `make generate-e2e-templates` to generate the templates first - ../cluster-api-k3s/test/e2e/data/infrastructure-docker ``` -------------------------------- ### Build and Push Docker Images for Development Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md These commands build and push development images for the bootstrap and control plane controllers. Ensure your registry is correctly exported. ```bash # Build image with `dev` tag make BOOTSTRAP_IMG_TAG=dev docker-build-bootstrap make CONTROLPLANE_IMG_TAG=dev docker-build-controlplane # Push image to your registry export REGISTRY="localhost:5001" # Set this to your local/remote registry docker tag ghcr.io/k3s-io/cluster-api-k3s/controlplane-controller:dev ${REGISTRY}/controlplane-controller:dev docker tag ghcr.io/k3s-io/cluster-api-k3s/bootstrap-controller:dev ${REGISTRY}/bootstrap-controller:dev docker push ${REGISTRY}/controlplane-controller:dev docker push ${REGISTRY}/bootstrap-controller:dev ``` -------------------------------- ### Build and Run E2E Tests Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/test/e2e/README.md Build the e2e test image and then run all available e2e tests. The `make docker-build-e2e` command should be run whenever controller code is modified. ```shell make docker-build-e2e make test-e2e ``` -------------------------------- ### Connect to Child Cluster Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Use this command to connect to the child cluster and verify its status by listing all pods. ```bash kubectl --kubeconfig workload-kubeconfig.yaml get pods -A ``` -------------------------------- ### Generate Cloud-Init for Additional Control Plane Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use `NewJoinControlPlane` to render a cloud-init user-data script for subsequent control-plane nodes. This variant does not embed certificates and is used for joining an existing cluster. ```go package main import ( "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/cloudinit" ) func main() { input := &cloudinit.ControlPlaneInput{ BaseUserData: cloudinit.BaseUserData{ K3sVersion: "v1.30.2+k3s2", ConfigFile: bootstrapv1.File{ Path: "/etc/rancher/k3s/config.yaml", Content: "server: https://10.0.0.1:6443\ntoken: abc123\n", Owner: "root:root", Permissions: "0640", }, }, } userData, err := cloudinit.NewJoinControlPlane(input) if err != nil { panic(err) } fmt.Printf("cloud-init size: %d bytes\n", len(userData)) } ``` -------------------------------- ### GenerateInitControlPlaneConfig for First Control Plane Node Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Generates K3sServerConfig for the initial control-plane node, setting cluster-init, injecting TLS SANs, cipher suites, and cloud-provider arguments. Requires controlPlaneEndpoint, cluster join token, server config, and agent config. ```go package main import ( "encoding/json" "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/k3s" "k8s.io/utils/ptr" ) func main() { serverConfig := bootstrapv1.KThreesServerConfig{ TLSSan: []string{"10.0.0.1"}, ClusterCidr: "10.42.0.0/16", ServiceCidr: "10.43.0.0/16", DisableComponents: []string{"traefik"}, DisableCloudController: ptr.To(true), CloudProviderName: ptr.To("external"), SystemDefaultRegistry: "my-registry.example.com", } agentConfig := bootstrapv1.KThreesAgentConfig{ NodeLabels: []string{"node-role.kubernetes.io/control-plane=true"}, KubeletArgs: []string{"max-pods=110"}, } cfg := k3s.GenerateInitControlPlaneConfig( "10.0.0.1", // controlPlaneEndpoint (added to tls-san) "my-secret-token", // cluster join token serverConfig, agentConfig, ) // cfg.ClusterInit == true (set automatically) // cfg.TLSSan == ["10.0.0.1", "10.0.0.1"] (user + endpoint) // cfg.Token == "my-secret-token" b, _ := json.MarshalIndent(cfg, "", " ") fmt.Println(string(b)) // Output (excerpt): // { // "disable-cloud-controller": true, // "kube-apiserver-arg": ["anonymous-auth=true", "tls-cipher-suites=TLS_ECDHE_..."], // "tls-san": ["10.0.0.1", "10.0.0.1"], // "cluster-init": true, // "system-default-registry": "my-registry.example.com", // "token": "my-secret-token", // "kubelet-arg": ["max-pods=110", "cloud-provider=external"], // "node-label": ["node-role.kubernetes.io/control-plane=true"] // } } ``` -------------------------------- ### Clean Up Kind Cluster and Tilt Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/docs/tilt-setup.md Commands to clean up resources: delete workload clusters, stop Tilt, and delete the kind management cluster. ```bash kubectl delete cluster tilt up (ctrl-c) kind delete cluster ``` -------------------------------- ### Push Development Docker Images to Local Registry Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Tag and push the locally built development Docker images to a local registry, such as the one provided by `kind` on port 5001. ```bash # Push to a local registry (e.g. kind registry on port 5001) export REGISTRY="localhost:5001" docker tag ghcr.io/k3s-io/cluster-api-k3s/controlplane-controller:dev \ ${REGISTRY}/controlplane-controller:dev docker tag ghcr.io/k3s-io/cluster-api-k3s/bootstrap-controller:dev \ ${REGISTRY}/bootstrap-controller:dev docker push ${REGISTRY}/controlplane-controller:dev docker push ${REGISTRY}/bootstrap-controller:dev ``` -------------------------------- ### Verify Controller Deployment Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Check if the control plane and bootstrap controller pods are running in their respective namespaces after deployment. ```bash # Verify kubectl get pods -n capi-k3s-bootstrap-system kubectl get pods -n capi-k3s-control-plane-system ``` -------------------------------- ### GenerateJoinControlPlaneConfig for Joining Control Plane Nodes Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Generates K3sServerConfig for additional control-plane nodes joining an existing cluster. Sets the 'server' URL instead of 'cluster-init'. Requires server URL, token, controlPlaneEndpoint, server config, and agent config. ```go package main import ( "encoding/json" "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/k3s" "k8s.io/utils/ptr" ) func main() { serverConfig := bootstrapv1.KThreesServerConfig{ TLSSan: []string{"10.0.0.1"}, DisableCloudController: ptr.To(true), } agentConfig := bootstrapv1.KThreesAgentConfig{} cfg := k3s.GenerateJoinControlPlaneConfig( "https://10.0.0.1:6443", // serverURL "my-secret-token", // token "10.0.0.1", // controlPlaneEndpoint (added to tls-san) serverConfig, agentConfig, ) b, _ := json.MarshalIndent(cfg, "", " ") fmt.Println(string(b)) // Output (excerpt): // { // "tls-san": ["10.0.0.1", "10.0.0.1"], // "server": "https://10.0.0.1:6443", // "token": "my-secret-token" // } } ``` -------------------------------- ### Configure K3s Server Node Options Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Map KThreesServerConfig fields directly to the k3s server configuration file (`/etc/rancher/k3s/config.yaml`) on control-plane machines. ```yaml # Excerpt showing all KThreesServerConfig fields in a KThreesControlPlane spec: kthreesConfigSpec: serverConfig: kubeAPIServerArg: - "audit-log-path=/var/log/apiserver/audit.log" - "audit-policy-file=/etc/kubernetes/audit-policy.yaml" kubeControllerManagerArgs: - "node-monitor-period=5s" kubeSchedulerArgs: - "leader-elect=false" tlsSan: - "192.168.1.100" - "api.my-cluster.example.com" bindAddress: "0.0.0.0" httpsListenPort: "6443" advertiseAddress: "192.168.1.100" clusterCidr: "10.42.0.0/16" serviceCidr: "10.43.0.0/16" clusterDNS: "10.43.0.10" clusterDomain: "cluster.local" disableComponents: - "traefik" - "servicelb" - "metrics-server" disableCloudController: true cloudProviderName: "external" systemDefaultRegistry: "my-private-registry.example.com" # Image used by the etcd proxy daemonset (default: alpine/socat) etcdProxyImage: "my-private-registry.example.com/alpine/socat:latest" ``` -------------------------------- ### Check Management Cluster Pods Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Verifies connectivity to the management cluster by listing all pods. ```bash kubectl get pods -A ``` -------------------------------- ### Generate Air-Gapped Cluster Configuration Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use this command to generate a cluster configuration file for an air-gapped deployment. Ensure environment variables for cluster name, Kubernetes version, and machine counts are set. ```bash clusterctl generate cluster \ --from samples/docker/air-gapped/k3s-template.yaml \ "${CLUSTER_NAME}" \ --kubernetes-version "${KUBERNETES_VERSION}" \ --worker-machine-count "${WORKER_MACHINE_COUNT}" \ --control-plane-machine-count "${CONTROL_PLANE_MACHINE_COUNT}" \ > airgap-cluster.yaml kubectl apply -f airgap-cluster.yaml ``` -------------------------------- ### Generate Worker Cloud-Init User Data Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Generates the cloud-init user-data for worker nodes, which run `k3s agent`. Ensure correct K3s version and air-gapped configuration if needed. ```go package main import ( "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/cloudinit" ) func main() { input := &cloudinit.WorkerInput{ BaseUserData: cloudinit.BaseUserData{ K3sVersion: "v1.30.2+k3s2", AirGapped: true, AirGappedInstallScriptPath: "/opt/install.sh", ConfigFile: bootstrapv1.File{ Path: "/etc/rancher/k3s/config.yaml", Content: "server: https://10.0.0.1:6443\ntoken: abc123\n", Owner: "root:root", Permissions: "0640", }, }, } userData, err := cloudinit.NewWorker(input) if err != nil { panic(err) } // In air-gapped mode the runcmd uses the local install script instead of curl: // - INSTALL_K3S_SKIP_DOWNLOAD=true INSTALL_K3S_EXEC='agent' sh /opt/install.sh && ... fmt.Printf("cloud-init size: %d bytes\n", len(userData)) } ``` -------------------------------- ### Scale K3s Control Plane Replicas Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Patch the KThreesControlPlane resource to scale the number of control plane replicas. Only odd replica counts are supported for embedded etcd. ```bash # Scale control plane from 1 to 3 replicas (adds two new nodes with join config) kubectl patch kthreescontrolplane my-cluster-control-plane \ --type=merge \ -p '{"spec":{"replicas":3}}' ``` -------------------------------- ### KThreesConfigSpec.ServerConfig Fields Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Fields for configuring k3s server nodes, mapping to the `/etc/rancher/k3s/config.yaml` file. ```APIDOC ## `KThreesConfigSpec.ServerConfig` — Server Node Configuration Fields `KThreesServerConfig` maps 1-to-1 onto the k3s server configuration file written to `/etc/rancher/k3s/config.yaml` on control-plane machines. ```yaml # Excerpt showing all KThreesServerConfig fields in a KThreesControlPlane spec: kthreesConfigSpec: serverConfig: kubeAPIServerArg: - "audit-log-path=/var/log/apiserver/audit.log" - "audit-policy-file=/etc/kubernetes/audit-policy.yaml" kubeControllerManagerArgs: - "node-monitor-period=5s" kubeSchedulerArgs: - "leader-elect=false" tlsSan: - "192.168.1.100" - "api.my-cluster.example.com" bindAddress: "0.0.0.0" httpsListenPort: "6443" advertiseAddress: "192.168.1.100" clusterCidr: "10.42.0.0/16" serviceCidr: "10.43.0.0/16" clusterDNS: "10.43.0.10" clusterDomain: "cluster.local" disableComponents: - "traefik" - "servicelb" - "metrics-server" disableCloudController: true cloudProviderName: "external" systemDefaultRegistry: "my-private-registry.example.com" # Image used by the etcd proxy daemonset (default: alpine/socat) etcdProxyImage: "my-private-registry.example.com/alpine/socat:latest" ``` ``` -------------------------------- ### Force K3s Control Plane Rollout Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Force a full rollout of the control plane, even without a version change, by patching the `rolloutAfter` field with the current UTC timestamp. Useful after certificate rotation. ```bash # Force a full rollout even without a version change (e.g. after certificate rotation) kubectl patch kthreescontrolplane my-cluster-control-plane \ --type=merge \ -p "{\"spec\":{\"rolloutAfter\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}}" ``` -------------------------------- ### Define KThreesControlPlane for CACP3 Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use KThreesControlPlane to declaratively manage control plane replicas, k3s version, and machine shape. CACP3 handles initialization, scaling, upgrades, and more. ```yaml apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KThreesControlPlane metadata: name: my-cluster-control-plane namespace: default spec: # Odd numbers only when using embedded etcd (1, 3, 5) replicas: 3 version: v1.30.2+k3s2 machineTemplate: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: DockerMachineTemplate name: my-cluster-control-plane nodeDrainTimeout: 1m0s kthreesConfigSpec: serverConfig: tlsSan: - "0.0.0.0" - "my-cluster.example.com" disableComponents: - "traefik" disableCloudController: true clusterCidr: "10.45.0.0/16" serviceCidr: "10.46.0.0/16" systemDefaultRegistry: "my-registry.example.com" agentConfig: kubeletArgs: - "max-pods=110" # Trigger a rolling replacement of all control plane nodes rolloutAfter: "2024-06-01T00:00:00Z" remediationStrategy: maxRetry: 3 retryPeriod: 5m0s minHealthyPeriod: 1h0m0s --- # The parent Cluster resource that references the KThreesControlPlane apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: name: my-cluster namespace: default spec: clusterNetwork: pods: cidrBlocks: ["10.45.0.0/16"] services: cidrBlocks: ["10.46.0.0/16"] serviceDomain: cluster.local controlPlaneRef: apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KThreesControlPlane name: my-cluster-control-plane infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: DockerCluster name: my-cluster ``` -------------------------------- ### Generate and Apply Cluster Configuration Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/samples/docker/air-gapped/README.md This command generates the Cluster API YAML configuration for the air-gapped K3s cluster, ensuring `airGapped` is set to true in the agent configuration. The generated YAML is then applied to create the cluster. ```shell # Generate the cluster yaml # Note that `airGapped` is set to true in `agentConfig` clusterctl generate yaml --from ./k3s-template.yaml > k3s-airgapped.yaml # Create the cluster to the management cluster kubectl apply -f k3s-airgapped.yaml ``` -------------------------------- ### Inspect Machine Remediation Annotations Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt View the annotations on a specific machine resource to inspect remediation details. ```bash # Inspect remediation annotations on a machine kubectl get machine ha-cluster-control-plane-abc12 \ -o jsonpath='{.metadata.annotations}' ``` -------------------------------- ### Apply Workload Cluster Definition Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Applies the generated cluster definition to create the workload cluster. ```bash kubectl apply -f cluster.yaml ``` -------------------------------- ### Create Kind Management Cluster Configuration Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Defines a kind cluster configuration to expose the Docker socket, necessary for certain Cluster API operations. ```yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 name: capi-quickstart nodes: - role: control-plane extraMounts: - hostPath: /var/run/docker.sock containerPath: /var/run/docker.sock ``` -------------------------------- ### Attach Delve Debugger to K3s Bootstrap Controller Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/docs/tilt-setup.md VS Code launch configuration to attach the Delve debugger to the K3s Bootstrap Controller. Ensure the 'port' matches the one configured in `tilt-settings.yaml`. ```json { "name": "K3s Bootstrap Controller", "type": "go", "request": "attach", "mode": "remote", "remotePath": "", "port": 32000, "host": "127.0.0.1", "showLog": true, "trace": "log", "logOutput": "rpc" } ``` -------------------------------- ### KThreesConfigTemplate and MachineDeployment Reference Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Defines a reusable template for k3s worker node configurations and shows how it's referenced in a MachineDeployment. CABP3 uses the template to create individual KThreesConfig objects for each worker machine. ```yaml apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KThreesConfigTemplate metadata: name: my-cluster-md-0 namespace: default spec: template: spec: version: v1.30.2+k3s2 agentConfig: nodeLabels: - "node.kubernetes.io/worker=true" kubeletArgs: - "max-pods=110" serverConfig: disableComponents: - "traefik" disableCloudController: true ``` ```yaml # Reference in a MachineDeployment apiVersion: cluster.x-k8s.io/v1beta1 kind: MachineDeployment metadata: name: my-cluster-md-0 namespace: default spec: clusterName: my-cluster replicas: 3 selector: matchLabels: cluster.x-k8s.io/cluster-name: my-cluster cluster.x-k8s.io/deployment-name: my-cluster-md-0 template: spec: bootstrap: configRef: apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KThreesConfigTemplate name: my-cluster-md-0 clusterName: my-cluster version: v1.30.2+k3s2 infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: DockerMachineTemplate name: my-cluster-md-0 ``` -------------------------------- ### Generate Workload Cluster Definition Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Generates a Kubernetes cluster definition file using clusterctl, specifying k3s Kubernetes version and worker count. ```bash export KIND_IMAGE_VERSION=v1.30.0 clusterctl generate cluster --from samples/docker/cluster-template-quickstart.yaml test1 --kubernetes-version v1.30.2+k3s2 --worker-machine-count 2 --control-plane-machine-count 1 > cluster.yaml ``` -------------------------------- ### Configure Cluster API k3s Providers Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Specifies the URLs for the k3s bootstrap and control plane provider components in the clusterctl configuration file. ```yaml # NOTE: the following will be changed to use 'latest' in the future providers: - name: "k3s" url: "https://github.com/k3s-io/cluster-api-k3s/releases/v0.2.1/bootstrap-components.yaml" type: "BootstrapProvider" - name: "k3s" url: "https://github.com/k3s-io/cluster-api-k3s/releases/v0.2.1/control-plane-components.yaml" type: "ControlPlaneProvider" ``` -------------------------------- ### Define KThreesControlPlaneTemplate for ClusterClass Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use KThreesControlPlaneTemplate with ClusterClass topologies to provide a reusable control-plane definition for multiple clusters. ```yaml apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KThreesControlPlaneTemplate metadata: name: k3s-control-plane-template namespace: default spec: template: spec: machineTemplate: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: DockerMachineTemplate name: k3s-control-plane kthreesConfigSpec: serverConfig: tlsSan: - "0.0.0.0" disableComponents: - "traefik" disableCloudController: true remediationStrategy: maxRetry: 3 retryPeriod: 5m minHealthyPeriod: 1h --- # Used inside a ClusterClass apiVersion: cluster.x-k8s.io/v1beta1 kind: ClusterClass metadata: name: k3s-clusterclass namespace: default spec: controlPlane: ref: apiVersion: controlplane.cluster.x-k8s.io/v1beta2 kind: KThreesControlPlaneTemplate name: k3s-control-plane-template workers: machineDeployments: - class: default-worker template: bootstrap: ref: apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KThreesConfigTemplate name: k3s-worker-template ``` -------------------------------- ### Generate K3s Worker Node Configuration Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Use `GenerateWorkerConfig` to create the `K3sAgentConfig` for worker nodes joining a K3s cluster. This function takes the server URL, token, server configuration, and agent configuration to produce the final agent configuration. ```go package main import ( "encoding/json" "fmt" bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2" "github.com/k3s-io/cluster-api-k3s/pkg/k3s" "k8s.io/utils/ptr" ) func main() { serverConfig := bootstrapv1.KThreesServerConfig{ CloudProviderName: ptr.To("external"), } agentConfig := bootstrapv1.KThreesAgentConfig{ NodeLabels: []string{"node.kubernetes.io/worker=true"}, NodeTaints: []string{"dedicated=gpu:NoSchedule"}, KubeletArgs: []string{"max-pods=110"}, } cfg := k3s.GenerateWorkerConfig( "https://10.0.0.1:6443", // serverURL "my-secret-token", // token serverConfig, agentConfig, ) b, _ := json.MarshalIndent(cfg, "", " ") fmt.Println(string(b)) // Output: // { // "token": "my-secret-token", // "server": "https://10.0.0.1:6443", // "kubelet-arg": ["max-pods=110", "cloud-provider=external"], // "node-label": ["node.kubernetes.io/worker=true"], // "node-taint": ["dedicated=gpu:NoSchedule"] // } } ``` -------------------------------- ### KThreesConfig for Worker Node Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Defines the bootstrap configuration for a k3s worker node, including custom labels, taints, and extra files. This CRD is consumed by CABP3 and resolved into a cloud-init secret. ```yaml apiVersion: bootstrap.cluster.x-k8s.io/v1beta2 kind: KThreesConfig metadata: name: worker-bootstrap namespace: default spec: version: v1.30.2+k3s2 preK3sCommands: - "apt-get install -y nfs-common" postK3sCommands: - "systemctl enable --now k3s-agent" agentConfig: nodeLabels: - "node-role.kubernetes.io/worker=true" - "topology.kubernetes.io/zone=us-east-1a" nodeTaints: - "dedicated=gpu:NoSchedule" kubeletArgs: - "max-pods=110" airGapped: false serverConfig: disableComponents: - "traefik" tlsSan: - "10.0.0.1" - "my-cluster.example.com" clusterCidr: "10.42.0.0/16" serviceCidr: "10.43.0.0/16" clusterDNS: "10.43.0.10" disableCloudController: true cloudProviderName: "external" files: - path: /etc/rancher/k3s/registries.yaml owner: root:root permissions: "0640" content: | mirrors: docker.io: endpoint: - "https://my-registry.example.com" - path: /opt/custom-script.sh permissions: "0755" contentFrom: secret: name: custom-script-secret key: script.sh ``` -------------------------------- ### Upgrade K3s Version Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Patch the KThreesControlPlane resource to upgrade the k3s version. This triggers a rolling replacement of all control plane nodes. ```bash # Upgrade k3s version (triggers a rolling replacement of all control plane nodes) kubectl patch kthreescontrolplane my-cluster-control-plane \ --type=merge \ -p '{"spec":{"version":"v1.31.0+k3s1"}}' ``` -------------------------------- ### KThreesConfigSpec.AgentConfig Fields Source: https://context7.com/k3s-io/cluster-api-k3s/llms.txt Fields for configuring k3s agent (worker) nodes, also embedded in server node configurations. ```APIDOC ## `KThreesConfigSpec.AgentConfig` — Agent Node Configuration Fields `KThreesAgentConfig` configures agent (worker) nodes and is also embedded in every server node's configuration. ```yaml ``` -------------------------------- ### Check Workload Cluster Machine State Source: https://github.com/k3s-io/cluster-api-k3s/blob/main/README.md Displays the state of Cluster API machines in the workload cluster. ```bash kubectl get machine ```