Install & Compatibility
Where this runs
tested against v2.70.75 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 23.7MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 3.0s · import 0.000s · 24MB
22MB installed
● package 22MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
App
✓ from cdk8s import App
Chart
✓ from cdk8s import Chart
Construct
✓ from constructs import Construct
KubeDeployment
✓ from imports import k8s
✗ from cdk8s import KubeDeployment
Kubernetes API objects like KubeDeployment are generated into an 'imports' directory by running `cdk8s import k8s` and are not directly part of the `cdk8s` PyPI package.
This quickstart demonstrates how to define a basic Kubernetes Deployment and Service using `cdk8s`. It requires installing the `cdk8s-cli` (via npm), initializing a project with `cdk8s init python-app`, running `cdk8s import k8s` to generate Kubernetes API constructs, and then placing this code in `main.py`. The `app.synth()` call generates the Kubernetes YAML manifests, which can then be applied to any Kubernetes cluster.
import os
from constructs import Construct
from cdk8s import App, Chart, IntOrString
from imports import k8s # This directory is generated by 'cdk8s import k8s'
class MyChart(Chart):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
# Define a Kubernetes Deployment
k8s.KubeDeployment(self, "my-deployment",
spec=k8s.DeploymentSpec(
replicas=1,
selector=k8s.LabelSelector(
match_labels={"app": "my-app"}
),
template=k8s.PodTemplateSpec(
metadata=k8s.ObjectMeta(
labels={"app": "my-app"}
),
spec=k8s.PodSpec(
containers=[k8s.Container(
name="my-container",
image="nginx:latest",
ports=[k8s.ContainerPort(container_port=80)]
)]
)
)
)
)
# Define a Kubernetes Service
k8s.KubeService(self, "my-service",
spec=k8s.ServiceSpec(
type="LoadBalancer",
ports=[k8s.ServicePort(port=80, target_port=IntOrString.from_number(80))],
selector={"app": "my-app"}
)
)
app = App()
MyChart(app, "my-cdk8s-app")
app.synth()
cdk8s --version
Debug
Known issues
breakingAuto-generated resource names changed between v0.x and v1.0/v2.x. Deploying new manifests with different hashing could cause existing Kubernetes resources to be replaced, leading to downtime or unexpected behavior.fixDuring migration, you can temporarily opt into the legacy hashing mechanism by setting the environment variable `CDK8S_LEGACY_HASH=1`. It is recommended to update resource names and remove this temporary fix once migrated.
affects: <1.0
gotchaThe `cdk8s-cli` tool, essential for project initialization (`init`), generating API constructs (`import`), and synthesizing manifests (`synth`), is written in TypeScript and requires Node.js and npm to be installed globally on your system, even for Python projects.fixEnsure Node.js and npm are installed globally via your preferred package manager (e.g., `npm install -g cdk8s-cli`).
affects: All versions
gotchaKubernetes API objects (e.g., `KubeDeployment`, `KubeService`) are not directly available from the `cdk8s` library package. They are generated into a local `imports` directory by running the `cdk8s import k8s` command. This `imports` directory must be committed to your source control.fixAfter initializing a project, run `cdk8s import k8s` in your project directory. This will create an `imports` folder with the generated type-safe Kubernetes API constructs. Then, import them with `from imports import k8s`.
affects: All versions
breakingThe `cdk8s-plus` library, which provides higher-level abstractions, is versioned per Kubernetes API version (e.g., `cdk8s-plus-34` for Kubernetes 1.34) and is only actively maintained for the three latest Kubernetes releases. Using a `cdk8s-plus` version incompatible with your target cluster can lead to invalid manifests.fixAlways install the `cdk8s-plus-XX` package that matches your target Kubernetes cluster's major API version to ensure compatibility.
affects: All versions of `cdk8s-plus`
gotchaA significant portion of the official `cdk8s` documentation and examples are written for TypeScript. When working with Python, this can lead to confusion regarding property naming (TypeScript's camelCase vs. Python's snake_case) and API structure.fixWhen in doubt, consult the Python API reference generated by `pydoc` (after `cdk8s import k8s`) or directly inspect the generated `imports/__init__.py` file for precise Python API details.
affects: All versions
breakingThe deprecated API `Duration.toISOString()` has been removed. Use `Duration.toIsoString()` instead.fixUpdate calls from `Duration.toISOString()` to `Duration.toIsoString()`.
affects: Introduced in v1.0
breakingThe `cdk8s-plus` library introduced several breaking changes in its 2.0.0 release, including removal of `service.addDeployment`, renaming `service.serve` to `service.bind`, and changing `container.addEnv` to `container.env.addVariable`.fixRefer to the specific `cdk8s-plus` changelog for detailed migration steps when upgrading to version 2.x or higher of the `cdk8s-plus` library.
affects: cdk8s-plus < 2.0.0 to >= 2.0.0
Errors
Common errors & fixes
"import" does not work through a network proxy
The `cdk8s import` command, which is part of the `cdk8s-cli` (written in TypeScript), often fails in environments requiring HTTP(S) requests to go through a network proxy because the underlying Node.js `http(s)` modules do not natively support standard `HTTP_PROXY` and `HTTPS_PROXY` environment variables.
fixAs a workaround, configure your environment or `npm` to correctly route traffic through the proxy, or download the necessary Kubernetes API specifications manually and use them for local import. Ensure that Node.js and npm proxy configurations are correctly set up.
jsii.errors.JavaScriptError: Caused by: Error: EBUSY: resource busy or locked, open '.../node_modules/generated/package.json'
This error, often seen as 'Multiple Imports Fail To Synth', occurs when `cdk8s synth` fails due to name collisions within the generated Node.js packages, particularly when importing multiple Custom Resource Definitions (CRDs). The `jsii` kernel attempts to untar packages into a temporary directory, and a naming conflict (e.g., multiple packages named 'generated') causes the subsequent untar operations to fail silently or with an EBUSY error.
fixThis was a known bug in older versions of `cdk8s` related to how `jsii-srcmak` generated package names. Ensure you are using the latest version of `cdk8s` and the `cdk8s-cli`. If the issue persists with custom CRDs, you might need to manually inspect the generated `package.json` files for name conflicts or consider importing CRDs individually with unique module names.
undefined: constructs.ConstructOptions
This specific error, often encountered when working with cdk8s in Go, indicates an incompatibility or missing type definition for `constructs.ConstructOptions`. This typically happens due to version mismatches between the `cdk8s` library, `constructs-go` library, or outdated documentation examples referencing types that have been moved or deprecated in newer versions.
fixVerify the imported `constructs-go` module version. For example, if the error occurs with `v10`, try importing `github.com/aws/constructs-go/constructs/v3` or the version specified in the official `cdk8s` Go examples if it's different from the one you're using. Always refer to the official `cdk8s` documentation for the correct import paths and versions for your chosen language.
PodSpec must have at least 1 container
This Kubernetes validation error occurs when a `Deployment` (or other workload resource) is defined without specifying any containers within its pod template. While the user might have intended to add containers, they might be placed incorrectly within the CDK8s construct's properties, or the API structure for defining containers in `cdk8s-plus` might be misunderstood.
fixEnsure that the `containers` property is correctly specified within the `spec.template.spec` object of your `Deployment` construct. If using `cdk8s-plus`, make sure to follow its API for defining containers, as the structure might abstract the underlying Kubernetes API slightly. Double-check the nesting of your resource definition.
a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character
This error occurs when automatically generated resource names (e.g., for Deployments, Services) by cdk8s exceed the Kubernetes DNS_LABEL character limit of 63 characters or contain invalid characters/patterns. This is particularly problematic for long construct paths which contribute to the generated resource name.
fixThis issue was addressed in `cdk8s` by improving the name generation logic to conform to DNS_LABEL standards. Ensure you are using an up-to-date version of `cdk8s`. If you encounter this with specific constructs, you might need to provide shorter, explicit names for your constructs or their parent scopes to reduce the length of the generated resource names.
Upgrade
Version history
2.70.75latest on PyPI · released Jun 12, 2026
Audit
Dependencies
constructsrequiredCore building block library for CDK applications.
cdk8s-plus-XXoptionalProvides higher-level, opinionated abstractions for Kubernetes resources. 'XX' denotes the Kubernetes API version (e.g., cdk8s-plus-34).