# How to Integrate KCL with Kubernetes Effectively Using the kubectl-kcl Plugin

> Learn to integrate KCL with Kubernetes effectively using the kubectl-kcl plugin. Streamline KCL file compilation to YAML/JSON manifests for kubectl apply, diff, and validate operations.

- Repository: [The KCL Programming Language/kcl](https://github.com/kcl-lang/kcl)
- Tags: how-to-guide
- Published: 2026-03-05

---

**The kubectl-kcl plugin bridges the KCL configuration language with Kubernetes by adding sub-commands to kubectl that compile KCL files into standard YAML/JSON manifests and stream them directly to kubectl apply, diff, or validate operations.**

The kcl-lang/kcl repository provides a constraint-based configuration language designed for cloud-native infrastructure. By integrating KCL with Kubernetes through the kubectl-kcl plugin, developers can generate, mutate, and validate manifests directly from KCL source files while maintaining the familiar kubectl workflow.

## Architectural Overview

The kubectl-kcl plugin serves as a CLI bridge between the KCL compiler (`kclc`) and the Kubernetes API server. According to the source code in [`README.md`](https://github.com/kcl-lang/kcl/blob/main/README.md) at lines 38 and 55, the plugin is highlighted as a primary integration mechanism that enables developers to leverage KCL's high-level abstraction capabilities while preserving standard Kubernetes deployment patterns.

The workflow maintains separation between the compilation and deployment phases:

1. **KCL Program** – describes resources, constraints, and reuse logic in `.k` files
2. **kubectl-kcl** – parses arguments, invokes the KCL compiler, and renders manifests
3. **kubectl** – receives the rendered YAML/JSON and communicates with the Kubernetes API server exactly as it would with static manifests

This architecture enables **offline validation** via `kubectl kcl validate`, allowing policy enforcement before any cluster interaction occurs.

## Installing the kubectl-kcl Plugin

Install the plugin via Homebrew to register it as a kubectl sub-command:

```bash
brew install kcl-lang/kcl/kubectl-kcl

```

Alternatively, download the binary directly from the [kubectl-kcl releases page](https://github.com/kcl-lang/kubectl-kcl/releases). Once installed, verify the plugin is available:

```bash
kubectl kcl --help

```

## Rendering Kubernetes Manifests

Write KCL programs that import Kubernetes API types. The [`crates/ast/src/ast.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/ast/src/ast.rs) file at line 673 demonstrates how KCL handles package imports for the Kubernetes SDK:

```kcl

# pod.k

import "k8s.io/api/core/v1"

pod = v1.Pod {
    metadata = {
        name = "hello-pod"
        labels = {
            app = "hello"
        }
    }
    spec = {
        containers = [
            {
                name  = "hello"
                image = "nginx:1.25"
                ports = [{ containerPort = 80 }]
            }
        ]
    }
}

```

Render the KCL file to standard Kubernetes YAML:

```bash
kubectl kcl render pod.k

```

The command prints the compiled manifest to stdout, which you can inspect or pipe to other tools.

## Applying KCL Files Directly to Clusters

Deploy KCL configurations without intermediate manual steps:

```bash
kubectl kcl apply pod.k

```

Under the hood, the plugin compiles the KCL file and streams the output to `kubectl apply -f -`, creating resources in your current context. This ensures compatibility with existing kubectl features like context switching and namespace targeting.

## Validating Constraints Before Deployment

KCL supports inline assertions for policy-as-code enforcement. Add constraints to validate configurations before they reach the cluster:

```kcl

# pod_with_constraints.k

import "k8s.io/api/core/v1"

pod = v1.Pod {
    metadata = {
        name = "hello-pod"
        labels = { app = "hello" }
    }
    spec = {
        containers = [{
            name  = "hello"
            image = "nginx:1.25"
            ports = [{ containerPort = 80 }]
        }]
    }
}

# Enforce policy at compile time

assert spec.containers[0].ports[0].containerPort == 80, "Port 80 is required"

```

Validate locally without cluster connectivity:

```bash
kubectl kcl validate pod_with_constraints.k

```

Failed assertions cause a non-zero exit status and print the error message, preventing invalid deployments.

## Diffing Against Live Cluster State

Preview changes before applying them:

```bash
kubectl kcl diff pod.k

```

This command renders the KCL file and executes `kubectl diff` to compare the generated manifest against the live resource in the cluster, displaying additions, deletions, and modifications.

## Advanced kubectl-kcl Usage Patterns

| Feature | Command | Description |
|---------|---------|-------------|
| **Parameterization** | `kubectl kcl run -D env=prod config.k` | Pass external variables (`-D`) into KCL programs for environment-specific rendering |
| **Bulk Operations** | `kubectl kcl apply dir/**/*.k` | Process multiple KCL modules using glob patterns |
| **JSON Output** | `kubectl kcl render -o json pod.k` | Generate JSON instead of the default YAML format |
| **Client-Side Dry Run** | `kubectl kcl apply --dry-run=client pod.k` | Validate manifests without modifying cluster state |

All flags passed to kubectl-kcl are forwarded to the underlying kubectl command, preserving familiar ergonomics.

## Summary

- The **kubectl-kcl plugin** compiles KCL source files into standard Kubernetes manifests and pipes them directly to kubectl commands
- Key source references include [`README.md`](https://github.com/kcl-lang/kcl/blob/main/README.md) (lines 38 and 55) for integration documentation and [`crates/ast/src/ast.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/ast/src/ast.rs) (line 673) for package import handling
- Core commands include `kubectl kcl render`, `apply`, `validate`, and `diff`, supporting the complete deployment lifecycle
- **Offline validation** via assertions enables policy enforcement before cluster interaction
- The architecture maintains strict separation between the KCL compiler and Kubernetes API, allowing independent tooling evolution

## Frequently Asked Questions

### What is the difference between kubectl kcl apply and standard kubectl apply?

**kubectl kcl apply** first invokes the KCL compiler to transform `.k` files into YAML/JSON, then streams that output to `kubectl apply -f -`. Standard **kubectl apply** requires pre-rendered YAML files. The plugin eliminates manual compilation steps while preserving kubectl's familiar interface and flag support.

### Can I use kubectl-kcl without a running Kubernetes cluster?

Yes. The **kubectl kcl validate** command performs offline validation using KCL's built-in type checker and assertion engine. As implemented in the kcl-lang/kcl source code, constraints are evaluated during compilation without requiring API server connectivity, enabling CI/CD pipelines to catch configuration errors early.

### How does parameterization work with kubectl-kcl?

Use the **-D** flag to pass external variables: `kubectl kcl run -D environment=production config.k`. These variables become accessible within your KCL program, enabling environment-specific configurations from a single source file. This is particularly useful for managing differences between development, staging, and production environments.

### Where can I find the kubectl-kcl plugin source code?

The plugin implementation resides in the separate **kcl-lang/kubectl-kcl** repository, which contains the CLI glue code that invokes `kclc` and forwards output to kubectl. The main kcl-lang/kcl repository contains the core compiler and AST definitions (including [`crates/ast/src/ast.rs`](https://github.com/kcl-lang/kcl/blob/main/crates/ast/src/ast.rs)) that power the compilation process.