DEV Community

Ytalo
Ytalo

Posted on

How I used js to dynamically create and delete pods in kubernetes

First of all: Why?

Imagine you have a system where your user needs to execute something private on your server quickly and securely, like deploying bots or what Next.js does. This article is perfect for such cases.

But, how do I do it on localhost?

To develop this code, we will use two approaches: production and development. We will use Minikube for the development environment and Azure for the production environment.

How can we start?

We need to define a development path to avoid getting lost. We will need a way to communicate with Kubernetes, as well as to create and delete pods.

Development

We will use the libraries @kubernetes/client-node and @azure.

First

We start by creating the Kubernetes API. To do this, we define a function getKubernetesApi, and in it, we initiate the Kubernetes configuration, something like:

import { ContainerServiceClient } from "@azure/arm-containerservice";
import { DefaultAzureCredential } from "@azure/identity";
import k8s from "kubernetes-client";

async function getKubernetesClient() {
    const kc = new k8s.KubeConfig();
}
Enter fullscreen mode Exit fullscreen mode

Then we define a try catch block, where we test if the environment is production to configure Kubernetes with Azure, or load the default configuration in the development environment. We create and return the client, something like:

async function getKubernetesClient() {
    const kc = new k8s.KubeConfig();
    try {
        if (process.env.NODE_ENV === "production") {
            const credentials = new DefaultAzureCredential();
            const containerServiceClient = new ContainerServiceClient(credentials);
            const response = await containerServiceClient.managedClusters.listClusterAdminCredentials();
            kc.loadFromString(response.kubeconfigs[0].value);
        } else {
            kc.loadFromDefault();
        }
        const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
        return k8sApi;
    } catch (error) {
        console.error("Error while getting Kubernetes API", error);
        return;
    }
}
Enter fullscreen mode Exit fullscreen mode

Second

Next, we define the functions to create and delete pods using the obtained client. For this, we receive data such as the pod name, pod namespace, and metadata for the pod, something like:

async function createPod(metadata, namespace) {
    try {
        const k8sApi = await getKubernetesClient();
        return await k8sApi.createNamespacedPod(namespace, metadata);
    } catch (error) {
        console.error("Error while creating pod", error);
        return;
    }
}

async function deletePod(name, namespace) {
    try {
        const k8sApi = await getKubernetesClient();
        return await k8sApi.deleteNamespacedPod(name, namespace);
    } catch (error) {
        console.error("Error while deleting pod", error);
        return;
    }
}
Enter fullscreen mode Exit fullscreen mode

Third, but not less important

Finally, we export the useful functions to be used in the code and ensure that they cannot be altered during execution. This can be done as:

export default Object.freeze({
    createPod,
    deletePod,
    getKubernetesClient
});
Enter fullscreen mode Exit fullscreen mode

Final Result

import { ContainerServiceClient } from "@azure/arm-containerservice";
import { DefaultAzureCredential } from "@azure/identity";
import k8s from "kubernetes-client";

async function getKubernetesClient() {
    const kc = new k8s.KubeConfig();
    try {
        if (process.env.NODE_ENV === "production") {
            const credentials = new DefaultAzureCredential();
            const containerServiceClient = new ContainerServiceClient(credentials);
            const response = await containerServiceClient.managedClusters.listClusterAdminCredentials();
            kc.loadFromString(response.kubeconfigs[0].value);
        } else {
            kc.loadFromDefault();
        }
        const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
        return k8sApi;
    } catch (error) {
        console.error("Error while getting Kubernetes API", error);
        return;
    }
}

async function createPod(metadata, namespace) {
    try {
        const k8sApi = await getKubernetesClient();
        return await k8sApi.createNamespacedPod(namespace, metadata);
    } catch (error) {
        console.error("Error while creating pod", error);
        return;
    }
}

async function deletePod(name, namespace) {
    try {
        const k8sApi = await getKubernetesClient();
        return await k8sApi.deleteNamespacedPod(name, namespace);
    } catch (error) {
        console.error("Error while deleting pod", error);
        return;
    }
}

export default Object.freeze({
    createPod,
    deletePod,
    getKubernetesClient
});
Enter fullscreen mode Exit fullscreen mode

Top comments (0)