/kubernetes-client

Simplified Kubernetes API client for Node.js.

Primary LanguageJavaScriptMIT LicenseMIT

kubernetes-client

Build Status

Simplified Kubernetes API client for Node.js.

Installation

Install via npm:

$ npm i kubernetes-client --save

Examples

kubernetes-client provides access to all the Kubernetes objects and includes some niceties for writing simpler code.

Basics

kubernetes-client maps the URI paths in the Kubernetes API to sequences of objects chained together via properties and ending in a function. For example, to GET the ReplicationController named 'http-rc' in the Namespace 'my-project':

const Api = require('kubernetes-client');
const core = new Api.Core({
  url: 'http://my-k8s-api-server.com',
  version: 'v1',  // Defaults to 'v1'
  namespace: 'my-project' // Defaults to 'default'
});

function print(err, result) {
  console.log(JSON.stringify(err || result, null, 2));
}

core.namespaces.replicationcontrollers('http-rc').get(print);

kubernetes-client supports the Extensions API group. For example, GET the Deployment named http-deployment:

const ext = new Api.Extensions({
  url: 'http://my-k8s-api-server.com',
  version: 'v1beta1',  // Defaults to 'v1beta1'
  namespace: 'my-project' // Defaults to 'default'
});

ext.namespaces.deployments('http-deployment').get(print);

kubernetes-client provides a helper to get in-cluster config and accessing the API from a Pod:

const Api = require('kubernetes-client');
const core = new Api.Core(Api.config.getInCluster());

and a helper to get the current-context config from ~/.kube/config:

const Api = require('kubernetes-client');
const core = new Api.Core(Api.config.fromKubeconfig());

Experimental support for promises and async/await

kubernetes-client exposes experimental support for promises via the promises option passed to API group constructors. The API is the same, except for the functions that previously took a callback (e.g., .get). Those functions now return a promise.

// Notice the promises: true
const core = new Api.Core({
  url: 'http://my-k8s-api-server.com',
  version: 'v1',  // Defaults to 'v1'
  promises: true,  // Enable promises
  namespace: 'my-project' // Defaults to 'default'
});

and then:

core.namespaces.replicationcontrollers('http-rc').get()
  .then(result => print(null, result));

or with async/await:

print(null, await core.namespaces.replicationcontrollers('http-rc').get());

You can invoke promise-based and callback-based functions explictly:

print(null, await core.namespaces.replicationcontrollers('http-rc').getPromise());
core.namespaces.replicationcontrollers('http-rc').getCb(print);

Creating and updating

kubernetes-client objects expose .post, .patch, and .put methods. Create the ReplicationController from the example above:

const manifestObject = require('./rc.json');
core.namespaces.replicationcontrollers.post({ body: manifestObject }, print);

or update the number of replicas:

const patch = { spec: { replicas: 10 } };
core.namespaces.replicationcontrollers('http-rc').patch({
  body: patch
}, print);

Using the correct API group and version

kubernetes-client client includes functionality to help determine the correct Kubernetes API group and version to use based on manifests:

const Api = require('kubernetes-client');
const api = new Api.Api({
  url: 'http://my-k8s-api-server.com',
  namespace: 'my-project'
});

const manifest0 = {
  kind: 'Deployment',
  apiVersion: 'extensions/v1beta1'
  ...
};
const manifest1 = {
  kind: 'ReplicationController',
  apiVersion: 'v1'
  ...
};

api.group(manifest0).ns.kind(manifest0).post({ body: manifest0 }, print);
api.group(manifest1).ns.kind(manifest1).post({ body: manifest1 }, print);

Object name aliases

kubernetes-client supports the same aliases as kubectl (e.g., ns for namespaces) and the singular versions of the resource name (e.g., namespace for namespaces). We can shorten the example above:

core.ns.rc('http-rc').get(print);

Switching namespaces

You can call the namespace object to specify the namespace:

core.ns('other-project').rc('http-rc').get(print);

Query parameters

You can optionally specify query string object qs to GET endpoints. kubernetes-client passes qs directly to request. For example to filter based on label selector:

core.ns.rc.get({ qs: { labelSelector: 'service=http,component=api' } }, print);

Label selector filtering

kubernetes-client has a shortcut, matchLabels, for filtering on label selector equality:

core.ns.rc.matchLabels({ service: 'http' }).get(print);

and a more general match method based on Kubernetes Match Expressions:

core.ns.rc.match([{
  key: 'service',
  operator: 'In',
  values: ['http']
}, {
  key: 'deploy',
  operator: 'NotIn',
  values: ['production', 'staging']
}]).get(print);

Note: The Kubernetes API supports label selector filtering for GET methods only. The Kubernetes API does not support label selector filtering for POST, PUT, PATCH, or DELETE.

ThirdPartyResources

You can extend the Kubernetes API using a ThirdPartyResource and kubernetes-client:

const newResoure = {
  apiVersion: 'extensions/v1beta1',
  kind: 'ThirdPartyResource',
  metadata: {
    name: 'new-resource.kubernetes-client.io'
  },
  description: 'Example resource',
  versions: [{
    name: 'v1'
  }]
};

ext.thirdpartyresources.post({ body: newResource }, print);

and then extend an ThirdPartyResource API client with your new resources:

const thirdPartyResources = new Api.ThirdPartyResources({
  url: 'http://my-k8s-api-server.com',
  group: 'kubernetes-client.io',
  resources: ['customresources']  // Notice pluralization!
});

// Access `customresources` as if they were a regular Kubernetes object
thirdPartyResources.ns.customresources.get(print);
thirdPartyResources.addResource('newresources');  // Notice pluralization!
// Now access `newresources`
thirdPartyResources.ns.newresources.get(print);

ReplicationController Pods

kubernetes-client provides a shortcut for listing all Pods matching a ReplicationController selector:

core.ns.rc.po.get(print);

kubernetes-client deletes all the Pods associated with a ReplicationController when it deletes the ReplicationController. You can preserve the Pods:

core.ns.rc.delete({ name: 'http-rc', preservePods: true }, print);

Watching and streaming

You can call .getStream to stream results. This is useful for watching:

const JSONStream = require('json-stream');
const jsonStream = new JSONStream();

const stream = core.ns.po.getStream({ qs: { watch: true } });
stream.pipe(jsonStream);
jsonStream.on('data', object => {
  console.log('Pod:', JSON.stringify(object, null, 2));
});

You can access logs in a similar fashion:

const stream = core.ns.po('http-123').log.getStream({ qs: { follow: true } });
stream.on('data', chunk => {
  process.stdout.write(chunk.toString());
});

Note: the kube-apiserver will close watch connections eventually according to the [--min-request-timeout](http://kubernetes.io/docs/admin/kube-apiserver/ command line argument. kubernetes-client does not attempt to reconnect when the kube-apiserver closes a connection.

Authenticating

kubernetes-client supports Kubernetes apiserver authentication.

Basic authentication (with optional certificate authority):

const core = new Api.Core({
  url: 'https://my-k8s-api-server.com',
  ca: fs.readFileSync('cluster-ca.pem'),
  auth: {
    user: 'user',
    pass: 'pass'
  }
});

or without a certificate authority:

const core = new Api.Core({
  url: 'https://my-k8s-api-server.com',
  insecureSkipTlsVerify: true,
  auth: {
    user: 'user',
    pass: 'pass'
  }
});

token authentication:

const core = new Api.Core({
  url: 'https://my-k8s-api-server.com',
  auth: {
    bearer: 'token'
  }
});

and client certificate authentication:

const core = new Api.Core({
  url: 'https://my-k8s-api-server.com',
  ca: fs.readFileSync('cluster-ca.pem'),
  cert: fs.readFileSync('my-user-cert.pem'),
  key: fs.readFileSync('my-user-key.pem')
});

Passing options to request

kubernetes-client uses request. You can specify request options for kubernetes-client to pass to request:

const core = new Api.Core({
  url: 'https://my-k8s-api-server.com',
  request: {
    timeout: 3000
  }
});

Testing

kubernetes-client includes unit tests and integration tests. Minikube is a tool that makes it easy to run integration tests locally.

Run the unit tests:

$ npm test

The integration tests use a running Kubernetes server. You specify the Kubernetes server context via the CONTEXT environment variable. For example, run the integration tests with the minikube context:

$ CONTEXT=minikube npm run test-integration

More Documentation

License

MIT