§1 through §9 are about Kubernetes. This section is about the
tools you use to work with Kubernetes — the editor for manifests,
the shell for commands, the conveniences that make 1000 kubectl
invocations feel like 100.
None of what’s below is required for the examples in this
tutorial to work. The examples have been written to copy-paste
directly. But by §6 you’ve probably noticed that typing kubectl
get deployment nginx -n default -o yaml for the fifteenth time
gets old; by §11 (Istio) it gets very old.
The goal here: enough productivity wins that the rest of your k8s
work feels natural rather than tedious.
Editor: Pulsar
This tutorial’s manifests were written and tested in Pulsar
— the community-maintained successor to Atom, which GitHub
discontinued in 2022 after the Microsoft acquisition. A group of
contributors forked the editor and continues to ship it under the
Pulsar name. Open source,
fast keyboard-driven workflow, plugin-friendly. The official
Fedora .rpm is at pulsar-edit.dev.
Out of the box, Pulsar gives you what matters for editing
Kubernetes manifests:
- YAML syntax highlighting —
apiVersion, kind, list/map
structure all visually distinct
- Bracket and indentation matching — YAML indentation is
load-bearing, and a misaligned space wastes hours. Pulsar
shows the indent guides
- Fuzzy file finder (Ctrl-T) — type
dep<enter> to jump to
deployment.yaml from anywhere in the project
- Multi-pane editing for side-by-side manifests (e.g., the
Deployment in one pane, the Service in another)
- Project-wide search — useful when you’ve forgotten which
example uses a particular pattern
- Git integration — see what’s changed before
git diff-ing in the terminal
For schema-aware editing (red-underlining unknown fields,
autocomplete for spec.containers[] and friends), check Pulsar’s
package registry for bindings to yaml-language-server. Pointing
the language server at the Kubernetes JSON Schema URL gives you
IDE-grade validation inside a lightweight editor.
If Pulsar isn’t your thing
This tutorial doesn’t depend on the editor — manifests are plain
YAML; the editor doesn’t talk to the cluster. Use whatever you
like:
- VS Code with Microsoft’s official Kubernetes extension —
most popular by far; deep schema awareness; integrated kubectl
panel that shows cluster state alongside the editor. If you
want a single tool that does everything, this is it
- Neovim with
yaml-language-server (via Mason or LSP-zero)
— terminal-native, fast, mature ecosystem; popular among
k8s practitioners who already live in vim
- IntelliJ family (IDEA, GoLand, PyCharm, CLion, …) with
JetBrains’ Kubernetes plugin — same schema awareness as
VS Code in a heavier IDE
- nano / vi / vim out of the box — works fine for one-off
edits; less convenient when you’re hopping between multiple
manifest files in a single example directory
The §6-§9 demos all run identically regardless of which editor
opened the manifests.
Shell: zsh
The §1 prerequisites assumed a POSIX-style shell. The demo.sh
scripts and helpers under scripts/lib/ all start with
#!/usr/bin/env bash, so they run under bash regardless of your
interactive shell.
For interactive k8s work, zsh has a few advantages worth
the switch:
- Tab completion is more powerful and more configurable than
bash’s — completing pod names, label keys, resource fields
kubectl, helm, and minikube ship with first-class zsh
completion
- The
oh-my-zsh framework (ohmyz.sh)
packages a kubectl plugin, prompt themes that show your
current cluster context, and a hundred quality-of-life
features
Fedora 44’s default for new users is bash. Install and switch
to zsh:
sudo dnf install -y zsh
chsh -s "$(which zsh)"
Log out and back in. New terminal sessions launch zsh; the
demo.sh scripts keep working unchanged (they exec their own
bash).
If you’d rather stick with bash, everything below still works —
substitute bash for zsh in the completion source lines,
and use complete -F instead of compdef for the aliases.
Tab completion — the single biggest win
If you do nothing else in this section, do this. Tab completion
turns kubectl get pod nginx-pv-864c5dfd8b-zvpwn into kubectl
get pod nginx-pv<TAB> and lets the shell fill in the rest.
Add to ~/.zshrc:
# kubectl / helm / minikube tab completion
source <(kubectl completion zsh)
source <(helm completion zsh)
source <(minikube completion zsh)
For bash, the equivalent in ~/.bashrc:
source <(kubectl completion bash)
source <(helm completion bash)
source <(minikube completion bash)
Reload (source ~/.zshrc) and try:
You’ll see pod podsecuritypolicies poddisruptionbudgets ….
Completion also covers resource names — `kubectl describe pod
` lists the actual Pods in your current namespace.
## Aliases: the k= shortcut family
The de facto convention among k8s practitioners is `alias
k=kubectl`. Three keystrokes per command saved; small-sounding
until you've run kubectl a few hundred times.
If you're not normally an alias user (some good reasons not to:
aliases hide from teammates pairing on your terminal, scripts
can't assume them, they make screenshots in tutorials harder to
follow), the conventional set is still worth knowing because it
appears in blog posts, talks, and others' shell history.
A curated starter set for `~/.zshrc`:
```zsh
# kubectl shortcuts
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kgn='kubectl get nodes'
alias kga='kubectl get all'
alias kd='kubectl describe'
alias kdp='kubectl describe pod'
alias kl='kubectl logs'
alias klf='kubectl logs -f'
alias kx='kubectl exec -it'
# helm shortcut
alias h=helm
# Tell completion to handle k and h as aliases for kubectl/helm.
# zsh-specific; the bash equivalent is `complete -F`.
compdef __start_kubectl k
compdef __start_helm h
```
After `source ~/.zshrc`:
```
k g
```
… completes to `get`, just like `kubectl`. Tab completion follows
the alias because of the `compdef` lines.
Two variants worth knowing:
- **`kgp -w`** — kubectl's watch flag re-renders Pod state as it
changes. `kgp -w` is the fastest way to see a Deployment roll
out
- **oh-my-zsh's `kubectl` plugin** — a turn-key alias set far
larger than the above. Enable in `~/.zshrc` via `plugins=(...
kubectl ...)`. The trade-off: more aliases to remember vs.
copying the curated short list
## kubectl built-ins worth knowing
Two kubectl subcommands that aren't in §6-§9 but earn their
keep:
- **`kubectl edit `** — opens the live object in your
`$EDITOR` (set this to `pulsar -w` or your preference). Save
and the change is applied to the cluster. Useful for one-off
tweaks; less safe than `apply` from a versioned file but
faster for exploration
- **`kubectl explain .`** — schema lookup. Forgot
what `spec.template.spec.affinity` accepts? `kubectl explain
deployment.spec.template.spec.affinity` lists the subfields
with descriptions. Faster than the official docs when you
already know the resource name
## Context and namespace switching: kubectx, kubens
§2 installed these as krew plugins (`kubectl ctx`, `kubectl ns`).
The fast access pattern:
```bash
kubectl ctx # list contexts; current marked
kubectl ctx minikube # switch context
kubectl ns # list namespaces; current marked
kubectl ns kube-system # switch default namespace
```
If you live in a single minikube cluster these matter less; the
moment you're toggling between minikube and a remote cluster —
or between `default` and `kube-system` — the gain is obvious.
## Streaming logs from multiple Pods: stern
Also installed in §2:
```bash
stern -l app=nginx-helm
```
Tails logs from every Pod matching the label, color-coded by
Pod name. More useful than `kubectl logs -f ` specifically
for Deployments where you want all replicas' output interleaved.
## k9s — curses UI for the cluster
`kubectl get pods` over and over feels like driving by reading
the speedometer. **k9s** is the dashboard.
A curses-style terminal UI: navigate Kubernetes resources with
arrow keys and short letter commands, see live updates as state
changes, drill into Pods to view logs / shell in / view the
manifest inline.
Install from Fedora:
```bash
sudo dnf install -y k9s
```
Or grab the latest release from [k9scli.io](https://k9scli.io/).
Launch:
```bash
k9s
```
`?` shows keyboard shortcuts. `:pod` lists Pods. Press
`l` on a Pod to tail its logs; `s` to open a shell in it; `d`
to describe. `:svc` switches to Services, `:deploy`
to Deployments. `q` quits.
k9s is the single most-recommended optional tool here. Not
because the examples need it, but because once you have it
running in a second terminal pane while you `kubectl apply` in
another, debugging gets noticeably faster.
## Keeping multiple things open
A productive minikube session commonly has several long-running
things side by side:
- Nothing needs a terminal held open for access: services are on
published ports (§7), reachable at `127.0.0.1` from any shell or
browser
- `k9s` (one terminal, full-screen TUI)
- An interactive shell for running kubectl commands
- A `stern` log stream (one terminal, scrolling)
Three approaches to keeping these organized:
- **Terminal tabs** in whichever GUI terminal emulator you use
(GNOME Terminal, Kitty, Alacritty, Konsole, …). Simple,
visual, works everywhere
- **tmux** — the venerable terminal multiplexer. Detach and
re-attach across SSH sessions, define window layouts, scroll
back through buffers. Install via `sudo dnf install -y tmux`
- **zellij** — modern alternative to tmux with friendlier
defaults (the keybindings are discoverable rather than
cryptic). Check [zellij.dev](https://zellij.dev/)
This tutorial doesn't depend on terminal multiplexing — each
demo runs in one terminal — but you'll find yourself wanting it
as the parallelism grows in §11 onwards.
## Putting it together
A productive minikube-on-Fedora workflow:
1. **Pulsar** (or your editor) open on the manifest files
2. **zsh** with kubectl/helm/minikube tab completion and the
alias set above
3. **k9s** in a second terminal showing live cluster state
4. The current `examples/NN-*/demo.sh` running in a third
terminal
None of these are required for the examples in §1-§9 to work,
and none are part of the reconciliation plan (this section is
reference material). But the §6-§9 demos all become much more
pleasant to run with this setup — and the §11 Istio work, with
its handful of long-running watch processes, almost requires
it.
[On to §11: Istio →](/minikube-on-fedora/docs/11-istio/)