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:
- Cobra command in
pkg/cmd/<verb>/. Carries flags and theRunfunction. - An
Optionsstruct that holds parsed flags + aFactory(for resolving the kubeconfig and discovery client). - A
Validate()method that checks the command-line is internally consistent. - A
Complete()method that resolves implicit values (defaults, current namespace, target resource). - 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:
--kubeconfigflag,KUBECONFIGenv,~/.kube/config) - Current namespace (precedence:
--namespaceflag, 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 anapplication/apply-patch+yamlPatch, 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 foo → kubectl-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
Tablerendering 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 inpkg/cmd/cmd.go. - New
-oformat: implementprinters.ResourcePrinterand register instaging/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.