Comprehensive Node.js client library for interacting with Kubernetes clusters with full API coverage and TypeScript support
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
High-level classes for interactive pod operations including command execution, container attachment, port forwarding, and file transfer. These classes provide convenient abstractions over WebSocket-based Kubernetes APIs.
Execute commands in pod containers with support for interactive sessions, TTY mode, and stream handling.
/**
* Execute commands in pod containers
*/
class Exec {
constructor(config: KubeConfig, wsInterface?: WebSocketInterface);
/**
* Execute a command in a container
* @param namespace - Pod namespace
* @param podName - Pod name
* @param containerName - Container name
* @param command - Command to execute (string or array)
* @param stdout - Output stream for stdout
* @param stderr - Output stream for stderr
* @param stdin - Input stream for stdin
* @param tty - Enable TTY mode
* @param statusCallback - Callback for command status
* @returns Promise that resolves to WebSocket connection
*/
exec(
namespace: string,
podName: string,
containerName: string,
command: string | string[],
stdout: stream.Writable | null,
stderr: stream.Writable | null,
stdin: stream.Readable | null,
tty: boolean,
statusCallback?: (status: V1Status) => void
): Promise<WebSocket.WebSocket>;
}Usage Examples:
import { KubeConfig, Exec } from '@kubernetes/client-node';
import * as stream from 'stream';
const kc = new KubeConfig();
kc.loadFromDefault();
const exec = new Exec(kc);
// Execute a simple command
const stdout = new stream.PassThrough();
const stderr = new stream.PassThrough();
stdout.on('data', (data) => {
console.log('STDOUT:', data.toString());
});
stderr.on('data', (data) => {
console.error('STDERR:', data.toString());
});
try {
const ws = await exec.exec(
'default', // namespace
'my-pod', // pod name
'my-container', // container name
['ls', '-la', '/'], // command
stdout, // stdout stream
stderr, // stderr stream
null, // stdin stream
false, // tty mode
(status) => { // status callback
console.log('Command status:', status);
}
);
// Handle WebSocket events
ws.on('close', (code, reason) => {
console.log('Connection closed:', code, reason);
});
} catch (error) {
console.error('Exec error:', error);
}
// Interactive shell session with TTY
const process = require('process');
const interactiveExec = async () => {
try {
const ws = await exec.exec(
'default',
'my-pod',
'my-container',
['/bin/bash'], // shell command
process.stdout, // stdout to console
process.stderr, // stderr to console
process.stdin, // stdin from console
true // TTY mode for interactive session
);
// Handle process signals
process.on('SIGINT', () => {
ws.close();
});
} catch (error) {
console.error('Interactive exec error:', error);
}
};Attach to running containers to interact with their primary process.
/**
* Attach to running containers
*/
class Attach {
constructor(config: KubeConfig, websocketInterface?: WebSocketInterface);
/**
* Attach to a running container
* @param namespace - Pod namespace
* @param podName - Pod name
* @param containerName - Container name
* @param stdout - Output stream for stdout
* @param stderr - Output stream for stderr
* @param stdin - Input stream for stdin
* @param tty - Enable TTY mode
* @returns Promise that resolves to WebSocket connection
*/
attach(
namespace: string,
podName: string,
containerName: string,
stdout: stream.Writable | any,
stderr: stream.Writable | any,
stdin: stream.Readable | any,
tty: boolean
): Promise<WebSocket.WebSocket>;
}Usage Examples:
import { KubeConfig, Attach } from '@kubernetes/client-node';
const kc = new KubeConfig();
kc.loadFromDefault();
const attach = new Attach(kc);
// Attach to container's main process
try {
const ws = await attach.attach(
'default',
'my-pod',
'my-container',
process.stdout, // stdout
process.stderr, // stderr
process.stdin, // stdin
true // TTY mode
);
console.log('Attached to container');
ws.on('close', () => {
console.log('Detached from container');
});
} catch (error) {
console.error('Attach error:', error);
}Forward local ports to pod ports for accessing services running inside containers.
/**
* Forward local ports to pod ports
*/
class PortForward {
constructor(config: KubeConfig, disconnectOnErr?: boolean, handler?: WebSocketInterface);
/**
* Forward ports to a pod
* @param namespace - Pod namespace
* @param podName - Pod name
* @param targetPorts - Array of port numbers to forward
* @param output - Output stream for data
* @param err - Error stream
* @param input - Input stream for data
* @param retryCount - Number of retry attempts
* @returns Promise that resolves to WebSocket or connection function
*/
portForward(
namespace: string,
podName: string,
targetPorts: number[],
output: stream.Writable,
err: stream.Writable | null,
input: stream.Readable,
retryCount?: number
): Promise<WebSocket.WebSocket | (() => WebSocket.WebSocket | null)>;
}Usage Examples:
import { KubeConfig, PortForward } from '@kubernetes/client-node';
import * as net from 'net';
const kc = new KubeConfig();
kc.loadFromDefault();
const portForward = new PortForward(kc);
// Forward local port 8080 to pod port 80
const forwardPort = async () => {
const server = net.createServer((socket) => {
portForward.portForward(
'default', // namespace
'my-pod', // pod name
[80], // target ports
socket, // output stream
null, // error stream
socket, // input stream
0 // retry count
).then((ws) => {
console.log('Port forward established');
socket.on('close', () => {
if (typeof ws === 'function') {
const connection = ws();
if (connection) {
connection.close();
}
} else {
ws.close();
}
});
}).catch((error) => {
console.error('Port forward error:', error);
socket.destroy();
});
});
server.listen(8080, () => {
console.log('Local server listening on port 8080');
console.log('Forwarding to pod my-pod:80');
});
};
forwardPort();
// Simple port forwarding with streams
const simplePortForward = async () => {
const output = new stream.PassThrough();
const input = new stream.PassThrough();
try {
const ws = await portForward.portForward(
'default',
'my-pod',
[3000, 8080], // Forward multiple ports
output,
process.stderr,
input
);
console.log('Port forwarding active');
// Handle data
output.on('data', (data) => {
console.log('Received data:', data.toString());
});
} catch (error) {
console.error('Port forward failed:', error);
}
};Copy files to and from pod containers using tar-based transfer.
/**
* Copy files to/from pod containers
*/
class Cp {
constructor(config: KubeConfig, execInstance?: Exec);
/**
* Copy file from pod to local filesystem
* @param namespace - Pod namespace
* @param podName - Pod name
* @param containerName - Container name
* @param srcPath - Source path in container
* @param tgtPath - Target path on local filesystem
* @returns Promise that resolves when copy is complete
*/
cpFromPod(
namespace: string,
podName: string,
containerName: string,
srcPath: string,
tgtPath: string
): Promise<void>;
/**
* Copy file from local filesystem to pod
* @param namespace - Pod namespace
* @param podName - Pod name
* @param containerName - Container name
* @param srcPath - Source path on local filesystem
* @param tgtPath - Target path in container
* @returns Promise that resolves when copy is complete
*/
cpToPod(
namespace: string,
podName: string,
containerName: string,
srcPath: string,
tgtPath: string
): Promise<void>;
}Usage Examples:
import { KubeConfig, Cp } from '@kubernetes/client-node';
const kc = new KubeConfig();
kc.loadFromDefault();
const cp = new Cp(kc);
// Copy file from pod to local system
const copyFromPod = async () => {
try {
await cp.cpFromPod(
'default', // namespace
'my-pod', // pod name
'my-container', // container name
'/app/config.json', // source path in pod
'./local-config.json' // target path locally
);
console.log('File copied from pod successfully');
} catch (error) {
console.error('Copy from pod failed:', error);
}
};
// Copy file from local system to pod
const copyToPod = async () => {
try {
await cp.cpToPod(
'default', // namespace
'my-pod', // pod name
'my-container', // container name
'./local-data.txt', // source path locally
'/tmp/data.txt' // target path in pod
);
console.log('File copied to pod successfully');
} catch (error) {
console.error('Copy to pod failed:', error);
}
};
// Copy directory from pod
const copyDirectoryFromPod = async () => {
try {
await cp.cpFromPod(
'default',
'my-pod',
'my-container',
'/app/logs/', // source directory in pod
'./pod-logs/' // target directory locally
);
console.log('Directory copied from pod successfully');
} catch (error) {
console.error('Directory copy failed:', error);
}
};
// Batch file operations
const batchOperations = async () => {
const operations = [
// Backup configuration
() => cp.cpFromPod('default', 'my-pod', 'app', '/etc/app/config.yaml', './backups/config.yaml'),
// Update configuration
() => cp.cpToPod('default', 'my-pod', 'app', './new-config.yaml', '/etc/app/config.yaml'),
// Copy logs
() => cp.cpFromPod('default', 'my-pod', 'app', '/var/log/app.log', './logs/app.log')
];
for (const operation of operations) {
try {
await operation();
} catch (error) {
console.error('Operation failed:', error);
}
}
};All pod operations use WebSocket connections for real-time communication.
/**
* WebSocket interface for customizing WebSocket behavior
*/
interface WebSocketInterface {
connect(
path: string,
textHandler: (text: string) => void,
binaryHandler: (binary: Buffer) => void
): WebSocket.WebSocket;
}
/**
* Default WebSocket handler
*/
class WebSocketHandler implements WebSocketInterface {
connect(
path: string,
textHandler: (text: string) => void,
binaryHandler: (binary: Buffer) => void
): WebSocket.WebSocket;
}Pod operations can fail for various reasons. Always handle errors appropriately:
import { ApiException } from '@kubernetes/client-node';
const handlePodOperation = async () => {
try {
const ws = await exec.exec(
'default',
'my-pod',
'my-container',
['echo', 'hello'],
stdout,
stderr,
null,
false
);
} catch (error) {
if (error instanceof ApiException) {
console.error('API Error:', error.code);
if (error.code === 404) {
console.error('Pod not found');
} else if (error.code === 403) {
console.error('Access denied');
}
} else {
console.error('Network or other error:', error.message);
}
}
};Custom WebSocket handling:
import { Exec, WebSocketInterface } from '@kubernetes/client-node';
class CustomWebSocketHandler implements WebSocketInterface {
connect(path: string, textHandler: (text: string) => void, binaryHandler: (binary: Buffer) => void) {
// Custom WebSocket implementation
const ws = new WebSocket(path);
ws.on('message', (data) => {
if (typeof data === 'string') {
textHandler(data);
} else {
binaryHandler(data as Buffer);
}
});
return ws;
}
}
const exec = new Exec(kc, new CustomWebSocketHandler());Stream processing with transforms:
import { Transform } from 'stream';
const colorOutput = new Transform({
transform(chunk, encoding, callback) {
// Add color codes to output
const colored = `\x1b[32m${chunk.toString()}\x1b[0m`;
callback(null, colored);
}
});
const ws = await exec.exec(
'default',
'my-pod',
'my-container',
['tail', '-f', '/var/log/app.log'],
colorOutput.pipe(process.stdout),
process.stderr,
null,
false
);