Skip to content

Conversation

@janisz
Copy link
Collaborator

@janisz janisz commented Oct 28, 2025

This PR adds native support for linting Kustomize manifests. kube-linter can now automatically detect and render Kustomize directories, applying all transformations before running lint checks.

Motivation

Currently, users need to manually render Kustomize manifests before linting:

kustomize build ./my-app | kube-linter lint -

This PR enables direct linting of Kustomize directories:

kube-linter lint ./my-app

Changes

  • Automatic Detection: Detects directories containing kustomization.yaml or kustomization.yml files
  • Native Rendering: Uses k8s-manifests-lib to render Kustomize manifests
  • Context Isolation: Each kustomization is treated as a separate lint context (similar to Helm charts)
  • Full Transformation Support: All Kustomize transformations (patches, overlays, namePrefix, labels, etc.) are applied before linting

Usage Examples

Basic Usage

# Lint a kustomization directory
kube-linter lint ./my-app/

# Lint with custom config
kube-linter lint --config .kube-linter.yaml ./my-app/

Directory Structure Example

my-app/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml
kube-linter lint my-app/

Overlays Example

app/
├── base/
│   ├── kustomization.yaml
│   └── ...
└── overlays/
    ├── dev/
    │   └── kustomization.yaml
    └── prod/
        └── kustomization.yaml
# Lint specific overlay
kube-linter lint app/overlays/prod/

# Lint all overlays
kube-linter lint app/overlays/

# Lint base
kube-linter lint app/base/

Example Output

$ kube-linter lint tests/testdata/mykustomize/

KubeLinter development

tests/testdata/mykustomize/deployment-kustomize-test-deployment.yaml: (object: <no namespace>/kustomize-test-deployment apps/v1, Kind=Deployment) container "test-container" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in the container securityContext.)

tests/testdata/mykustomize/deployment-kustomize-test-deployment.yaml: (object: <no namespace>/kustomize-test-deployment apps/v1, Kind=Deployment) container "test-container" is not set to runAsNonRoot (check: run-as-non-root, remediation: Set runAsUser to a non-zero number and runAsNonRoot to true in your pod or container securityContext.)

Error: found 4 lint errors

Note: The deployment name kustomize-test-deployment includes the kustomize- namePrefix from kustomization.yaml.

CI/CD Integration

# GitHub Actions
kube-linter lint k8s/overlays/production/

# GitLab CI
kube-linter lint --format sarif k8s/base/ > kube-linter.sarif

# Jenkins
kube-linter lint --format json k8s/ > lint-results.json

With Ignore Paths

# Ignore test kustomizations
kube-linter lint --ignore-paths "test/**" ./k8s/

Implementation Details

  • Detection: Checks for kustomization.yaml or kustomization.yml in directories during traversal
  • Rendering: Uses github.com/lburgazzoli/k8s-manifests-lib v0.1.1 for Kustomize rendering
  • Error Handling: Invalid kustomizations are added to InvalidObjects (non-fatal, similar to Helm charts)
  • Ignore Paths: Standard --ignore-paths flag works with Kustomize directories

Testing

# Run unit tests
go test ./pkg/lintcontext -run TestKustomize -v

# Run e2e tests
KUBE_LINTER_BIN=./kube-linter ./e2etests/bats-tests.sh -f "kustomize-support"

# Build and test manually
go build -o kube-linter ./cmd/kube-linter
./kube-linter lint tests/testdata/mykustomize/

Breaking Changes

None. This is a purely additive feature.

Checklist

  • Added unit tests
  • Added e2e tests
  • Tested manually
  • All tests pass

Integrate k8s-manifests-lib to enable linting of Kustomize manifests.
Kustomization directories are automatically detected and rendered,
with each kustomization treated as a separate lint context similar
to Helm charts.

Changes:
- Add isKustomizeDir() detection for kustomization.yaml/yml files
- Add loadObjectsFromKustomize() to render manifests using k8s-manifests-lib
- Add unit tests for Kustomize support
- Add e2e BATS test for Kustomize rendering and linting
- Add test fixtures in tests/testdata/mykustomize/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@janisz janisz requested a review from rhybrillou as a code owner October 28, 2025 14:23
Enable source annotations in the Kustomize renderer to track the actual
source files where Kubernetes objects are defined. This improves error
reporting by showing the real file paths instead of synthetic paths.

Before:
  tests/testdata/mykustomize/deployment-kustomize-test-deployment.yaml

After:
  /path/to/tests/testdata/mykustomize/base/deployment.yaml

This makes it easier for users to find and fix lint errors in their
Kustomize configurations.

Addresses PR review comment:
#1045 (comment)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@janisz janisz requested a review from lburgazzoli October 29, 2025 17:09
Signed-off-by: Tomasz Janiszewski <[email protected]>
@janisz janisz marked this pull request as draft October 30, 2025 12:12
Signed-off-by: Tomasz Janiszewski <[email protected]>
@lburgazzoli
Copy link

@janisz I've tried to run it vs opedatahub-operator:

If I run it vs the config/crd folder, then it works:

➜  go run golang.stackrox.io/kube-linter/cmd/kube-linter@kustomize lint --config .kube-linter.yaml config/crd 
KubeLinter development

No lint errors found!

However it does not for config/manifests:

➜ go run golang.stackrox.io/kube-linter/cmd/kube-linter@kustomize lint --config .kube-linter.yaml config/manifests 
Warning: no valid objects found.

This is likely because for this to work, kustomize must be set using some additional configuration options, int his case to disable load restrinctions (not a good practice, but for this project it is required). The engine has an option to configure it : WithLoadRestrictions(LoadRestrictionsNone) however I wonder how we can make this configurable

@janisz
Copy link
Collaborator Author

janisz commented Oct 31, 2025

For this issue I have a separated pr

@lburgazzoli
Copy link

I think the only missing part is to figure out how to pass some specific kustomize flags, but otherwhise to LGTM

Note: update to github.com/lburgazzoli/k8s-manifests-lib v0.1.3 if you have time as it includes a fix that could prevent the engine to work in some cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants