Cluster API Provider k3s

repository·main·Indexed 41 days ago

https://github.com/k3s-io/cluster-api-k3s

Provides Bootstrap (CABP3) and Control Plane (CACP3) providers for Cluster API (CAPI) to manage the lifecycle of k3s clusters. Includes guides for setting up management clusters with kind, installing providers via clusterctl, creating workload clusters, and configuring air-gapped installations or Proxmox VM templates.

Tokens
5.2K
Snippets
19
Records
20
Agent score
52%

What's inside Cluster API Provider k3s

  1. What is Cluster API Provider k3s

    main

    Cluster API Provider k3s provides two specialized Cluster API (CAPI) providers designed to bring up k3s clusters instead of full Kubernetes clusters:

    • Cluster API Bootstrap Provider k3s (CABP3): Responsible for generating instructions (encoded as cloud-init) to transform a Machine into a k3s Kubernetes Node.
    • Cluster API ControlPlane Provider k3s (CACP3): Responsible for managing the lifecycle of control plane machines specifically for k3s.
  2. Build and install k3s providers from source

    main

    Developers can build the Bootstrap and Control Plane controllers locally and deploy them to a management cluster.

    1. Build the images using make with a dev tag.
    2. Tag and push the images to a local or remote registry.
    3. Install CRDs and deploy the components to the management cluster using make install-* and make deploy-* commands, passing the custom registry and tag variables.
    # Build
    make BOOTSTRAP_IMG_TAG=dev docker-build-bootstrap
    make CONTROLPLANE_IMG_TAG=dev docker-build-controlplane
    
    # Push (example using localhost registry)
    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
    
    # Install to management cluster
    make install-controlplane
    make install-bootstrap
    make CONTROLPLANE_IMG=${REGISTRY}/controlplane-controller CONTROLPLANE_IMG_TAG=dev deploy-controlplane
    make BOOTSTRAP_IMG=${REGISTRY}/bootstrap-controller BOOTSTRAP_IMG_TAG=dev deploy-bootstrap
  3. Set up a management cluster using kind

    main

    To use this provider, you first need a management cluster. This guide uses kind with an extra mount to expose the local Docker socket, which is required for the Docker infrastructure provider (CAPD).

    1. Create a configuration file kind-cluster-with-extramounts.yaml to expose /var/run/docker.sock.
    2. Create the cluster using kind create cluster.
    3. Verify connectivity with kubectl get pods -A.
    cat > kind-cluster-with-extramounts.yaml <<EOF
    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
    EOF
    
    kind create cluster --config kind-cluster-with-extramounts.yaml
    
    kubectl get pods -A
  4. Generate and deploy an air-gapped K3s cluster

    main

    Once your custom kind node image is built, you can generate the cluster configuration and deploy it to your management cluster.

    Important: Ensure that the airGapped field is set to true within the agentConfig section of your template to enable air-gapped mode.

    Follow these steps:

    1. Generate the YAML manifest using clusterctl from your template.
    2. Apply the manifest using kubectl to the management cluster.
    # 1. Generate the cluster yaml
    clusterctl generate yaml --from ./k3s-template.yaml > k3s-airgapped.yaml
    
    # 2. Create the cluster in the management cluster
    kubectl apply -f k3s-airgapped.yaml
  5. Import a VM template into Proxmox

    main

    To use a standard KVM optimized Ubuntu 22.04 image as a template in Proxmox, download the cloud image and use the qm CLI tool to create a VM, import the disk, and configure the hardware settings.

    Note that after importing, you must ensure the qemu-guest-agent is installed and enabled within the guest OS for proper integration with Proxmox.

    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
  6. Access the workload cluster kubeconfig

    main

    Once the cluster is created, you can retrieve its kubeconfig using clusterctl get kubeconfig.

    Note for Docker Desktop users: The generated kubeconfig might point to an inaccessible container IP. You must update the server address to point to the host's loopback address via the exposed load balancer port.

    # Get kubeconfig
    clusterctl get kubeconfig test1 > workload-kubeconfig.yaml
    
    # Fix for Docker Desktop (re-pointing to localhost via load balancer port)
    sed -i -e "s/server:.*/server: https:\/\/$(docker port test1-lb 6443/tcp | sed "s/0.0.0.0/127.0.0.1/")/g" ./workload-kubeconfig.yaml
    
    # Connect
    kubectl --kubeconfig workload-kubeconfig.yaml get pods -A
  7. Create a k3s workload cluster

    main

    You can generate a cluster definition from existing templates in the samples/ directory.

    1. Use clusterctl generate cluster with the --from flag pointing to a template (e.g., samples/docker/cluster-template-quickstart.yaml).
    2. Specify the k3s-compatible Kubernetes version using the +k3sX suffix (e.g., v1.30.2+k3s2).
    3. Validate the generated cluster.yaml using kubectl apply --dry-run=server.
    4. Apply the definition to create the cluster.
    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
    
    # Validate
    kubectl apply -f cluster.yaml --dry-run=server
    
    # Deploy
    kubectl apply -f cluster.yaml
  8. Set up a local development environment with Tilt

    main

    To develop cluster-api-k3s with rapid iterative builds, use kind as the management cluster and CAPD (Cluster API Provider Docker) as the infrastructure provider via Tilt.

    Prerequisites

    1. Follow the Cluster API Tilt prerequisites to install necessary tools.
    2. Clone the cluster-api repository. For this guide, it is assumed that cluster-api and cluster-api-k3s reside in the same parent directory:
      $ ls
      cluster-api  cluster-api-k3s

    Setup Steps

    1. Create the management cluster:

      cd cluster-api
      ./hack/kind-install-for-capd.sh
    2. Configure Tilt: Create a tilt-settings.yaml file in your local cluster-api directory. This file defines provider repositories, enabled providers, and Kustomize substitutions.

    3. Launch Tilt: Run the following command from the cluster-api directory:

      tilt up
    4. Create a workload cluster: Use the Tilt UI to create a cluster. If template_dirs is configured in tilt-settings.yaml, you can use the CABP3.templates resource for one-click cluster creation.

    # 1. Clone CAPI
    git clone https://github.com/kubernetes-sigs/cluster-api.git
    
    # 2. Install management cluster
    cd cluster-api
    ./hack/kind-install-for-capd.sh
    
    # 3. Run Tilt
    tilt up
  9. Build a custom kind node image for air-gapped K3s

    main

    To support air-gapped installations, you must build a custom kind node Docker image that contains the K3s binary, required images, and installation scripts. This is done by passing the K3s version, the installation script path, and the alpine/socat tarball as build arguments.

    Use the following command to build the image:

    export AIRGAPPED_KIND_IMAGE=kindnode:airgapped
    export AIRGAPPED_INSTALL_SCRIPT_PATH=/k3s-airgapped-install.sh
    export KUBERNETES_VERSION=v1.28.6+k3s2
    
    docker build -t $AIRGAPPED_KIND_IMAGE . \
    --build-arg="K3S_VERSION=$KUBERNETES_VERSION" \
    --build-arg="INSTALL_SCRIPT_PATH=$AIRGAPPED_INSTALL_SCRIPT_PATH" \
    --build-arg="ALPINE_SOCAT_TARBALL_PATH=./alpine-socat.tar"
  10. Debug k3s providers using Delve

    main

    You can debug CAPI K3s controllers by running them with Delve via Tilt.

    1. In tilt-settings.yaml, configure the debug section for the target service (e.g., k3s-bootstrap or k3s-control-plane) with continue: true and a specific port.
    2. In VS Code, use a remote attach configuration. Ensure the port in your .vscode/launch.json matches the port defined in tilt-settings.yaml.
    {
        "name": "K3s Bootstrap Controller",
        "type": "go",
        "request": "attach",
        "mode": "remote",
        "remotePath": "",
        "port": 32000,
        "host": "127.0.0.1",
        "showLog": true,
        "trace": "log",
        "logOutput": "rpc"
    }
  11. Install k3s Cluster API providers

    main

    To install the k3s providers, you must first configure clusterctl to know where to find the provider manifests.

    1. Create a clusterctl.yaml file in $HOME/.config/cluster-api/ containing the provider names and their component URLs.
    2. Run clusterctl init specifying the k3s bootstrap and control-plane providers, along with your chosen infrastructure provider (e.g., docker).
    3. Wait for the provider pods to reach a running state.
    # $HOME/.config/cluster-api/clusterctl.yaml
    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"
    clusterctl init --bootstrap k3s --control-plane k3s --infrastructure docker