1. Answers
  2. Setting up Karpenter Auto-Scaling with GKE

How do I set up Karpenter auto-scaling with GKE?

To set up Karpenter auto-scaling with GKE using Pulumi, you need to follow these steps: create a GKE cluster, install Karpenter, and configure networking. Below is the complete Pulumi program in TypeScript to achieve this.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as k8s from "@pulumi/kubernetes";

// Create a GKE cluster
const cluster = new gcp.container.Cluster("gke-cluster", {
    initialNodeCount: 1,
    minMasterVersion: "latest",
    nodeConfig: {
        machineType: "e2-medium",
    },
});

// Export the cluster name
export const clusterName = cluster.name;

// Get the GKE cluster credentials
const kubeconfig = pulumi.all([cluster.name, cluster.endpoint, cluster.masterAuth]).apply(([name, endpoint, masterAuth]) => {
    const context = `${gcp.config.project}_${gcp.config.zone}_${name}`;
    return `
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: ${masterAuth.clusterCaCertificate}
    server: https://${endpoint}
  name: ${context}
contexts:
- context:
    cluster: ${context}
    user: ${context}
  name: ${context}
current-context: ${context}
kind: Config
preferences: {}
users:
- name: ${context}
  user:
    auth-provider:
      config:
        cmd-args: config config-helper --format=json
        cmd-path: gcloud
        expiry-key: '{.credential.token_expiry}'
        token-key: '{.credential.access_token}'
      name: gcp
`;
});

// Create a Kubernetes provider instance using the kubeconfig
const provider = new k8s.Provider("gkeK8s", {
    kubeconfig: kubeconfig,
});

// Install Karpenter using Helm chart
const karpenterNamespace = new k8s.core.v1.Namespace("karpenter", {
    metadata: { name: "karpenter" },
}, { provider });

const karpenterServiceAccount = new k8s.core.v1.ServiceAccount("karpenter", {
    metadata: {
        namespace: karpenterNamespace.metadata.name,
        name: "karpenter",
    },
}, { provider });

const karpenterChart = new k8s.helm.v3.Chart("karpenter", {
    chart: "karpenter",
    fetchOpts: {
        repo: "https://charts.karpenter.sh",
    },
    namespace: karpenterNamespace.metadata.name,
    values: {
        serviceAccount: {
            create: false,
            name: karpenterServiceAccount.metadata.name,
        },
    },
}, { provider });

// Configure networking for Karpenter
const networkPolicy = new k8s.networking.v1.NetworkPolicy("karpenter-network-policy", {
    metadata: {
        namespace: karpenterNamespace.metadata.name,
    },
    spec: {
        podSelector: {
            matchLabels: {
                "app.kubernetes.io/name": "karpenter",
            },
        },
        policyTypes: ["Ingress", "Egress"],
        ingress: [{
            from: [{
                podSelector: {
                    matchLabels: {
                        "app.kubernetes.io/name": "karpenter",
                    },
                },
            }],
        }],
        egress: [{
            to: [{
                podSelector: {
                    matchLabels: {
                        "app.kubernetes.io/name": "karpenter",
                    },
                },
            }],
        }],
    },
}, { provider });

// Export the kubeconfig
export const kubeconfigOutput = kubeconfig;

In this program:

  1. A GKE cluster is created using the gcp.container.Cluster resource.
  2. The cluster’s kubeconfig is generated and used to create a Kubernetes provider.
  3. Karpenter is installed using a Helm chart in a dedicated namespace.
  4. A NetworkPolicy is configured to manage networking for Karpenter.

This setup ensures that Karpenter is installed and configured with the necessary networking policies on a GKE cluster.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up