Skip to main content
This lesson is short and focused: applying a Custom Resource (CR) is the simpler half of the operator pattern, but it’s useful to understand how the API server exposes and validates CRs and how to inspect them with kubectl. Below I walk through the typical steps to apply a Widget CR and explore it using various kubectl commands.

Setup

  • The lab platform pre-applied the Widget Custom Resource Definition (CRD) from the previous lesson and provided a starter YAML file in your lab folder.
  • The CRD enforces:
    • a color pattern (six-digit hex),
    • a size enum,
    • and exposes additional printer columns and a short name for convenience.
  • The starter YAML includes a placeholder color of "#000000" — replace that with any valid 6-digit hex color (keep the quotes so YAML treats # as a literal, not a comment).
Open the starter file in your editor and update the color value. Example starter resource (edit the color as needed):
Always quote a hex color in YAML (for example: "#4287f5"). Without quotes, # begins a comment and the value will be parsed incorrectly.
Apply the CR:
Expected apply output:
That confirmation indicates the CRD schema validated your fields (the color matched the pattern and size: medium is in the enum).

Five ways to view the same Widget

Below are common ways to inspect a CR with kubectl. Each method serves different uses: quick overviews, scripting, full object inspection, or troubleshooting.

1) kubectl get (table view with additional printer columns)

The CRD added Additional Printer Columns for size and color, so kubectl get shows those fields directly:
Example output:
These columns make custom resources feel like first-class Kubernetes types by surfacing key fields without inspecting the full YAML.

2) Short name (fewer keystrokes)

The CRD defined a short name wg, so you can use it instead of the full plural:
Output (identical to the previous):
Short names are configured in the CRD’s spec.names.shortNames and are convenient for interactive work and scripts.

3) Full object (YAML)

To inspect the full object, including server-populated metadata:
Example (abridged to relevant parts):
Note the API server populated standard metadata fields (creationTimestamp, uid, resourceVersion, generation). Because this lab is CR-only (no controller installed), there is no status block yet — that will appear when a controller reconciles the CR and updates status.

4) jsonpath (machine-friendly single-field extraction)

For scripts or one-liners, jsonpath extracts a single field cleanly. Example — get only the color:
Output:
This pattern is useful in shell scripts where you need a single value with no extra parsing.

5) describe (human-readable breakdown and events)

kubectl describe provides a friendly field-by-field summary and an Events section at the bottom:
Example output (abridged):
When you later implement the controller that reconciles Widget resources, events from each reconcile or error will appear here — making describe the first place to look when something goes wrong.

Extra: kubectl explain (auto-generated documentation)

kubectl explain reads the CRD’s OpenAPI v3 schema and displays field descriptions you included in the CRD. This effectively becomes auto-generated documentation for your CR API. Examples:
Sample output for widget.spec.color:
If you add description fields to your CRD schema, they will appear here. Including descriptions in the CRD is valuable because kubectl explain surfaces them to users and scripts.
This lab contains only the CRD and CR (no controller). The API server validates and stores the object, but no controller will reconcile it or populate status until you implement one.

Wrap-up

This walkthrough demonstrates the consumer side of the operator pattern:
  • The CRD defines the shape, validation, and documentation for the resource.
  • The API server treats custom resources like built-ins (populating metadata and enforcing schema).
  • kubectl provides familiar tooling (get with printer columns, short names, describe, jsonpath, explain) to interact with CRs.
Next step: implement a controller that watches and reconciles Widget resources to observe status updates and events.

Watch Video