kubernetes-client
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')
});
request
Passing options to 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