Connect and control Kubernetes system from NodeJS client
Bài đăng này đã không được cập nhật trong 2 năm
Kubernetes clients
As you know, we have many Kubenetes client, for example
- CLI: kubectl, kubeadm
- Kubenetes NodeJS client
- Java Kuberntes client https://github.com/kubernetes-client/java (official)
- Go lang Kubernetes client https://github.com/kubernetes/client-go
- C# Kubernetes client https://github.com/kubernetes-client/csharp (official)
- etc.

A nearly full list of clients in many programming language at here https://kubernetes.io/docs/reference/using-api/client-libraries/ .
Kuberntes clients for NodeJS / TypeScript / JavaScript
In this article, I share with you client what written in TypeScript by community (not official) https://www.npmjs.com/package/@kubernetes/client-node . GitHub repository at https://github.com/kubernetes-client/javascript (443 Folks, 1,600 starts)
List all pods
Print name of all pods for you
const k8sClient = require('@kubernetes/client-node');
const kcFromNodeJS = new k8sClient.KubeConfig();
kcFromNodeJS.loadFromDefault();
const k_api = kcFromNodeJS.makeApiClient(k8sClient.CoreV1Api);
k_api.listNamespacedPod('default').then((res) => {
console.log(res.body);
});

Top pods what consuming resource intensively
const k8s = require('../dist/index');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
const metricsClient = new k8s.Metrics(kc);
k8s.topPods(k8sApi, metricsClient, "kube-system")
.then((pods) => {
const podsColumns = pods.map((pod) => {
return {
"POD": pod.Pod.metadata.name,
"CPU(cores)": pod.CPU.CurrentUsage,
"MEMORY(bytes)": pod.Memory.CurrentUsage,
}
});
console.log("TOP PODS")
console.table(podsColumns)
});
k8s.topPods(k8sApi, metricsClient, "kube-system")
.then((pods) => {
const podsAndContainersColumns = pods.flatMap((pod) => {
return pod.Containers.map(containerUsage => {
return {
"POD": pod.Pod.metadata.name,
"NAME": containerUsage.Container,
"CPU(cores)": containerUsage.CPUUsage.CurrentUsage,
"MEMORY(bytes)": containerUsage.MemoryUsage.CurrentUsage,
};
})
});
console.log("TOP CONTAINERS")
console.table(podsAndContainersColumns)
});
See flow stream log
const stream = require('stream');
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const log = new k8s.Log(kc);
const logStream = new stream.PassThrough();
logStream.on('data', (chunk) => {
// use write rather than console.log to prevent double line feed
process.stdout.write(chunk);
});
log.log('default', 'pod1', 'container', logStream, {follow: true, tailLines: 50, pretty: false, timestamps: false})
.catch(err => {
console.log(err);
process.exit(1);
})
.then(req => {
// disconnects after 5 seconds
if (req) {
setTimeout(function(){
req.abort();
}, 5000);
}
});
List Kuberntes cache services
const stream = require('stream');
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const log = new k8s.Log(kc);
const logStream = new stream.PassThrough();
logStream.on('data', (chunk) => {
// use write rather than console.log to prevent double line feed
process.stdout.write(chunk);
});
log.log('default', 'pod1', 'container', logStream, {follow: true, tailLines: 50, pretty: false, timestamps: false})
.catch(err => {
console.log(err);
process.exit(1);
})
.then(req => {
// disconnects after 5 seconds
if (req) {
setTimeout(function(){
req.abort();
}, 5000);
}
});

Create a new namespace
For example, named it is test_a_thursday .
const k8sClient = require('@kubernetes/client-node');
const my_kc = new k8sClient.KubeConfig();
my_kc.loadFromDefault();
const my_api = my_kc.makeApiClient(k8sClient.CoreV1Api);
var namespace = {
metadata: {
name: 'test_a_thursday',
},
};
my_api.createNamespace(blabla_namespace).then(
(response) => {
console.log('Your namespace created! Response: '); console.log(response);
k8sApi.readNamespace(blabla_namespace.metadata.name).then((response) => {
console.log(response);
my_api.deleteNamespace(blabla_namespace.metadata.name, {} /* delete options */);
});
},
(er) => {
console.log('Error you catch: ' + er);
},
);
Config a cluster from source code of programming language (SDK)
const k8s = require('@kubernetes/client-node');
const cluster = {
name: 'my-server',
server: 'http://server.com',
};
const user = {
name: 'my-user',
password: 'some-password',
};
const context = {
name: 'my-context',
user: user.name,
cluster: cluster.name,
};
const kc = new k8s.KubeConfig();
kc.loadFromOptions({
clusters: [cluster],
users: [user],
contexts: [context],
currentContext: context.name,
});
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
Config Ingress
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.NetworkingV1Api); // before 1.14 use extensions/v1beta1
const clientIdentifier = 'my-subdomain';
k8sApi.createNamespacedIngress('default', {
apiVersions: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: `production-custom-${clientIdentifier}`,
labels: {
createdBy: 'node-client',
},
annotations: {
'meta.helm.sh/release-namespace': 'production-auto-deploy',
},
},
spec: {
ingressClassName: 'nginx',
rules: [{
host: `${clientIdentifier}`,
http: {
paths: [{
backend: {
service: {
name: 'production-auto-deploy',
port: {
number: 5000,
},
},
},
path: '/default-kuberiq(/|$)(.*)',
pathType: 'ImplementationSpecific',
}],
},
}],
tls: [{
hosts: [`${clientIdentifier}.example.com`],
}],
},
}).catch(e => console.log(e));
Scale deployement
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.AppsV1Api);
const targetNamespaceName = 'default';
const targetDeploymentName = 'docker-test-deployment';
const numberOfTargetReplicas = 3;
async function scale(namespace, name, replicas) {
// find the particular deployment
const res = await k8sApi.readNamespacedDeployment(name, namespace);
let deployment = res.body;
// edit
deployment.spec.replicas = replicas;
// replace
await k8sApi.replaceNamespacedDeployment(name, namespace, deployment);
}
scale(targetNamespaceName, targetDeploymentName, numberOfTargetReplicas);
Create job from cronjob in cluster
const k8s = require('@kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromCluster();
const batchV1Api = kc.makeApiClient(k8s.BatchV1Api);
const batchV1beta1Api = kc.makeApiClient(k8s.BatchV1beta1Api);
const cronJobName = 'myCronJob';
const jobName = 'myJob';
const job = new k8s.V1Job();
const metadata = new k8s.V1ObjectMeta();
job.apiVersion = 'batch/v1';
job.kind = 'Job';
metadata.name = jobName;
metadata.annotations = {
'cronjob.kubernetes.io/instantiate': 'manual',
};
job.metadata = metadata;
batchV1beta1Api.readNamespacedCronJob(cronJobName, 'default')
.then((cronJobRes) => {
job.spec = cronJobRes.body.spec.jobTemplate.spec;
batchV1Api.createNamespacedJob('default', job)
.then((res) => {
console.log(res.body);
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
These examples are not full list of feature what Kubernetes NodeJS client can bring to you, has more features for you.
Choose correct version of NodeJS client works together with Kubernetes system
Matrix of compatibility

Order of compatibility (greatest to lower):
✓Fully comaptible+Common will work-The Kuberntes cluster has features the JS client cannot use.xNot supported totally

Lastest version (at the time of writing) of NodeJS client is 0.18.1 what support Kuberntes 1.25 (Current version of Kubernetes is 1.27.1)
Author: https://github.com/donhuvy , https://stackoverflow.com/users/3728901
All rights reserved