Skip to main content

Workstation Setup

This chapter prepares your local machine for everything that follows. You'll install every CLI tool the course uses, authenticate with the services it depends on, and run a smoke test that proves each tool works. Nothing here costs money; the cluster doesn't exist yet.

Prerequisites

  • The orientation read.
  • A GitHub account.
  • A DigitalOcean account with billing enabled.

What you will install

ToolWhy we need itVersion this course was written against
docker (or Podman)Build images locally and feed them to kind.25.x or newer
node / npmRun and test the Express app.Node.js 20 LTS
kubectlThe Kubernetes CLI.1.30+
helmInstall kube-prometheus-stack, cert-manager, Traefik, others.3.14+
kustomizeManage manifests with base + overlays.5.x
k9sTerminal UI for navigating the cluster fast.0.32+
kindRun Kubernetes locally for early chapters.0.31+
doctlCreate droplets, the container registry, Spaces, Load Balancers.1.104+
ghDrive GitHub from the terminal (workflows, branch protection, secrets).2.50+
kubesealEncrypt secrets so they can be committed safely.0.27+
trivyScan images and manifests for vulnerabilities.0.55+
jq, curl, gitEveryday helpers used by snippets in this course.recent

You don't need to match versions exactly. Anything newer than the listed minimum is fine; if you hit a behavior change, the chapter that uses the tool calls it out.

Step 1 — Pick your shell

Use either bash or zsh. Both are fine. The course only assumes POSIX shell features. Verify:

echo "$SHELL"
# /bin/bash or /bin/zsh

If you use fish, the commands in this course still work because each example invokes a real binary; only export syntax differs. When you see export FOO=bar, in fish write set -x FOO bar.

macOS: install GNU coreutils

A few snippets in later chapters assume GNU userland behavior, for example a sed -i form without an explicit suffix, or a date -d 'N hours ago'. The course tries hard to use portable forms (e.g. date +%s arithmetic instead of date -d), but install GNU coreutils on macOS anyway so you have gsed, gdate, gawk, etc. when a snippet does drift:

brew install coreutils gnu-sed gawk
# To make GNU versions the default (without overriding macOS defaults), prepend
# the gnubin paths only for this course's shell:
echo 'export PATH="$(brew --prefix coreutils)/libexec/gnubin:$(brew --prefix gnu-sed)/libexec/gnubin:$PATH"' >> ~/.zshrc

Linux users can skip this section.

Step 2 — Install Docker

You need a container runtime locally for kind and for building the app image. Docker is the default; Podman with a docker alias also works.

Linux (Fedora / RHEL family):

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"
# log out and back in so the group change takes effect

Linux (Debian / Ubuntu family):

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
# log out and back in

macOS: install Docker Desktop from the official download page, then launch it once.

Verify:

docker version
docker run --rm hello-world

Expected: the second command prints the "Hello from Docker!" banner.

Step 3 — Install Node.js (LTS) and npm

Linux (any distro): use nvm so you can switch versions later:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# open a new shell, then:
nvm install --lts
nvm use --lts

macOS: either brew install node@20 or use nvm as above.

Verify:

node --version # v20.x
npm --version # 10.x

Step 4 — Install the Kubernetes client tools

You can install these one at a time. The course assumes all of them are on your PATH.

kubectl

Linux:

KREL="$(curl -L -s https://dl.k8s.io/release/stable.txt)"
curl -LO "https://dl.k8s.io/release/${KREL}/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm kubectl

macOS:

brew install kubectl

Verify:

kubectl version --client
# Client Version: v1.30.x (or newer)

helm

Linux:

curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

macOS:

brew install helm

Verify: helm version.

kustomize

kubectl ships an embedded Kustomize, but a few features in this course need the standalone binary.

Linux/macOS:

curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/

Verify: kustomize version.

k9s

Linux: download the latest release from the releases page and unpack into /usr/local/bin. Or use Homebrew on Linux: brew install derailed/k9s/k9s.

macOS: brew install k9s.

Verify: k9s version.

kind

# Linux
go install sigs.k8s.io/kind@v0.31.0 # if you have Go
# or grab the binary:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-linux-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind

# macOS
brew install kind

If you used go install, the binary lands in Go's bin directory ($(go env GOPATH)/bin, usually ~/go/bin). That directory isn't on PATH by default, so the shell won't find kind until you add it:

echo 'export PATH="$PATH:$(go env GOPATH)/bin"' >> ~/.bashrc # or ~/.zshrc
source ~/.bashrc # or ~/.zshrc

Verify: kind --version.

Step 5 — Install the platform CLIs

doctl

# Linux
cd /tmp
curl -sL https://github.com/digitalocean/doctl/releases/download/v1.159.0/doctl-1.159.0-linux-amd64.tar.gz | tar -xzv
sudo mv doctl /usr/local/bin

# macOS
brew install doctl

Verify: doctl version.

gh

Linux (Fedora):

sudo dnf install -y gh

Linux (Debian/Ubuntu):

curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
https://cli.github.com/packages stable main" \
| sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update && sudo apt install -y gh

macOS: brew install gh.

Verify: gh --version.

Step 6 — Install the security and secrets tools

kubeseal

# Linux
KSV=0.36.6
curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KSV}/kubeseal-${KSV}-linux-amd64.tar.gz"
tar -xvzf kubeseal-${KSV}-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
rm kubeseal kubeseal-${KSV}-linux-amd64.tar.gz

# macOS
brew install kubeseal

Verify: kubeseal --version.

trivy

# Linux
sudo dnf install -y trivy # Fedora
# or, on any Linux:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin

# macOS
brew install trivy

Verify: trivy --version.

Step 7 — Shell completion

Set up completion now. You'll type these commands hundreds of times.

# bash
mkdir -p ~/.local/share/bash-completion/completions
kubectl completion bash > ~/.local/share/bash-completion/completions/kubectl
helm completion bash > ~/.local/share/bash-completion/completions/helm
gh completion -s bash > ~/.local/share/bash-completion/completions/gh

# zsh
cat >> ~/.zshrc <<'EOF'
autoload -U compinit; compinit
source <(kubectl completion zsh)
source <(helm completion zsh)
source <(gh completion -s zsh)
EOF

Open a new shell and confirm kubectl <TAB> completes.

A useful alias for the rest of the course:

echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc

Step 8 — SSH key for GitHub and DigitalOcean

If you don't already have one:

ssh-keygen -t ed25519 -C "$(whoami)@$(hostname) — k8slearn"
# accept defaults; set a passphrase

Add the public key to GitHub:

gh ssh-key add ~/.ssh/id_ed25519.pub --title "k8slearn"

You'll add the same public key to DigitalOcean in Part 3 when you provision droplets.

Step 9 — Authenticate the CLIs

GitHub

gh auth login
# - GitHub.com
# - SSH protocol
# - Use your existing key
# - Login with a web browser

Verify:

gh auth status
# ✓ Logged in to github.com as <you>

DigitalOcean

In the DO control panel, go to API → Personal access tokens and create a token with full read and write scopes (you need write so doctl can create droplets, registries, Spaces, and Load Balancers later). Copy the token; you won't see it again.

doctl auth init
# paste the token at the prompt
doctl account get

Expected: your DO account email and team show up.

Step 10 — Smoke test

Save this as ~/k8slearn-smoke.sh and run it:

#!/usr/bin/env bash
set -euo pipefail

tools=(docker node npm kubectl helm kustomize k9s kind doctl gh kubeseal trivy jq curl git)

echo "=== version check ==="
for t in "${tools[@]}"; do
printf "%-10s : " "$t"
case "$t" in
docker) docker --version ;;
node) node --version ;;
npm) npm --version ;;
kubectl) kubectl version --client --output=yaml | grep gitVersion ;;
helm) helm version --short ;;
kustomize) kustomize version ;;
k9s) k9s version --short 2>/dev/null || k9s version ;;
kind) kind --version ;;
doctl) doctl version | head -n1 ;;
gh) gh --version | head -n1 ;;
kubeseal) kubeseal --version ;;
trivy) trivy --version | head -n1 ;;
jq) jq --version ;;
curl) curl --version | head -n1 ;;
git) git --version ;;
esac
done

echo
echo "=== auth check ==="
gh auth status
doctl account get

Run:

chmod +x ~/k8slearn-smoke.sh
~/k8slearn-smoke.sh

Expected: every line prints a version. gh auth status reports you're logged in. doctl account get prints your account details. If anything fails, fix that tool before moving on; the next chapter assumes all of them work.

Completion signal

~/k8slearn-smoke.sh exits 0. kubectl version --client exits cleanly. gh auth status and doctl account get both succeed without errors. You can read your DO account name and your GitHub username from the smoke test output.

You're ready to move on to 02. Fundamentals (Local).