Open-Source Wikis

/

Kubernetes

/

Components

/

kubectl

kubernetes/kubernetes

kubectl

kubectl is the official command-line client. The binary in cmd/kubectl/ is a thin wrapper; the real code lives in the staging module staging/src/k8s.io/kubectl/.

Directory layout

cmd/kubectl/
└── kubectl.go                # main: builds command, calls cli.Run

staging/src/k8s.io/kubectl/
├── pkg/
│   ├── cmd/                  # One subcommand per CLI verb
│   │   ├── apply/
│   │   ├── get/
│   │   ├── describe/
│   │   ├── exec/
│   │   ├── logs/
│   │   ├── run/
│   │   ├── scale/
│   │   ├── rollout/
│   │   ├── port-forward/
│   │   └── ... (~50 verbs)
│   ├── cmd/util/             # Shared CLI utilities (factory, flag groups)
│   ├── describe/             # Per-resource describe formatters
│   ├── drain/                # Node drain logic (used by `kubectl drain` and `kubectl cordon`)
│   ├── explain/              # Schema-driven `kubectl explain`
│   ├── generate/             # Legacy generators for `kubectl run`/`expose`
│   ├── polymorphichelpers/   # Common operations across resource kinds
│   ├── scheme/               # Built-in scheme used to decode YAML
│   └── util/                 # Shared helpers
└── ...

cmd/kubectl-convert/          # `kubectl convert` plugin (separate binary)

Subcommand pattern

Every verb follows the same shape:

  1. Cobra command in pkg/cmd/<verb>/. Carries flags and the Run function.
  2. An Options struct that holds parsed flags + a Factory (for resolving the kubeconfig and discovery client).
  3. A Validate() method that checks the command-line is internally consistent.
  4. A Complete() method that resolves implicit values (defaults, current namespace, target resource).
  5. A Run() method that does the actual work.

This split keeps unit tests focused on Validate and Run, with Complete mocked.

The factory

staging/src/k8s.io/kubectl/pkg/cmd/util/factory.go is the central dependency. It is the single place that resolves:

  • Kubeconfig (precedence: --kubeconfig flag, KUBECONFIG env, ~/.kube/config)
  • Current namespace (precedence: --namespace flag, kubeconfig context's namespace, default)
  • Discovery client (cached, on disk under ~/.kube/cache/discovery/)
  • REST mapper (used to map kind → resource on the server)
  • Object printer (format negotiation between -o yaml, -o json, -o jsonpath, -o name, -o wide, …)
  • Object decoder (YAML/JSON → typed object via the scheme)

Subcommand code reaches into the factory rather than instantiating these themselves; this is what lets every subcommand share consistent flag behaviour.

Server-side apply vs client-side apply

kubectl apply has two modes:

  • Client-side apply (legacy default before 1.18) — kubectl computes a 3-way merge between the live object, the manifest, and the previous applied annotation, then sends a Patch.
  • Server-side apply (kubectl apply --server-side) — kubectl sends the manifest as an application/apply-patch+yaml Patch, and the server computes the merge using field-managed metadata.

The client-side merge logic is in staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/. Server-side apply lives entirely in the apiserver.

Plugins

kubectl autodiscovers binaries on $PATH named kubectl-*. They become subcommands (kubectl fookubectl-foo). The convention is documented in staging/src/k8s.io/kubectl/pkg/cmd/plugin/.

The bundled kubectl convert is itself a plugin shipped from cmd/kubectl-convert/.

Output formatting

The -o flag is processed by staging/src/k8s.io/cli-runtime/pkg/printers/. Built-in formats include yaml, json, name, wide, go-template, go-template-file, jsonpath, jsonpath-file, jsonpath-as-json, custom-columns, custom-columns-file. The wide and default tabular outputs come from server-side Table rendering (the apiserver returns a meta.k8s.io/v1.Table).

Diff and rollout helpers

kubectl diff shells out to a tool defined by KUBECTL_EXTERNAL_DIFF (default diff). The library code that produces the patch + applied-on-server view is in pkg/cmd/diff/.

kubectl rollout is implemented per resource kind in pkg/cmd/rollout/. For each kind, an interface provides History, Status, Pause, Resume, Restart, Undo. Implementations live next to each (Deployment, DaemonSet, StatefulSet).

Drain and cordon

pkg/drain/drain.go carries the cluster-aware drain implementation: list pods on a node, evict each pod respecting PodDisruptionBudget, fall back to delete for pods that don't tolerate eviction. Used by kubectl drain, kubectl uncordon, and consumed externally by tools like cluster-api.

Key source files

File Purpose
cmd/kubectl/kubectl.go main, builds NewDefaultKubectlCommand
staging/src/k8s.io/kubectl/pkg/cmd/cmd.go Top-level Cobra tree
staging/src/k8s.io/kubectl/pkg/cmd/util/factory.go Factory abstraction
staging/src/k8s.io/kubectl/pkg/describe/describe.go Per-kind describe printers
staging/src/k8s.io/kubectl/pkg/drain/drain.go Drain logic
staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go Apply command
staging/src/k8s.io/kubectl/pkg/cmd/diff/diff.go Diff command
staging/src/k8s.io/cli-runtime/pkg/genericclioptions/ Shared flag groups

Integration points

  • kube-apiserver — kubectl talks REST.
  • client-go — every command builds typed clients via staging/src/k8s.io/client-go.
  • CRDs — discovery surfaces them automatically; printers fall back to the Table rendering produced by the API server.
  • cli-runtime — common flag groups, resource builder, output printers.

Entry points for modification

  • New verb: add a package under staging/src/k8s.io/kubectl/pkg/cmd/<verb>/, implement Cobra command + Options{Validate,Complete,Run}, and register in pkg/cmd/cmd.go.
  • New -o format: implement printers.ResourcePrinter and register in staging/src/k8s.io/cli-runtime/pkg/genericclioptions.
  • Plugin: just write a binary named kubectl-<verb> and put it on $PATH.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

kubectl – Kubernetes wiki | Factory