Kubernetes JavaScript Client

repository·main·Indexed 24 days ago

https://github.com/kubernetes-client/javascript

A TypeScript-based Kubernetes client for Node.js that allows developers to interact with Kubernetes clusters using JavaScript or TypeScript. The library provides the KubeConfig class for managing cluster, user, and context configurations, as well as utility classes like Exec for running commands in containers and Cp for copying files between local systems and pods. Version 2.0.0-rc.1 utilizes undici for native Node.js fetch.

Tokens
8K
Snippets
11
Records
49
Agent score
80%

What's inside @kubernetes/client-node

  1. Understand client and Kubernetes version compatibility

    main

    The client versioning tracks Kubernetes minor versions. Starting from 0.13.0, the client minor version increments when the underlying Kubernetes API version is updated.

    Compatibility Rules:

    • Newer clients generally work with older Kubernetes clusters, but compatibility is not 100% guaranteed.
    • The client supports $n-2$ versions of Kubernetes.
    • If a Kubernetes cluster is newer than the client's supported range (marked as x in compatibility tables), operations using API versions that were deprecated or removed in the cluster may fail.

    HTTP Backend Evolution:

    • 1.0.0: Migrated from request to node-fetch.
    • 2.0.0: Migrated from node-fetch to undici (native Node.js fetch).
  2. How to use an Informer to watch Kubernetes resources

    main

    An Informer is an abstraction used to watch for changes to specific Kubernetes resources (like Pods or Namespaces) in real-time. It combines a list of current resources with a watch stream to keep a local cache synchronized.

    An Informer allows you to register callbacks for specific event types:

    • Object Events: add, update, delete, and change (which triggers on both add and update).
    • Lifecycle Events: connect (when the watch connection is established or re-established) and error.

    To create an informer, use the makeInformer function, providing the KubeConfig, the API path for the resource, and a listPromiseFn to fetch the initial state. The returned object implements the Informer interface for event handling and the ObjectCache interface for querying the current state of resources.

  3. Configure terminal resizing for Exec sessions

    main

    If the stdout stream provided to the exec method implements the isResizable interface (a ResizableStream), the Exec class will automatically handle terminal resizing.

    It uses an internal TerminalSizeQueue to manage resize events, ensuring that changes to the terminal dimensions are communicated to the container via the WebSocket connection. This is useful for interactive TTY sessions where the layout depends on the terminal size.

  4. Initialize KubernetesObjectApi with KubeConfig

    main

    To interact with any Kubernetes resource dynamically without needing specific typed clients for every resource, use KubernetesObjectApi.makeApiClient. This method is preferred over KubeConfig.makeApiClient because it automatically detects and sets the default namespace from your current KubeConfig context.

    import { KubeConfig } from '@kubernetes/client-node';
    import { KubernetesObjectApi } from './path-to-object-api';
    
    const kc = new KubeConfig();
    kc.loadFromDefault();
    
    const api = KubernetesObjectApi.makeApiClient(kc);
    const client = kc.makeApiClient(KubernetesObjectApi);
    client.setDefaultNamespace(kc);
    return client;
  5. Troubleshoot known issues with headers and kubeconfigs

    main

    Multiple Kubeconfigs

    Credentials are cached based on the kubeconfig username. If you use multiple kubeconfigs with overlapping usernames, credentials may collide.

    Duplicate Header Keys (e.g., Impersonate-Group)

    Because the client uses fetch (via undici), it may merge multiple headers with the same key into a single string (e.g., Impersonate-Group: "group1,group2") instead of a list of strings. If your use case requires multiple distinct header entries for the same key, avoid using the standard client methods and use a low-level library like https instead.

  6. Create a new namespace

    main

    To create a namespace, define a namespace object with metadata.name. Use k8sApi.createNamespace and pass the object inside a body key.

    Note: The createNamespace method expects the resource definition to be wrapped in a body property.

    const k8s = require('@kubernetes/client-node');
    
    const kc = new k8s.KubeConfig();
    kc.loadFromDefault();
    
    const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
    
    var namespace = {
        metadata: {
            name: 'test',
        },
    };
    
    k8sApi.createNamespace({ body: namespace }).then(
        (response) => {
            console.log('Created namespace');
            console.log(response);
            k8sApi.readNamespace({ name: namespace.metadata.name }).then((response) => {
                console.log(response);
                k8sApi.deleteNamespace({ name: namespace.metadata.name });
            });
        },
        (err) => {
            console.log('Error!: ' + err);
        },
    );
  7. Create a cluster configuration programmatically

    main

    Instead of loading a file, you can construct a KubeConfig manually using loadFromOptions. You must provide arrays for clusters, users, and contexts, and specify the currentContext name.

    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);
  8. List all pods in a namespace

    main

    To list pods, initialize a KubeConfig object, load your default configuration (e.g., from ~/.kube/config), and create an API client using CoreV1Api. Use the listNamespacedPod method, passing the namespace in the options object.

    const k8s = require('@kubernetes/client-node');
    
    const kc = new k8s.KubeConfig();
    kc.loadFromDefault();
    
    const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
    
    k8sApi.listNamespacedPod({ namespace: 'default' }).then((res) => {
        console.log(res);
    });
  9. Configure OpenID Connect (OIDC) authentication

    main

    To use OpenID Connect authentication with the Kubernetes client, you must provide a User object with an authProvider configured for oidc. The authProvider.config object requires specific keys to manage token discovery and refreshing.

    Required configuration keys in user.authProvider.config:

    • idp-issuer-url: The URL of the Identity Provider (IDP) issuer.
    • client-id: The client ID assigned by the IDP.
    • id-token: The initial ID token.
    • refresh-token: The initial refresh token used to obtain new ID tokens.
    • client-secret: (Optional) The client secret for the OIDC client.

    Optional configuration keys:

    • idp-certificate-authority: A file path to a custom CA certificate.
    • idp-certificate-authority-data: Raw CA certificate data (used if the file path is not provided).

    When applyAuthentication is called, the OpenIDConnectAuth class automatically checks the expiration of the current id-token and uses the refresh-token to fetch a new one if it has expired.

  10. Configure error handling for invalid configuration entries

    main

    When using helper functions like newClusters, newUsers, or newContexts to parse raw configuration data, you can specify how the client should handle malformed or missing entries using the ConfigOptions object.

    By default, the client uses ActionOnInvalid.THROW, which will cause the parsing process to fail and throw an error if an entry is invalid. Alternatively, you can use ActionOnInvalid.FILTER to silently skip invalid entries and return only the valid ones.

  11. Replace a Kubernetes resource using KubernetesObjectApi.replace()

    main

    The replace method performs a full replacement of a resource (HTTP PUT).

    Parameters:

    • spec: The full Kubernetes resource spec.
    • pretty: (Optional) If 'true', output is pretty printed.
    • dryRun: (Optional) Valid values: All.
    • fieldManager: (Optional) Name of the actor making changes.
    • options: (Optional) Overriding Configuration object.

    Returns a Promise containing the replaced resource.