Simplified Kubernetes API client for Node.js.
Install via npm:
$ npm i kubernetes-client --save
kubernetes-client provides access to all the Kubernetes objects and includes some niceties for writing simpler code.
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());
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);
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);
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);
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);
You can call the namespace
object to specify the namespace:
core.ns('other-project').rc('http-rc').get(print);
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);
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.
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);
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);
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.
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')
});
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
}
});
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