/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);

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