From eeee75e1d02d2148972e3862ac8bc59c3a08daca Mon Sep 17 00:00:00 2001 From: ogormans-deptstack Date: Sat, 27 Sep 2025 07:53:48 +0000 Subject: [PATCH 1/5] KEP 34146 --- .../34146-kubectl-explain-example/README.md | 628 ++++++++++++++++++ .../34146-kubectl-explain-example/kep.yaml | 21 + 2 files changed, 649 insertions(+) create mode 100644 keps/sig-cli/34146-kubectl-explain-example/README.md create mode 100644 keps/sig-cli/34146-kubectl-explain-example/kep.yaml diff --git a/keps/sig-cli/34146-kubectl-explain-example/README.md b/keps/sig-cli/34146-kubectl-explain-example/README.md new file mode 100644 index 000000000000..df8c0f93c313 --- /dev/null +++ b/keps/sig-cli/34146-kubectl-explain-example/README.md @@ -0,0 +1,628 @@ + +# KEP-34146: kubectl example - kubectl explain example: practical output that can be applied | trialed by new user to advanced + + + + + + +- [Release Signoff Checklist](#release-signoff-checklist) +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) + - [Basic Usage](#basic-usage) + - [Risks and Mitigations](#risks-and-mitigations) +- [Design Details](#design-details) + - [Test Plan](#test-plan) + - [Prerequisite testing updates](#prerequisite-testing-updates) + - [Unit tests](#unit-tests) + - [Integration tests](#integration-tests) + - [e2e tests](#e2e-tests) + - [Graduation Criteria](#graduation-criteria) + - [Alpha](#alpha) + - [Beta](#beta) + - [GA](#ga) + - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) + - [Version Skew Strategy](#version-skew-strategy) +- [Production Readiness Review Questionnaire](#production-readiness-review-questionnaire) + - [Feature Enablement and Rollback](#feature-enablement-and-rollback) + - [Rollout, Upgrade and Rollback Planning](#rollout-upgrade-and-rollback-planning) + - [Monitoring Requirements](#monitoring-requirements) + - [Dependencies](#dependencies) + - [Scalability](#scalability) + - [Troubleshooting](#troubleshooting) +- [Implementation History](#implementation-history) +- [Drawbacks](#drawbacks) +- [Alternatives](#alternatives) +- [Future Work](#future-work) + + +## Release Signoff Checklist + + + +Items marked with (R) are required *prior to targeting to a milestone / release*. + +- [ ] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR) +- [ ] (R) KEP approvers have approved the KEP status as `implementable` +- [ ] (R) Design details are appropriately documented +- [ ] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors) + - [ ] e2e Tests for all Beta API Operations (endpoints) + - [ ] (R) Ensure GA e2e tests meet requirements for [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) + - [ ] (R) Minimum Two Week Window for GA e2e tests to prove flake free +- [ ] (R) Graduation criteria is in place + - [ ] (R) [all GA Endpoints](https://github.com/kubernetes/community/pull/1806) must be hit by [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) +- [ ] (R) Production readiness review completed +- [ ] (R) Production readiness review approved +- [ ] "Implementation History" section is up-to-date for milestone +- [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io] +- [ ] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes + + + +[kubernetes.io]: https://kubernetes.io/ +[kubernetes/enhancements]: https://git.k8s.io/enhancements +[kubernetes/kubernetes]: https://git.k8s.io/kubernetes +[kubernetes/website]: https://git.k8s.io/website + +## Summary + +This KEP proposes adding a new kubectl subcommand `kubectl example` that provides generic seed YAML for different resources, complementing the existing `kubectl explain` command. Think of it as `curl cht.sh/kubectl` but distributed at the CLI level. + +The idea is to provide a `kubectl explain` then `kubectl example` flow, where users can get detailed explanations and then practical YAML examples. + +## Motivation + +Users often need practical, applicable YAML examples for Kubernetes resources. While `kubectl explain` provides detailed schema information, it doesn't give users ready-to-use YAML snippets. This creates a gap where users must manually construct YAML from documentation, which can be error-prone and time-consuming, especially for beginners. + +This KEP addresses that gap by introducing `kubectl example`, which outputs generic seed YAML for resources. The examples are designed to be: + +- **Immediately applicable**: Can be piped directly to `kubectl apply` for testing. +- **Best-practice oriented**: Include common configurations like resource limits, labels, and annotations. +- **Educational**: Serve as templates that users can modify for their needs. +- **Comprehensive**: Cover a wide range of Kubernetes resources. + +For instance: + +- `kubectl explain pod` -- detailed explanation of resource + +- `kubectl example pod` -- generic YAML output for a standard pod with linux - alpine image + +This enhances the user experience, especially for new users learning Kubernetes, by providing immediate practical output that can be applied or trialed. + +Additionally, this could socialize further the use of `kubectl get --raw` on APIs and potentially automate ingestion of that to explain what the API controls in flight within a cluster at a version. + +### Goals + +1. Provide a new `kubectl example` subcommand that outputs generic seed YAML for Kubernetes resources. +2. Complement `kubectl explain` by offering practical, applicable examples. +3. Support common resources with sensible defaults. +4. Potentially integrate with `kubectl get --raw` to enhance API understanding. + +### Non-Goals + +1. Replace or modify `kubectl explain`. +2. Provide exhaustive examples for all possible configurations. +3. Generate examples dynamically from cluster state. + + +## Proposal + +### Basic Usage + +The following user experience should be possible with `kubectl example`: + +```shell +kubectl example pod +``` + +This would output a generic YAML for a Pod resource, e.g.: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: example-pod +spec: + containers: + - name: example-container + image: alpine:latest + command: ["sleep", "3600"] + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" +``` + +For a PersistentVolumeClaim: + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: example-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +``` + +Similarly for other resources like deployments, services, etc. + +### Advanced Usage + +- `kubectl example deployment --replicas=3` - Generate example with custom parameters +- `kubectl example --list` - List all available example resources +- `kubectl example pod | kubectl apply -f -` - Apply the example directly + +### Risks and Mitigations + +#### No Examples Available for a Resource + +##### Risk + +The requested resource does not have a predefined example. + +##### Mitigation + +Return an error message suggesting to use `kubectl explain` for schema information or check available examples with `kubectl example --list`. + +#### Outdated Examples + +##### Risk + +Examples may not reflect the latest best practices or API changes. + +##### Mitigation + +Examples will be maintained as part of kubectl releases, with community contributions encouraged. Version-specific examples can be added if needed. + + +## Design Details + +The new `kubectl example` command will be implemented as a new subcommand in kubectl, similar to `kubectl explain`. + +High-level Approach: + +1. User types `kubectl example ` +2. kubectl resolves the resource type using discovery (similar to `kubectl explain`) +3. kubectl looks up a predefined YAML template for that resource +4. kubectl outputs the YAML to stdout + +Templates will be hardcoded in the kubectl binary for common resources like pods, deployments, services, etc. Examples should use sensible defaults, such as alpine images for containers. + +For extensibility, future versions could allow loading examples from files or online repositories, but initially, examples will be built-in. + +### Example Storage and Management + +Examples will be stored as Go string literals or embedded files in the kubectl codebase. Each example will include: + +- Valid YAML structure +- Sensible default values +- Comments explaining key sections +- Resource limits and requests where applicable +- Common labels and annotations + +### Adding New Examples + +To add a new example: + +1. Create the YAML template +2. Add it to the examples map in the code +3. Update tests +4. Update documentation + +### Parameterization + +Future enhancements could support basic parameterization, such as custom names, replica counts, or image versions, using Go templates or simple string replacement. + +### Test Plan + +##### Prerequisite testing updates + +None required. + +##### Unit tests + +Unit tests will verify that the correct YAML is output for supported resources and appropriate errors for unsupported ones. + +##### Integration tests + +Integration tests will ensure the command integrates well with kubectl's existing infrastructure, such as resource discovery. + +##### e2e tests + +E2E tests will validate that the output YAML can be applied to a cluster (e.g., `kubectl example pod | kubectl apply -f -` creates a running pod). + +### Graduation Criteria + +#### Alpha + +- Basic `kubectl example` command implemented with examples for core resources (pod, deployment, service). +- Unit and integration tests in place. + +#### Beta + +- Expanded set of examples for more resources. +- User feedback incorporated. +- E2E tests passing. + +#### GA + +- Comprehensive examples for commonly used resources. +- Documentation updated. +- No breaking changes. + +### Upgrade / Downgrade Strategy + +N/A - This is a new command, no upgrades needed. + +### Version Skew Strategy + +The command relies on kubectl's resource discovery, which should work across versions. Examples are static, so no skew issues. + +### Test Plan + + + +[x] I/we understand the owners of the involved components may require updates to +existing tests to make this code solid enough prior to committing the changes necessary +to implement this enhancement. + +##### Prerequisite testing updates + + + +##### Unit tests + +Unit tests will verify that the correct YAML is output for supported resources, appropriate errors for unsupported ones, and that the YAML is valid. + +##### Integration tests + +Integration tests will ensure the command integrates well with kubectl's existing infrastructure, such as resource discovery, and that examples are consistent with cluster capabilities. + +##### e2e tests + +E2E tests will validate that the output YAML can be applied to a cluster successfully (e.g., `kubectl example pod | kubectl apply -f -` creates a running pod), and that examples work across different cluster configurations. + +### Graduation Criteria + +#### Alpha + +- Basic `kubectl example` command implemented with examples for core resources (pod, deployment, service, persistentvolumeclaim). +- Unit and integration tests in place. +- Command available in kubectl builds. + +#### Beta + +- Expanded set of examples for more resources (configmap, secret, job, etc.). +- User feedback incorporated from alpha usage. +- E2E tests passing in CI. +- Documentation updated with examples. + +#### GA + +- Comprehensive examples for commonly used resources. +- Examples validated against multiple Kubernetes versions. +- No breaking changes in output format. +- Feature promoted as stable in kubectl documentation. + + + +### Upgrade / Downgrade Strategy + + + +N/A + +### Version Skew Strategy + +The command relies on kubectl's resource discovery, which should work across versions. Examples are static YAML templates, so no version skew issues with the output itself. However, the applicability of examples may vary based on cluster capabilities (e.g., newer API versions). The command will use the latest available API versions for resource discovery. + +## Production Readiness Review Questionnaire + + + +### Feature Enablement and Rollback + +###### How can this feature be enabled / disabled in a live cluster? + +- [x] Other + - Describe the mechanism: This is a new kubectl subcommand. It is enabled by building kubectl with the new code. No feature gate. + - Will enabling / disabling the feature require downtime of the control plane? No + - Will enabling / disabling the feature require downtime or reprovisioning of a node? No + +###### Does enabling the feature change any default behavior? + +No, it's a new command. + +###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)? + +Yes, by using an older version of kubectl without the command. + +###### What happens if we reenable the feature if it was previously rolled back? + +Normal operation. + +###### Are there any tests for feature enablement/disablement? + +Unit tests for the command presence. + + +### Rollout, Upgrade and Rollback Planning + +###### How can a rollout or rollback fail? Can it impact already running workloads? + +No, this is a new CLI command. No impact on workloads. + +###### What specific metrics should inform a rollback? + +N/A + +###### Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested? + +N/A + +###### Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.? + +No. + +### Monitoring Requirements + +###### How can an operator determine if the feature is in use by workloads? + +N/A + +###### How can someone using this feature know that it is working for their instance? + +Run `kubectl example pod` and verify YAML output. + +###### What are the reasonable SLOs (Service Level Objectives) for the enhancement? + +N/A + +###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service? + +- [x] Other (treat as last resort) + - Details: N/A + +###### Are there any missing metrics that would be useful to have to improve observability of this feature? + +N/A + +### Dependencies + +None + +### Scalability + +###### Will enabling / using this feature result in any new API calls? + +Potentially, also happy to make it a subcommand of explain if that's logically neater: +``` +kubectl explain example pod +``` + +###### Will enabling / using this feature result in introducing new API types? + +No. + +###### Will enabling / using this feature result in any new calls to the cloud provider? + +No. + +###### Will enabling / using this feature result in increasing size or count of the existing API objects? + +No. + +###### Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs? + +No. + +###### Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, ...) in any components? + +No. + +###### Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)? + +No. + +### Troubleshooting + +###### How does this feature react if the API server and/or etcd is unavailable? + +The command doesn't require API server access, as examples are static. diff --git a/keps/sig-cli/34146-kubectl-explain-example/kep.yaml b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml new file mode 100644 index 000000000000..d5bb3b5dd3e6 --- /dev/null +++ b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml @@ -0,0 +1,21 @@ +id: "34146" +name: kubectl-example +title: kubectl example - kubectl explain but immediate practical output that can be applied | trialed by new user to advanced +kep-number: 34146 +authors: ['@ogormans-deptstack'] +owning-sig: sig-cli +participating-sigs: [sig-cli] +reviewers: [] +approvers: [] +creation-date: "2025-09-27" +last-updated: "2025-09-27" +status: provisional +stage: alpha +latest-milestone: "v1.35" +milestone: + alpha: "v1.35" + beta: "v1.36" + stable: "v1.37" +feature-gates: [] +disable-supported: false +metrics: [] \ No newline at end of file From a04523192a4dece806b167498122f4c021d19e0d Mon Sep 17 00:00:00 2001 From: ogormans-deptstack Date: Fri, 10 Oct 2025 20:57:32 +0000 Subject: [PATCH 2/5] fix: milestone was too aggressive --- keps/sig-cli/34146-kubectl-explain-example/kep.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keps/sig-cli/34146-kubectl-explain-example/kep.yaml b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml index d5bb3b5dd3e6..b237145eea85 100644 --- a/keps/sig-cli/34146-kubectl-explain-example/kep.yaml +++ b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml @@ -11,11 +11,11 @@ creation-date: "2025-09-27" last-updated: "2025-09-27" status: provisional stage: alpha -latest-milestone: "v1.35" +latest-milestone: "v1.36" milestone: - alpha: "v1.35" - beta: "v1.36" - stable: "v1.37" + alpha: "v1.36" + beta: "v1.37" + stable: "v1.38" feature-gates: [] disable-supported: false metrics: [] \ No newline at end of file From 9096c2b8d31d0106eedb5feb040a25334b8b5355 Mon Sep 17 00:00:00 2001 From: ogormans-deptstack Date: Tue, 17 Mar 2026 15:57:54 +0000 Subject: [PATCH 3/5] docs: update KEP design details to reflect struct-based generation - Replace template-based design with struct-based architecture using typed K8s API objects (corev1, appsv1, metav1) and sigs.k8s.io/yaml - Document buildersByKind registry, builder functions, and alias support - Add builder defaults table (images, resource limits, ports) - Update API calls answer: no server contact needed - Add Implementation History, Drawbacks, Alternatives, Future Work sections Signed-off-by: Sean O'Gorman --- .../34146-kubectl-explain-example/README.md | 110 +++++++++++++----- 1 file changed, 83 insertions(+), 27 deletions(-) diff --git a/keps/sig-cli/34146-kubectl-explain-example/README.md b/keps/sig-cli/34146-kubectl-explain-example/README.md index df8c0f93c313..10d4dc65b9d9 100644 --- a/keps/sig-cli/34146-kubectl-explain-example/README.md +++ b/keps/sig-cli/34146-kubectl-explain-example/README.md @@ -272,41 +272,70 @@ Examples will be maintained as part of kubectl releases, with community contribu ## Design Details -The new `kubectl example` command will be implemented as a new subcommand in kubectl, similar to `kubectl explain`. +The new `kubectl example` command is implemented as a new subcommand in kubectl, similar to `kubectl explain`. -High-level Approach: +### Architecture: Struct-Based Generation -1. User types `kubectl example ` -2. kubectl resolves the resource type using discovery (similar to `kubectl explain`) -3. kubectl looks up a predefined YAML template for that resource -4. kubectl outputs the YAML to stdout +Examples are generated using **typed Go structs** from the Kubernetes API, not embedded YAML templates. Each resource kind has a dedicated builder function that constructs a fully-typed API object and marshals it to YAML via `sigs.k8s.io/yaml`. -Templates will be hardcoded in the kubectl binary for common resources like pods, deployments, services, etc. Examples should use sensible defaults, such as alpine images for containers. +High-level flow: -For extensibility, future versions could allow loading examples from files or online repositories, but initially, examples will be built-in. +1. User types `kubectl example ` (with optional `--name`, `--image`, `--replicas` flags) +2. kubectl resolves the resource kind, including aliases (e.g., `po` → `pod`, `deploy` → `deployment`) +3. kubectl looks up the builder function in a `buildersByKind` registry +4. The builder constructs a typed Go struct (e.g., `corev1.Pod`, `appsv1.Deployment`) with the user's flag values applied +5. `sigs.k8s.io/yaml` marshals the struct to YAML +6. kubectl outputs the YAML to stdout -### Example Storage and Management +This approach provides: -Examples will be stored as Go string literals or embedded files in the kubectl codebase. Each example will include: +- **Type safety**: Builders use `corev1`, `appsv1`, and `metav1` API types, so invalid field names or structures are caught at compile time +- **Determinism**: Same inputs always produce identical YAML output — there is no template rendering, string interpolation, or conditional logic +- **Parameterization**: `--name`, `--image`, and `--replicas` flags modify the struct fields before marshaling, providing real customization rather than no-op flags +- **API consistency**: Output automatically follows Kubernetes API field ordering conventions since it is marshaled from the canonical Go types -- Valid YAML structure -- Sensible default values -- Comments explaining key sections -- Resource limits and requests where applicable -- Common labels and annotations +### Builder Registry + +The `buildersByKind` map routes resource kind strings (and their aliases) to builder functions: + +```go +buildersByKind map[string]func(name, image string, replicas int) ([]byte, error) +``` + +Supported resources and aliases: + +| Kind | Aliases | Builder | API Types Used | +|------|---------|---------|----------------| +| pod | pods, po | `buildPod` | `corev1.Pod` | +| deployment | deployments, deploy | `buildDeployment` | `appsv1.Deployment` | +| service | services, svc | `buildService` | `corev1.Service` | +| persistentvolumeclaim | persistentvolumeclaims, pvc | `buildPVC` | `corev1.PersistentVolumeClaim` | +| secret | secrets | `buildSecret` | `corev1.Secret` | +| customresourcedefinition | customresourcedefinitions, crd | `buildCRD` | `map[string]interface{}` (unstructured) | + +Note: CRD uses an unstructured map because `k8s.io/apiextensions-apiserver` is not in kubectl's `go.mod`. All other resources use their canonical typed API objects. ### Adding New Examples -To add a new example: +To add a new resource example: -1. Create the YAML template -2. Add it to the examples map in the code -3. Update tests -4. Update documentation +1. Create a builder function in `resources.go` that returns the typed API object +2. Register the kind and its aliases in the `buildersByKind` map in `example.go` +3. Add unit tests that unmarshal the output back into the typed object and assert field values +4. Update `--list` output (automatic from `buildersByKind` keys) -### Parameterization +### Default Values -Future enhancements could support basic parameterization, such as custom names, replica counts, or image versions, using Go templates or simple string replacement. +Each builder applies sensible defaults: + +- **Pod**: `alpine:latest` image, `sleep 3600` command, resource requests (250m CPU, 64Mi memory) and limits (500m CPU, 128Mi memory) +- **Deployment**: `nginx:stable` image, 1 replica, port 80 +- **Service**: ClusterIP type, port 80→80 +- **PVC**: ReadWriteOnce, 1Gi storage +- **Secret**: Opaque type with placeholder `stringData` +- **CRD**: Complete apiextensions/v1 structure with OpenAPI validation schema + +All resources include `app.kubernetes.io/name` labels following Kubernetes recommended labels convention. ### Test Plan @@ -592,10 +621,7 @@ None ###### Will enabling / using this feature result in any new API calls? -Potentially, also happy to make it a subcommand of explain if that's logically neater: -``` -kubectl explain example pod -``` +No. Examples are generated entirely from in-binary Go struct builders. No API server contact is needed. If a kubeconfig is available, the command may optionally attempt discovery-based kind resolution, but falls back to a local alias map if the API server is unreachable. ###### Will enabling / using this feature result in introducing new API types? @@ -625,4 +651,34 @@ No. ###### How does this feature react if the API server and/or etcd is unavailable? -The command doesn't require API server access, as examples are static. +The command doesn't require API server access, as examples are generated from in-binary struct builders. + +## Implementation History + +- **2024-12**: Initial KEP draft and PR opened (kubernetes/enhancements#5576) +- **2024-12**: Initial implementation PR opened with embedded YAML templates (kubernetes/kubernetes#134529) +- **2026-03**: Rearchitected from YAML templates to struct-based generation using typed K8s API objects (`corev1`, `appsv1`, `metav1`) with `sigs.k8s.io/yaml` marshaling. Added working `--name`, `--image`, `--replicas` flags. Rewrote tests with structured assertions. + +## Drawbacks + +- Adds a new top-level kubectl subcommand, increasing the command surface area. +- Examples are static and may not cover every user's specific use case. +- Struct-based builders require Go code changes to add new resources (vs. dropping in a YAML file), though this is offset by compile-time type safety. + +## Alternatives + +1. **Embedded YAML templates**: The original approach used `//go:embed` with `.yaml` files. This was simpler but produced static output with no real parameterization, no type safety, and risked template drift from the actual API types. + +2. **Dynamic generation from OpenAPI schema**: Generate examples by walking the cluster's OpenAPI spec. More flexible but requires API server access, produces verbose output, and cannot provide sensible default values without heuristics. + +3. **External example repository**: Host examples in a separate repo and fetch them at runtime. Avoids binary size growth but introduces a network dependency and versioning complexity. + +4. **Subcommand of explain**: `kubectl explain --example pod` instead of `kubectl example pod`. Considered but rejected to keep the UX simple and the commands orthogonal. + +## Future Work + +- Expand resource coverage: ConfigMap, Job, CronJob, Ingress, NetworkPolicy, StatefulSet, DaemonSet +- Support `--output=json` flag for JSON output (trivial with struct-based approach) +- Community-contributed examples via a plugin mechanism +- Integration with `kubectl explain` to show examples inline with field documentation +- Version-aware examples that adapt to the target cluster's API capabilities From 7075d5f208a592dd8bdb5c06a57ae2e0017bb915 Mon Sep 17 00:00:00 2001 From: ogormans-deptstack Date: Tue, 17 Mar 2026 16:40:03 +0000 Subject: [PATCH 4/5] KEP-34146: rewrite with precedent analysis, release timing, plugin rationale Major KEP rewrite for sig-cli/sig-kep review readiness: - Remove all template HTML comments and duplicate sections - Add Precedent Analysis: kubectl debug/diff/events/wait history, KEP-2380 failure analysis - Add 'Why Not a Plugin?' section with discovery/distribution/CI arguments - Add Release Timing Strategy targeting v1.37 alpha - Update Builder Registry from 6 to 11 resources (ConfigMap, Job, CronJob, Ingress, NetworkPolicy) - Update Default Values table, Implementation History, Future Work - Clean Graduation Criteria with concrete alpha/beta/GA milestones - Update kep.yaml milestones to v1.37/v1.38/v1.39 --- .../34146-kubectl-explain-example/README.md | 571 +++++++----------- .../34146-kubectl-explain-example/kep.yaml | 10 +- 2 files changed, 208 insertions(+), 373 deletions(-) diff --git a/keps/sig-cli/34146-kubectl-explain-example/README.md b/keps/sig-cli/34146-kubectl-explain-example/README.md index 10d4dc65b9d9..d14416b0af66 100644 --- a/keps/sig-cli/34146-kubectl-explain-example/README.md +++ b/keps/sig-cli/34146-kubectl-explain-example/README.md @@ -1,80 +1,4 @@ - -# KEP-34146: kubectl example - kubectl explain example: practical output that can be applied | trialed by new user to advanced - - - - +# KEP-34146: kubectl example - [Release Signoff Checklist](#release-signoff-checklist) @@ -82,10 +6,20 @@ tags, and then generate with `hack/update-toc.sh`. - [Motivation](#motivation) - [Goals](#goals) - [Non-Goals](#non-goals) +- [Precedent Analysis](#precedent-analysis) + - [Successful kubectl UX Additions](#successful-kubectl-ux-additions) + - [Failed Precedent: KEP-2380 Data-Driven Commands](#failed-precedent-kep-2380-data-driven-commands) + - [Key Takeaway](#key-takeaway) +- [Why Not a Plugin?](#why-not-a-plugin) - [Proposal](#proposal) - [Basic Usage](#basic-usage) + - [Advanced Usage](#advanced-usage) - [Risks and Mitigations](#risks-and-mitigations) - [Design Details](#design-details) + - [Architecture: Struct-Based Generation](#architecture-struct-based-generation) + - [Builder Registry](#builder-registry) + - [Adding New Examples](#adding-new-examples) + - [Default Values](#default-values) - [Test Plan](#test-plan) - [Prerequisite testing updates](#prerequisite-testing-updates) - [Unit tests](#unit-tests) @@ -105,6 +39,7 @@ tags, and then generate with `hack/update-toc.sh`. - [Scalability](#scalability) - [Troubleshooting](#troubleshooting) - [Implementation History](#implementation-history) +- [Release Timing Strategy](#release-timing-strategy) - [Drawbacks](#drawbacks) - [Alternatives](#alternatives) - [Future Work](#future-work) @@ -112,20 +47,6 @@ tags, and then generate with `hack/update-toc.sh`. ## Release Signoff Checklist - - Items marked with (R) are required *prior to targeting to a milestone / release*. - [ ] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR) @@ -133,20 +54,16 @@ Items marked with (R) are required *prior to targeting to a milestone / release* - [ ] (R) Design details are appropriately documented - [ ] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors) - [ ] e2e Tests for all Beta API Operations (endpoints) - - [ ] (R) Ensure GA e2e tests meet requirements for [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) + - [ ] (R) Ensure GA e2e tests meet requirements for [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) - [ ] (R) Minimum Two Week Window for GA e2e tests to prove flake free - [ ] (R) Graduation criteria is in place - - [ ] (R) [all GA Endpoints](https://github.com/kubernetes/community/pull/1806) must be hit by [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) + - [ ] (R) [all GA Endpoints](https://github.com/kubernetes/community/pull/1806) must be hit by [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md) - [ ] (R) Production readiness review completed - [ ] (R) Production readiness review approved - [ ] "Implementation History" section is up-to-date for milestone - [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io] - [ ] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes - - [kubernetes.io]: https://kubernetes.io/ [kubernetes/enhancements]: https://git.k8s.io/enhancements [kubernetes/kubernetes]: https://git.k8s.io/kubernetes @@ -154,62 +71,106 @@ Items marked with (R) are required *prior to targeting to a milestone / release* ## Summary -This KEP proposes adding a new kubectl subcommand `kubectl example` that provides generic seed YAML for different resources, complementing the existing `kubectl explain` command. Think of it as `curl cht.sh/kubectl` but distributed at the CLI level. +This KEP proposes adding a new kubectl subcommand `kubectl example` that generates production-ready seed YAML for Kubernetes resources using typed Go structs. It complements `kubectl explain` by providing practical, immediately applicable manifests rather than schema documentation. -The idea is to provide a `kubectl explain` then `kubectl example` flow, where users can get detailed explanations and then practical YAML examples. +The workflow is: `kubectl explain pod` (understand the schema) → `kubectl example pod` (get a working manifest) → `kubectl apply -f -` (try it). ## Motivation Users often need practical, applicable YAML examples for Kubernetes resources. While `kubectl explain` provides detailed schema information, it doesn't give users ready-to-use YAML snippets. This creates a gap where users must manually construct YAML from documentation, which can be error-prone and time-consuming, especially for beginners. -This KEP addresses that gap by introducing `kubectl example`, which outputs generic seed YAML for resources. The examples are designed to be: +This KEP addresses that gap by introducing `kubectl example`, which outputs seed YAML for resources. The examples are designed to be: -- **Immediately applicable**: Can be piped directly to `kubectl apply` for testing. -- **Best-practice oriented**: Include common configurations like resource limits, labels, and annotations. -- **Educational**: Serve as templates that users can modify for their needs. -- **Comprehensive**: Cover a wide range of Kubernetes resources. +- **Immediately applicable**: Can be piped directly to `kubectl apply` for testing +- **Best-practice oriented**: Include resource limits, recommended labels, and common configurations +- **Educational**: Serve as starting points that users can modify for their needs +- **Offline-capable**: Generated entirely from in-binary Go structs with no API server dependency For instance: -- `kubectl explain pod` -- detailed explanation of resource - -- `kubectl example pod` -- generic YAML output for a standard pod with linux - alpine image +```shell +# Understand the schema +kubectl explain pod -This enhances the user experience, especially for new users learning Kubernetes, by providing immediate practical output that can be applied or trialed. +# Get a working manifest +kubectl example pod -Additionally, this could socialize further the use of `kubectl get --raw` on APIs and potentially automate ingestion of that to explain what the API controls in flight within a cluster at a version. +# Try it immediately +kubectl example pod | kubectl apply -f - +``` ### Goals -1. Provide a new `kubectl example` subcommand that outputs generic seed YAML for Kubernetes resources. -2. Complement `kubectl explain` by offering practical, applicable examples. -3. Support common resources with sensible defaults. -4. Potentially integrate with `kubectl get --raw` to enhance API understanding. +1. Provide a new `kubectl example` subcommand that outputs seed YAML for Kubernetes resources +2. Complement `kubectl explain` by offering practical, applicable examples +3. Support common resources with sensible defaults and customization flags (`--name`, `--image`, `--replicas`) +4. Work fully offline using struct-based generation (no API server required) ### Non-Goals -1. Replace or modify `kubectl explain`. -2. Provide exhaustive examples for all possible configurations. -3. Generate examples dynamically from cluster state. +1. Replace or modify `kubectl explain` +2. Provide exhaustive examples for all possible configurations +3. Generate examples dynamically from cluster state +4. Cover every Kubernetes resource kind — focus on the most commonly used resources + +## Precedent Analysis + +Several kubectl UX commands have successfully navigated the KEP process. Their history provides a roadmap for `kubectl example`. + +### Successful kubectl UX Additions +| Command | KEP | Time to Alpha | Key Factor | +|---------|-----|---------------|------------| +| `kubectl debug` | [KEP-1441](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/1441-kubectl-debug) | ~8 months | Clear user pain point (debugging pods), sig-cli sponsor early | +| `kubectl diff` | [KEP-491](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/491-kubectl-diff) | ~2 months | Small, focused scope — one command, one purpose | +| `kubectl events` | [KEP-1440](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/1440-kubectl-events) | ~2 years | Broader scope, required more iteration on API surface | +| `kubectl wait` | N/A (pre-KEP) | Graduated alpha→beta→GA | Utility command, no feature gate needed | + +**Common success factors**: (1) clear user pain point, (2) small surface area, (3) client-only with no server changes, (4) early sig-cli sponsor engagement. + +`kubectl example` shares all four factors — it is a single read-only command that generates YAML locally. + +### Failed Precedent: KEP-2380 Data-Driven Commands + +[KEP-2380](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2380-scalable-kubectl-commands) attempted to solve a related problem — making kubectl commands data-driven so they could adapt to new resource types. It was ultimately abandoned because it **required server-side metadata changes** (adding command hints to CRD schemas), which created cross-SIG coordination challenges and coupling between client and server. + +### Key Takeaway + +`kubectl example` succeeds where KEP-2380 failed by being **entirely client-side**. No new API types, no server-side metadata, no CRD schema changes. Builders are compiled into the kubectl binary and work offline. This eliminates the cross-SIG coordination burden that stalled KEP-2380. + +## Why Not a Plugin? + +A natural question is whether `kubectl example` should be a [kubectl plugin](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/) (e.g., `kubectl-example` distributed via [krew](https://krew.sigs.k8s.io/)) rather than a built-in command. We considered this and believe built-in is the right choice: + +| Concern | Built-in command | Plugin | +|---------|-----------------|--------| +| **Discovery** | Appears in `kubectl --help` and shell completion | Invisible unless user knows to search krew | +| **Distribution** | Available to every kubectl user immediately | Requires separate install step | +| **CI testing** | Tested in Kubernetes CI on every release | Maintained separately, may drift from API types | +| **Educational flow** | `kubectl explain` → `kubectl example` is a natural, discoverable pair | Users must learn about krew, find the plugin, install it | +| **Type safety** | Uses in-tree API types (`corev1`, `appsv1`), compile-time guarantees | Must vendor or copy types, no compile-time guarantees against kubectl's tree | + +Additionally, **`kubectl example` is not a niche tool** — it targets the same audience as `kubectl explain`, which is every kubectl user. The `explain` → `example` flow is most valuable when both commands are first-class and discoverable together. + +**Comparison with `kubectl create`**: `kubectl create` generates minimal imperative manifests for quick resource creation. `kubectl example` generates educational, best-practice manifests designed as starting points for real workloads — including resource limits, recommended labels, and production-oriented defaults. ## Proposal ### Basic Usage -The following user experience should be possible with `kubectl example`: - ```shell kubectl example pod ``` -This would output a generic YAML for a Pod resource, e.g.: +Outputs a complete, valid Pod manifest: ```yaml apiVersion: v1 kind: Pod metadata: name: example-pod + labels: + app.kubernetes.io/name: example-pod spec: containers: - name: example-container @@ -224,56 +185,28 @@ spec: cpu: "500m" ``` -For a PersistentVolumeClaim: - -```yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: example-pvc -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi -``` - -Similarly for other resources like deployments, services, etc. - ### Advanced Usage -- `kubectl example deployment --replicas=3` - Generate example with custom parameters -- `kubectl example --list` - List all available example resources -- `kubectl example pod | kubectl apply -f -` - Apply the example directly +- `kubectl example deployment --replicas=3 --image=myapp:v1` — Generate with custom parameters +- `kubectl example --list` — List all available example resources +- `kubectl example pod --name=my-pod | kubectl apply -f -` — Customize and apply directly ### Risks and Mitigations #### No Examples Available for a Resource -##### Risk - -The requested resource does not have a predefined example. - -##### Mitigation +**Risk**: The requested resource does not have a predefined example. -Return an error message suggesting to use `kubectl explain` for schema information or check available examples with `kubectl example --list`. +**Mitigation**: Return a clear error message suggesting `kubectl explain` for schema information and `kubectl example --list` for available examples. The `--list` flag makes coverage explicit. #### Outdated Examples -##### Risk - -Examples may not reflect the latest best practices or API changes. - -##### Mitigation - -Examples will be maintained as part of kubectl releases, with community contributions encouraged. Version-specific examples can be added if needed. +**Risk**: Examples may not reflect the latest best practices or API changes. +**Mitigation**: Examples are generated from canonical Go API types (`corev1.Pod`, `appsv1.Deployment`, etc.), so they are always structurally correct for the kubectl version. Best-practice defaults (resource limits, labels) are maintained as part of kubectl releases. Struct-based generation ensures output stays in sync with API types at compile time. ## Design Details -The new `kubectl example` command is implemented as a new subcommand in kubectl, similar to `kubectl explain`. - ### Architecture: Struct-Based Generation Examples are generated using **typed Go structs** from the Kubernetes API, not embedded YAML templates. Each resource kind has a dedicated builder function that constructs a fully-typed API object and marshals it to YAML via `sigs.k8s.io/yaml`. @@ -289,9 +222,9 @@ High-level flow: This approach provides: -- **Type safety**: Builders use `corev1`, `appsv1`, and `metav1` API types, so invalid field names or structures are caught at compile time -- **Determinism**: Same inputs always produce identical YAML output — there is no template rendering, string interpolation, or conditional logic -- **Parameterization**: `--name`, `--image`, and `--replicas` flags modify the struct fields before marshaling, providing real customization rather than no-op flags +- **Type safety**: Builders use `corev1`, `appsv1`, `batchv1`, `networkingv1`, and `metav1` API types, so invalid field names or structures are caught at compile time +- **Determinism**: Same inputs always produce identical YAML output — no template rendering, string interpolation, or conditional logic +- **Parameterization**: `--name`, `--image`, and `--replicas` flags modify the struct fields before marshaling, providing real customization - **API consistency**: Output automatically follows Kubernetes API field ordering conventions since it is marshaled from the canonical Go types ### Builder Registry @@ -312,6 +245,11 @@ Supported resources and aliases: | persistentvolumeclaim | persistentvolumeclaims, pvc | `buildPVC` | `corev1.PersistentVolumeClaim` | | secret | secrets | `buildSecret` | `corev1.Secret` | | customresourcedefinition | customresourcedefinitions, crd | `buildCRD` | `map[string]interface{}` (unstructured) | +| configmap | configmaps, cm | `buildConfigMap` | `corev1.ConfigMap` | +| job | jobs | `buildJob` | `batchv1.Job` | +| cronjob | cronjobs | `buildCronJob` | `batchv1.CronJob` | +| ingress | ingresses, ing | `buildIngress` | `networkingv1.Ingress` | +| networkpolicy | networkpolicies, netpol | `buildNetworkPolicy` | `networkingv1.NetworkPolicy` | Note: CRD uses an unstructured map because `k8s.io/apiextensions-apiserver` is not in kubectl's `go.mod`. All other resources use their canonical typed API objects. @@ -321,270 +259,136 @@ To add a new resource example: 1. Create a builder function in `resources.go` that returns the typed API object 2. Register the kind and its aliases in the `buildersByKind` map in `example.go` -3. Add unit tests that unmarshal the output back into the typed object and assert field values -4. Update `--list` output (automatic from `buildersByKind` keys) +3. Add a fallback alias entry in `fallbackResolve()` for offline resolution +4. Add unit tests that unmarshal the output back into the typed object and assert field values +5. Update `--list` output (automatic from `buildersByKind` keys) ### Default Values -Each builder applies sensible defaults: - -- **Pod**: `alpine:latest` image, `sleep 3600` command, resource requests (250m CPU, 64Mi memory) and limits (500m CPU, 128Mi memory) -- **Deployment**: `nginx:stable` image, 1 replica, port 80 -- **Service**: ClusterIP type, port 80→80 -- **PVC**: ReadWriteOnce, 1Gi storage -- **Secret**: Opaque type with placeholder `stringData` -- **CRD**: Complete apiextensions/v1 structure with OpenAPI validation schema +Each builder applies sensible, production-oriented defaults: + +| Resource | Image | Key Defaults | +|----------|-------|-------------| +| **Pod** | `alpine:latest` | `sleep 3600` command, resource requests (250m CPU, 64Mi memory) and limits (500m CPU, 128Mi memory) | +| **Deployment** | `nginx:stable` | 1 replica, port 80, resource limits | +| **Service** | — | ClusterIP type, port 80→80 | +| **PVC** | — | ReadWriteOnce, 1Gi storage | +| **Secret** | — | Opaque type with placeholder `stringData` | +| **CRD** | — | Complete apiextensions/v1 structure with OpenAPI validation schema | +| **ConfigMap** | — | `config.yaml` file key + `LOG_LEVEL` environment variable key | +| **Job** | `perl:5.40` | Pi calculation example, BackoffLimit=4, RestartPolicy=Never | +| **CronJob** | `busybox:1.36` | `*/5 * * * *` schedule, date command | +| **Ingress** | — | nginx rewrite annotation, `example.com` host, PathTypePrefix, port 80 | +| **NetworkPolicy** | — | Frontend→App→Database flow, Ingress+Egress policy types | All resources include `app.kubernetes.io/name` labels following Kubernetes recommended labels convention. ### Test Plan -##### Prerequisite testing updates - -None required. - -##### Unit tests - -Unit tests will verify that the correct YAML is output for supported resources and appropriate errors for unsupported ones. - -##### Integration tests - -Integration tests will ensure the command integrates well with kubectl's existing infrastructure, such as resource discovery. - -##### e2e tests - -E2E tests will validate that the output YAML can be applied to a cluster (e.g., `kubectl example pod | kubectl apply -f -` creates a running pod). - -### Graduation Criteria - -#### Alpha - -- Basic `kubectl example` command implemented with examples for core resources (pod, deployment, service). -- Unit and integration tests in place. - -#### Beta - -- Expanded set of examples for more resources. -- User feedback incorporated. -- E2E tests passing. - -#### GA - -- Comprehensive examples for commonly used resources. -- Documentation updated. -- No breaking changes. - -### Upgrade / Downgrade Strategy - -N/A - This is a new command, no upgrades needed. - -### Version Skew Strategy - -The command relies on kubectl's resource discovery, which should work across versions. Examples are static, so no skew issues. - -### Test Plan - - - [x] I/we understand the owners of the involved components may require updates to existing tests to make this code solid enough prior to committing the changes necessary to implement this enhancement. ##### Prerequisite testing updates - +None required. The command is purely additive with no changes to existing kubectl behavior. ##### Unit tests -Unit tests will verify that the correct YAML is output for supported resources, appropriate errors for unsupported ones, and that the YAML is valid. +- Verify correct YAML output for all 11 supported resources +- Verify `--name`, `--image`, and `--replicas` flag overrides work correctly +- Verify alias resolution for all registered aliases (po, deploy, svc, pvc, crd, cm, ing, netpol) +- Verify error handling for unsupported resource kinds +- Verify `--list` output includes all registered resources +- Tests unmarshal YAML back into typed Go objects and assert specific field values (not string matching) +- **Current coverage**: 15 test functions, all passing ##### Integration tests -Integration tests will ensure the command integrates well with kubectl's existing infrastructure, such as resource discovery, and that examples are consistent with cluster capabilities. +Integration tests will ensure the command integrates well with kubectl's existing infrastructure, including resource discovery when a kubeconfig is available, and that the command falls back gracefully to offline alias resolution when no API server is reachable. ##### e2e tests -E2E tests will validate that the output YAML can be applied to a cluster successfully (e.g., `kubectl example pod | kubectl apply -f -` creates a running pod), and that examples work across different cluster configurations. - -### Graduation Criteria - -#### Alpha - -- Basic `kubectl example` command implemented with examples for core resources (pod, deployment, service, persistentvolumeclaim). -- Unit and integration tests in place. -- Command available in kubectl builds. - -#### Beta - -- Expanded set of examples for more resources (configmap, secret, job, etc.). -- User feedback incorporated from alpha usage. -- E2E tests passing in CI. -- Documentation updated with examples. - -#### GA - -- Comprehensive examples for commonly used resources. -- Examples validated against multiple Kubernetes versions. -- No breaking changes in output format. -- Feature promoted as stable in kubectl documentation. +E2E tests will validate that the output YAML can be applied to a cluster successfully: - +- Comprehensive examples for all commonly used resources +- Examples validated against multiple Kubernetes versions +- No breaking changes in output format +- Feature promoted as stable in kubectl documentation +- At least two releases between beta and GA for feedback collection ### Upgrade / Downgrade Strategy - - -N/A +Not applicable. This is a new, purely additive kubectl subcommand. Upgrading kubectl adds the command; downgrading removes it. No cluster state, configuration, or existing behavior is affected. ### Version Skew Strategy -The command relies on kubectl's resource discovery, which should work across versions. Examples are static YAML templates, so no version skew issues with the output itself. However, the applicability of examples may vary based on cluster capabilities (e.g., newer API versions). The command will use the latest available API versions for resource discovery. +The command generates YAML from in-binary Go struct builders with no API server dependency. The output uses stable API versions (`v1`, `apps/v1`, `batch/v1`, `networking.k8s.io/v1`) that are available across all supported Kubernetes versions. When a kubeconfig is available, the command may optionally attempt discovery-based kind resolution, but falls back to a local alias map if the API server is unreachable. No version skew issues arise because the output is self-contained YAML. ## Production Readiness Review Questionnaire - - ### Feature Enablement and Rollback ###### How can this feature be enabled / disabled in a live cluster? - [x] Other - - Describe the mechanism: This is a new kubectl subcommand. It is enabled by building kubectl with the new code. No feature gate. + - Describe the mechanism: This is a new kubectl subcommand. It is enabled by building kubectl with the new code. No feature gate is required — kubectl CLI commands (like `kubectl debug`, `kubectl diff`, `kubectl events`) graduate through alpha→beta→GA without feature gates. - Will enabling / disabling the feature require downtime of the control plane? No - Will enabling / disabling the feature require downtime or reprovisioning of a node? No ###### Does enabling the feature change any default behavior? -No, it's a new command. +No. It adds a new command; no existing commands or behaviors are modified. ###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)? -Yes, by using an older version of kubectl without the command. +Yes, by using an older version of kubectl that does not include the command. ###### What happens if we reenable the feature if it was previously rolled back? -Normal operation. +Normal operation. The command is stateless. ###### Are there any tests for feature enablement/disablement? -Unit tests for the command presence. - +Unit tests verify the command is registered and functional. Since there is no feature gate, enablement/disablement is controlled by kubectl binary version. ### Rollout, Upgrade and Rollback Planning ###### How can a rollout or rollback fail? Can it impact already running workloads? -No, this is a new CLI command. No impact on workloads. +It cannot. This is a purely additive CLI command that generates YAML to stdout. It does not modify cluster state, running workloads, or any existing kubectl behavior. ###### What specific metrics should inform a rollback? -N/A +Not applicable. The command is a local CLI tool with no server-side component. ###### Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested? -N/A +Not applicable. The command is stateless and has no persistent state to migrate. ###### Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.? @@ -594,28 +398,28 @@ No. ###### How can an operator determine if the feature is in use by workloads? -N/A +Not applicable. This is a local CLI command. ###### How can someone using this feature know that it is working for their instance? -Run `kubectl example pod` and verify YAML output. +Run `kubectl example pod` and verify valid YAML output is printed to stdout. ###### What are the reasonable SLOs (Service Level Objectives) for the enhancement? -N/A +Not applicable. This is a local CLI command with no service component. ###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service? - [x] Other (treat as last resort) - - Details: N/A + - Details: Not applicable — local CLI command. ###### Are there any missing metrics that would be useful to have to improve observability of this feature? -N/A +Not applicable. ### Dependencies -None +None. The command uses only packages already in kubectl's dependency tree: `corev1`, `appsv1`, `batchv1`, `networkingv1`, `metav1`, and `sigs.k8s.io/yaml`. ### Scalability @@ -641,7 +445,7 @@ No. ###### Will enabling / using this feature result in non-negligible increase of resource usage (CPU, RAM, disk, IO, ...) in any components? -No. +No. The struct builders add negligible binary size to kubectl (a few KB of compiled Go code). ###### Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)? @@ -651,34 +455,65 @@ No. ###### How does this feature react if the API server and/or etcd is unavailable? -The command doesn't require API server access, as examples are generated from in-binary struct builders. +The command works fully offline. Examples are generated from in-binary struct builders. Discovery-based kind resolution gracefully falls back to a hardcoded alias map when the API server is unreachable. ## Implementation History -- **2024-12**: Initial KEP draft and PR opened (kubernetes/enhancements#5576) -- **2024-12**: Initial implementation PR opened with embedded YAML templates (kubernetes/kubernetes#134529) -- **2026-03**: Rearchitected from YAML templates to struct-based generation using typed K8s API objects (`corev1`, `appsv1`, `metav1`) with `sigs.k8s.io/yaml` marshaling. Added working `--name`, `--image`, `--replicas` flags. Rewrote tests with structured assertions. +- **2024-12**: Initial KEP draft and PR opened ([kubernetes/enhancements#5576](https://github.com/kubernetes/enhancements/pull/5576)) +- **2024-12**: Initial implementation PR opened with embedded YAML templates ([kubernetes/kubernetes#134529](https://github.com/kubernetes/kubernetes/pull/134529)) +- **2026-03**: Rearchitected from YAML templates to struct-based generation using typed Kubernetes API objects (`corev1`, `appsv1`, `metav1`) with `sigs.k8s.io/yaml` marshaling. Added working `--name`, `--image`, `--replicas` flags. Rewrote tests with structured assertions (15 test functions). +- **2026-03**: Expanded resource coverage from 6 to 11 builders: added ConfigMap (`corev1`), Job (`batchv1`), CronJob (`batchv1`), Ingress (`networkingv1`), NetworkPolicy (`networkingv1`). Updated KEP with precedent analysis, release timing strategy, and plugin rationale. + +## Release Timing Strategy + +### Target: v1.37 Alpha + +The v1.36 Enhancements Freeze has already passed, so the earliest realistic target is **v1.37** (estimated July–October 2026). + +### Action Items + +1. **Attend sig-cli biweekly meeting** (Wednesdays 09:00 PT) to present the KEP and request a sponsor +2. **Request KEP review** from sig-cli tech leads and chairs: + - Chairs: @ardaguclu, @mpuckett159 + - Tech Leads: @eddiezane, @soltysh + - Primary sponsor target: @soltysh (extensive kubectl experience, tech lead) +3. **Post to sig-cli mailing list** with KEP summary before meeting presentation +4. **Target v1.37 Enhancements Freeze** — submit enhancement issue linking to this KEP directory before the freeze date +5. **Iterate on KEP feedback** — address reviewer comments promptly to maintain momentum + +### Timeline + +| Milestone | Target Date | Action | +|-----------|------------|--------| +| KEP review requested | March 2026 | Post to sig-cli mailing list, attend meeting | +| KEP sponsor assigned | April–May 2026 | Work with sponsor to refine KEP | +| KEP marked `implementable` | Before v1.37 Enhancements Freeze | Get KEP approver sign-off | +| Alpha implementation merged | v1.37 code freeze | PR already open, iterate on review feedback | +| Beta (expanded resources, e2e) | v1.38 | Incorporate alpha feedback | +| GA | v1.39 | Stable after two release cycles of feedback | ## Drawbacks -- Adds a new top-level kubectl subcommand, increasing the command surface area. -- Examples are static and may not cover every user's specific use case. -- Struct-based builders require Go code changes to add new resources (vs. dropping in a YAML file), though this is offset by compile-time type safety. +- Adds a new top-level kubectl subcommand, increasing the command surface area +- Examples are opinionated and may not cover every user's specific use case +- Struct-based builders require Go code changes to add new resources (vs. dropping in a YAML file), though this is offset by compile-time type safety and API consistency ## Alternatives -1. **Embedded YAML templates**: The original approach used `//go:embed` with `.yaml` files. This was simpler but produced static output with no real parameterization, no type safety, and risked template drift from the actual API types. +1. **Embedded YAML templates**: The original implementation used `//go:embed` with `.yaml` files. This was simpler but produced static output with no real parameterization, no type safety, and risked template drift from the actual API types. Abandoned in favor of struct-based generation. -2. **Dynamic generation from OpenAPI schema**: Generate examples by walking the cluster's OpenAPI spec. More flexible but requires API server access, produces verbose output, and cannot provide sensible default values without heuristics. +2. **Dynamic generation from OpenAPI schema**: Generate examples by walking the cluster's OpenAPI spec. More flexible but requires API server access, produces verbose output, and cannot provide sensible default values without heuristics. This is essentially what KEP-2380 attempted and it failed due to server-side complexity. 3. **External example repository**: Host examples in a separate repo and fetch them at runtime. Avoids binary size growth but introduces a network dependency and versioning complexity. -4. **Subcommand of explain**: `kubectl explain --example pod` instead of `kubectl example pod`. Considered but rejected to keep the UX simple and the commands orthogonal. +4. **kubectl plugin via krew**: Distribute as `kubectl-example` plugin. Rejected because plugins don't appear in `kubectl --help`, require separate installation, aren't tested in Kubernetes CI, and break the natural `explain` → `example` discoverability flow. See [Why Not a Plugin?](#why-not-a-plugin) for full analysis. + +5. **Subcommand of explain**: `kubectl explain --example pod` instead of `kubectl example pod`. Considered but rejected to keep the UX simple and the commands orthogonal — `explain` is for schema documentation, `example` is for working manifests. ## Future Work -- Expand resource coverage: ConfigMap, Job, CronJob, Ingress, NetworkPolicy, StatefulSet, DaemonSet -- Support `--output=json` flag for JSON output (trivial with struct-based approach) -- Community-contributed examples via a plugin mechanism +- Expand resource coverage: StatefulSet, DaemonSet, HorizontalPodAutoscaler, ServiceAccount +- Support `--output=json` flag for JSON output (trivial with struct-based approach since `sigs.k8s.io/yaml` supports both) +- Community-contributed examples via a plugin mechanism for custom resource types - Integration with `kubectl explain` to show examples inline with field documentation - Version-aware examples that adapt to the target cluster's API capabilities diff --git a/keps/sig-cli/34146-kubectl-explain-example/kep.yaml b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml index b237145eea85..dc5203104cdf 100644 --- a/keps/sig-cli/34146-kubectl-explain-example/kep.yaml +++ b/keps/sig-cli/34146-kubectl-explain-example/kep.yaml @@ -8,14 +8,14 @@ participating-sigs: [sig-cli] reviewers: [] approvers: [] creation-date: "2025-09-27" -last-updated: "2025-09-27" +last-updated: "2026-03-17" status: provisional stage: alpha -latest-milestone: "v1.36" +latest-milestone: "v1.37" milestone: - alpha: "v1.36" - beta: "v1.37" - stable: "v1.38" + alpha: "v1.37" + beta: "v1.38" + stable: "v1.39" feature-gates: [] disable-supported: false metrics: [] \ No newline at end of file From c2ddba69161eea1fcc034756cfd4ef69edecacfe Mon Sep 17 00:00:00 2001 From: ogormans-deptstack Date: Tue, 17 Mar 2026 17:00:21 +0000 Subject: [PATCH 5/5] KEP-34146: add Gateway API paradigm comparison, update to 13 builders Add Traffic Control Paradigm Comparison section showing how kubectl example teaches Ingress vs NetworkPolicy vs Gateway API side-by-side. Update builder count to 13, test count to 17. Add Gateway/HTTPRoute to default values, version skew, and dependencies sections. Update future work to reflect completed Gateway API implementation. --- .../34146-kubectl-explain-example/README.md | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/keps/sig-cli/34146-kubectl-explain-example/README.md b/keps/sig-cli/34146-kubectl-explain-example/README.md index d14416b0af66..34bdc6b03eb7 100644 --- a/keps/sig-cli/34146-kubectl-explain-example/README.md +++ b/keps/sig-cli/34146-kubectl-explain-example/README.md @@ -20,6 +20,7 @@ - [Builder Registry](#builder-registry) - [Adding New Examples](#adding-new-examples) - [Default Values](#default-values) + - [Traffic Control Paradigm Comparison](#traffic-control-paradigm-comparison) - [Test Plan](#test-plan) - [Prerequisite testing updates](#prerequisite-testing-updates) - [Unit tests](#unit-tests) @@ -222,7 +223,7 @@ High-level flow: This approach provides: -- **Type safety**: Builders use `corev1`, `appsv1`, `batchv1`, `networkingv1`, and `metav1` API types, so invalid field names or structures are caught at compile time +- **Type safety**: Builders use `corev1`, `appsv1`, `batchv1`, `networkingv1`, and `metav1` API types, so invalid field names or structures are caught at compile time. For API types not vendored in kubectl (CRDs, Gateway API), builders use `map[string]interface{}` with the same marshal path — no new dependencies required - **Determinism**: Same inputs always produce identical YAML output — no template rendering, string interpolation, or conditional logic - **Parameterization**: `--name`, `--image`, and `--replicas` flags modify the struct fields before marshaling, providing real customization - **API consistency**: Output automatically follows Kubernetes API field ordering conventions since it is marshaled from the canonical Go types @@ -250,8 +251,10 @@ Supported resources and aliases: | cronjob | cronjobs | `buildCronJob` | `batchv1.CronJob` | | ingress | ingresses, ing | `buildIngress` | `networkingv1.Ingress` | | networkpolicy | networkpolicies, netpol | `buildNetworkPolicy` | `networkingv1.NetworkPolicy` | +| gateway | gateways, gtw | `buildGateway` | `map[string]interface{}` (unstructured) | +| httproute | httproutes | `buildHTTPRoute` | `map[string]interface{}` (unstructured) | -Note: CRD uses an unstructured map because `k8s.io/apiextensions-apiserver` is not in kubectl's `go.mod`. All other resources use their canonical typed API objects. +Note: CRD, Gateway, and HTTPRoute use unstructured maps because their respective type packages (`k8s.io/apiextensions-apiserver`, `sigs.k8s.io/gateway-api`) are not in kubectl's `go.mod`. This is intentional — it avoids adding new dependencies while still producing valid, educational YAML. All other resources use their canonical typed API objects. ### Adding New Examples @@ -280,9 +283,53 @@ Each builder applies sensible, production-oriented defaults: | **CronJob** | `busybox:1.36` | `*/5 * * * *` schedule, date command | | **Ingress** | — | nginx rewrite annotation, `example.com` host, PathTypePrefix, port 80 | | **NetworkPolicy** | — | Frontend→App→Database flow, Ingress+Egress policy types | +| **Gateway** | — | `gatewayClassName: example`, HTTP (port 80) + HTTPS (port 443) listeners, TLS termination with certificateRefs, allowedRoutes from Same namespace | +| **HTTPRoute** | — | parentRef to Gateway, `example.com` hostname, path-based routing (`/api` → api-service, `/` → frontend-service) | All resources include `app.kubernetes.io/name` labels following Kubernetes recommended labels convention. +### Traffic Control Paradigm Comparison + +One of the strongest demonstrations of `kubectl example`'s educational value is its coverage of **three distinct traffic control paradigms**. New Kubernetes adopters frequently struggle to understand when to use Ingress vs. NetworkPolicy vs. Gateway API, and how these resources relate to each other. By providing working examples of all three, `kubectl example` enables side-by-side comparison that no single documentation page currently offers. + +#### Paradigm Overview + +| Paradigm | Command | What It Controls | Direction | OSI Layer | Scope | +|----------|---------|-----------------|-----------|-----------|-------| +| Legacy Ingress | `kubectl example ingress` | External HTTP(S) → Services | Inbound only | L7 (host/path routing) | Cluster-wide, single persona | +| NetworkPolicy | `kubectl example networkpolicy` | Pod-to-Pod traffic | Both ingress + egress | L3/L4 (IP/port/label selectors) | Namespace-scoped, security-focused | +| Gateway API | `kubectl example gateway` | External traffic → Services | Inbound (role-separated) | L4–L7 (protocol-aware) | Cross-namespace, multi-persona | +| | `kubectl example httproute` | HTTP routing rules | Inbound | L7 (host/path/header routing) | Namespace-scoped, developer-owned | + +#### Learning Flow + +A user can explore all three paradigms in sequence to understand Kubernetes networking holistically: + +```shell +# 1. Start with the simplest ingress pattern +kubectl example ingress +# → Single-persona L7 routing: host rules, path rules, TLS, one nginx annotation + +# 2. Understand pod-level traffic control +kubectl example networkpolicy +# → L3/L4 security: label-based ingress/egress rules, port restrictions, deny-by-default + +# 3. See the modern replacement for Ingress +kubectl example gateway +kubectl example httproute +# → Role-separated L7 routing: infrastructure team owns Gateway, developers own HTTPRoutes +``` + +#### Why This Matters for Adoption + +The Gateway API is the [recommended successor to Ingress](https://gateway-api.sigs.k8s.io/) and reached GA in October 2023, but adoption remains slow partly because new users cannot easily see how it differs from Ingress. `kubectl example` makes this comparison concrete: + +- **Ingress** bundles routing, TLS, and infrastructure into one resource controlled by one persona +- **Gateway API** separates infrastructure concerns (Gateway, owned by cluster operators) from routing logic (HTTPRoute, owned by application developers) +- **NetworkPolicy** operates at a completely different layer — pod-to-pod L3/L4 security rather than external L7 routing + +By covering all three paradigms, `kubectl example` serves as a **networking curriculum** built into kubectl itself. Users can generate, diff, and apply these resources to understand the tradeoffs firsthand rather than reading abstract documentation. + ### Test Plan [x] I/we understand the owners of the involved components may require updates to @@ -295,13 +342,13 @@ None required. The command is purely additive with no changes to existing kubect ##### Unit tests -- Verify correct YAML output for all 11 supported resources +- Verify correct YAML output for all 13 supported resources - Verify `--name`, `--image`, and `--replicas` flag overrides work correctly -- Verify alias resolution for all registered aliases (po, deploy, svc, pvc, crd, cm, ing, netpol) +- Verify alias resolution for all registered aliases (po, deploy, svc, pvc, crd, cm, ing, netpol, gtw, httproute) - Verify error handling for unsupported resource kinds - Verify `--list` output includes all registered resources - Tests unmarshal YAML back into typed Go objects and assert specific field values (not string matching) -- **Current coverage**: 15 test functions, all passing +- **Current coverage**: 17 test functions, all passing ##### Integration tests @@ -319,8 +366,8 @@ E2E tests will validate that the output YAML can be applied to a cluster success #### Alpha -- `kubectl example` command implemented with 11 resource builders (pod, deployment, service, pvc, secret, crd, configmap, job, cronjob, ingress, networkpolicy) -- Unit tests in place with structured assertions (15 test functions) +- `kubectl example` command implemented with 13 resource builders (pod, deployment, service, pvc, secret, crd, configmap, job, cronjob, ingress, networkpolicy, gateway, httproute) +- Unit tests in place with structured assertions (17 test functions) - `--name`, `--image`, `--replicas` customization flags working - `--list` flag for discoverability - Offline-first: works without API server via `fallbackResolve()` @@ -347,7 +394,7 @@ Not applicable. This is a new, purely additive kubectl subcommand. Upgrading kub ### Version Skew Strategy -The command generates YAML from in-binary Go struct builders with no API server dependency. The output uses stable API versions (`v1`, `apps/v1`, `batch/v1`, `networking.k8s.io/v1`) that are available across all supported Kubernetes versions. When a kubeconfig is available, the command may optionally attempt discovery-based kind resolution, but falls back to a local alias map if the API server is unreachable. No version skew issues arise because the output is self-contained YAML. +The command generates YAML from in-binary Go struct builders with no API server dependency. The output uses stable API versions (`v1`, `apps/v1`, `batch/v1`, `networking.k8s.io/v1`, `gateway.networking.k8s.io/v1`) that are available across all supported Kubernetes versions. Gateway API resources use the `v1` channel which reached GA in Gateway API v1.0.0 (October 2023) and is widely available in clusters running Gateway API CRDs. When a kubeconfig is available, the command may optionally attempt discovery-based kind resolution, but falls back to a local alias map if the API server is unreachable. No version skew issues arise because the output is self-contained YAML. ## Production Readiness Review Questionnaire @@ -419,7 +466,7 @@ Not applicable. ### Dependencies -None. The command uses only packages already in kubectl's dependency tree: `corev1`, `appsv1`, `batchv1`, `networkingv1`, `metav1`, and `sigs.k8s.io/yaml`. +None. The command uses only packages already in kubectl's dependency tree: `corev1`, `appsv1`, `batchv1`, `networkingv1`, `metav1`, and `sigs.k8s.io/yaml`. Gateway API resources (Gateway, HTTPRoute) use unstructured `map[string]interface{}` builders to avoid adding `sigs.k8s.io/gateway-api` as a new dependency. ### Scalability @@ -463,6 +510,7 @@ The command works fully offline. Examples are generated from in-binary struct bu - **2024-12**: Initial implementation PR opened with embedded YAML templates ([kubernetes/kubernetes#134529](https://github.com/kubernetes/kubernetes/pull/134529)) - **2026-03**: Rearchitected from YAML templates to struct-based generation using typed Kubernetes API objects (`corev1`, `appsv1`, `metav1`) with `sigs.k8s.io/yaml` marshaling. Added working `--name`, `--image`, `--replicas` flags. Rewrote tests with structured assertions (15 test functions). - **2026-03**: Expanded resource coverage from 6 to 11 builders: added ConfigMap (`corev1`), Job (`batchv1`), CronJob (`batchv1`), Ingress (`networkingv1`), NetworkPolicy (`networkingv1`). Updated KEP with precedent analysis, release timing strategy, and plugin rationale. +- **2026-03**: Added Gateway API resources (Gateway, HTTPRoute) using unstructured builders — no new dependencies. Expanded to 13 builders, 17 test functions. Added traffic control paradigm comparison section demonstrating educational value across Ingress, NetworkPolicy, and Gateway API approaches. Removed Gateway API and NetworkPolicy from future work. ## Release Timing Strategy @@ -517,3 +565,4 @@ The v1.36 Enhancements Freeze has already passed, so the earliest realistic targ - Community-contributed examples via a plugin mechanism for custom resource types - Integration with `kubectl explain` to show examples inline with field documentation - Version-aware examples that adapt to the target cluster's API capabilities +- Multi-resource composition: `kubectl example stack web` to generate a coordinated set of resources (Deployment + Service + Ingress/Gateway + NetworkPolicy) as a single manifest