Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Cloud Development Kit for Kubernetes
cdk8s (Cloud Development Kit for Kubernetes) is an open-source software development framework for defining Kubernetes applications and resources using familiar programming languages. It allows developers to use high-level constructs and abstractions to define Kubernetes manifests, making it easier to manage and deploy Kubernetes resources programmatically.
Defining Kubernetes Manifests
This code sample demonstrates how to define a Kubernetes Deployment manifest using cdk8s. It creates a deployment with 3 replicas of an NGINX container.
const cdk8s = require('cdk8s');
const { App, Chart } = cdk8s;
const k8s = require('cdk8s-plus-17');
const app = new App();
const chart = new Chart(app, 'MyChart');
new k8s.Deployment(chart, 'MyDeployment', {
spec: {
replicas: 3,
selector: {
matchLabels: { app: 'my-app' }
},
template: {
metadata: { labels: { app: 'my-app' } },
spec: {
containers: [{
name: 'my-app',
image: 'nginx'
}]
}
}
}
});
app.synth();
Using High-Level Constructs
This code sample shows how to use high-level constructs to define a Kubernetes Service manifest. It creates a LoadBalancer service that routes traffic to port 80 of the pods labeled with 'app: my-app'.
const cdk8s = require('cdk8s');
const { App, Chart } = cdk8s;
const k8s = require('cdk8s-plus-17');
const app = new App();
const chart = new Chart(app, 'MyChart');
new k8s.Service(chart, 'MyService', {
spec: {
type: 'LoadBalancer',
ports: [{ port: 80, targetPort: 80 }],
selector: { app: 'my-app' }
}
});
app.synth();
Composing Charts
This code sample demonstrates how to compose multiple Kubernetes resources into a single chart. It defines both a Deployment and a Service within a custom chart class.
const cdk8s = require('cdk8s');
const { App, Chart } = cdk8s;
const k8s = require('cdk8s-plus-17');
class MyChart extends Chart {
constructor(scope, id, props) {
super(scope, id, props);
new k8s.Deployment(this, 'MyDeployment', {
spec: {
replicas: 3,
selector: {
matchLabels: { app: 'my-app' }
},
template: {
metadata: { labels: { app: 'my-app' } },
spec: {
containers: [{
name: 'my-app',
image: 'nginx'
}]
}
}
}
});
new k8s.Service(this, 'MyService', {
spec: {
type: 'LoadBalancer',
ports: [{ port: 80, targetPort: 80 }],
selector: { app: 'my-app' }
}
});
}
}
const app = new App();
new MyChart(app, 'MyChart');
app.synth();
Pulumi is an infrastructure as code tool that allows you to define cloud resources using general-purpose programming languages. It supports Kubernetes and provides a similar approach to cdk8s by allowing you to define Kubernetes resources programmatically. However, Pulumi also supports other cloud providers like AWS, Azure, and Google Cloud, making it a more versatile tool for multi-cloud environments.
Helm is a package manager for Kubernetes that allows you to define, install, and upgrade complex Kubernetes applications using Helm charts. Unlike cdk8s, which uses programming languages to define resources, Helm uses YAML templates. Helm is widely adopted and has a large repository of pre-built charts, making it easier to deploy common applications.
Kustomize is a tool for customizing Kubernetes configurations. It allows you to define overlays to modify existing Kubernetes manifests without using templates. Kustomize is integrated into kubectl, making it a convenient option for Kubernetes users. Unlike cdk8s, Kustomize focuses on configuration management rather than programmatic resource definition.
Cloud Development Kit for Kubernetes
cdk8s is a software development framework for defining Kubernetes applications using rich object-oriented APIs. It allows developers to leverage the full power of software in order to define abstract components called "constructs" which compose Kubernetes resources or other constructs into higher-level abstractions.
This library is the foundation of cdk8s. It includes base types that are used to define cdk8s applications.
The Chart
is a container that synthesizes a single Kubernetes manifest.
class MyChart extends Chart {
constructor(scope: Construct, ns: string) {
super(scope, ns);
// add contents here
}
}
During synthesis, charts collect all the ApiObject
nodes (recursively) and
emit a single YAML manifest that includes all these objects.
An ApiObject
is a construct that represents an entry in a Kubernetes manifest.
In most cases, you won't use ApiObject
directly but rather use classes that
are generated by the cdk8s CLI and extend this base class.
The Include
construct can be used to include an existing manifest in a chart.
The following example will include the Kubernetes Dashboard in MyChart
:
import { Include } from 'cdk8s';
class MyChart extends Chart {
constructor(scope: Construct, id: string) {
super(scope, id);
const dashboard = new Include(this, 'dashboard', {
url: 'https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml',
// or
url: 'dashboard.yaml'
});
// ...other resources
}
}
All API objects defined in the included manifest will be added as children
ApiObject
s under the Include
construct's scope. This implies that you can
use Node.of(include).children
to inspect them.
The following example queries for all the Deployment
resources in the
dashboard:
const deps = Node.of(dashboard)
.children
.filter((c: ApiObject) => c.kind === 'Deployment');
NOTE: names of included objects (metadata.name
) are preserved. This means that
if you try to include the same manifest twice into the same chart, your manifest
will have duplicate definitions of the same objects.
You can declare dependencies between various cdk8s
constructs by using the built-in support of the underlying constructs
model.
For example, you can force kubernetes to first apply a Namespace
before applying the Service
in the scope of that namespace:
const namespace = new k8s.Namespace(chart, 'backend');
const service = new k8s.Service(chart, 'Service', { metadata: { namespace: namespace.name }});
// declare the dependency. this is just a syntactic sugar for Node.of(service).addDependency(namespace)
service.addDependency(namespace);
cdk8s
will ensure that the Namespace
object is placed before the Service
object in the resulting manifest:
apiVersion: v1
kind: Namespace
metadata:
name: chart-backend-a59d2e47
---
apiVersion: v1
kind: Service
metadata:
name: chart-service-93d02be7
namespace: chart-backend-a59d2e47
You can also specify dependencies between charts, in exactly the same manner. For example, if we have a chart that provisions our namespace
, we need that chart to be applied first:
const namespaceChart = new NamespaceChart(app, 'namespace');
const applicationChart = new ApplicationChart(app, 'application');
// declare the dependency. this is just a syntactic sugar for Node.of(applicationChart).addDependency(namespaceChart)
applicationChart.addDependency(namespaceChart);
Running cdk8s synth
will produce the following dist directory:
> cdk8s synth
dist/0000-namespace.k8s.yaml
dist/0001-application.k8s.yaml
Notice that the namespace
chart appears first with the 0000
prefix. This will ensure that a subsequent execution of kubectl apply -f dist/
will apply the namespace
first, and the application
second.
The behavior above applies in the same way to custom constructs that you create or use.
class Database extends Construct {
constructor(scope: Construct, name: string) {
super(scope, name);
new k8s.StatefulSet(this, 'StatefulSet');
new k8s.ConfigMap(this, 'ConfigMap');
}
}
const app = new App();
const chart = new Chart(app, 'Chart');
const service = new k8s.Service(chart, 'Service')
const database = new Database(chart, 'Database');
service.addDependency(database);
Declaring such a dependency will cause each ApiObject
in the source construct, to depend on every ApiObject
in the target construct.
Note that in the example above, the source construct is actually an ApiObject
, which is also ok since it is essentially a construct with a single ApiObject
.
Note that if the source of your dependency is a custom construct, it won't have the
addDependency
syntactic sugar by default, so you'll have to useNode.of()
.
The resulting manifest will be:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: chart-database-statefulset-4627f8e2
---
apiVersion: v1
kind: ConfigMap
metadata:
name: chart-database-configmap-676f8640
---
apiVersion: v1
kind: Service
metadata:
name: chart-service-93d02be7
You can see that all ApiObject
s of the Database
construct, appear before the Service
object.
If you simply declare a dependency between two ApiObject
s (or Constructs
), that belong to two different Chart
s, cdk8s
will create the chart dependency automatically for you.
const namespaceChart = new NamespaceChart(app, 'namespace');
const applicationChart = new ApplicationChart(app, 'application');
const namespace = new k8s.Namespace(namespaceChart, 'namespace');
const deployment = new k8s.Deployment(applicationChart, 'Deployment');
// dependency between ApiObjects, not Charts!
deployment.addDependency(namespace);
Running cdk8s synth
will produce the same result as if explicit chart dependencies were declared:
> cdk8s synth
dist/0000-namespace.k8s.yaml
dist/0001-application.k8s.yaml
This means you need not be bothered with managing chart dependencies, simply work with the ApiObject
s you create, and let cdk8s
infer the chart dependencies.
cdk8s bundles a set of test utilities under the Testing
class:
Testing.app()
returns an App
object bound to a temporary output directory.Testing.synth(chart)
returns the Kubernetes manifest synthesized from a
chart.This project is distributed under the Apache License, Version 2.0.
This module is part of the cdk8s project.
FAQs
This is the core library of Cloud Development Kit (CDK) for Kubernetes (cdk8s). cdk8s apps synthesize into standard Kubernetes manifests which can be applied to any Kubernetes cluster.
The npm package cdk8s receives a total of 89,253 weekly downloads. As such, cdk8s popularity was classified as popular.
We found that cdk8s demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.