Environment Setup & First Steps¶
Duration: 35 minutes (25 minutes theory + 10 minutes lab)
Learning Objectives¶
- Create your first Kubernetes cluster using kind
- Verify kubectl connectivity
- Explore the cluster with k9s
- Understand kubeconfig and contexts
- Run your first Pod
What is kind?¶
kind stands for Kubernetes IN Docker. It runs each Kubernetes node as a Docker container on your local machine instead of a full virtual machine or physical server.
How it works¶
kind packages all the Kubernetes node components (kubelet, containerd, etc.) into a single Docker image. When you create a cluster, kind starts one or more containers — one per node — and bootstraps a fully functional Kubernetes cluster inside them.
Your machine
└── Docker
├── Container: workshop-control-plane (Kubernetes control plane)
└── Container: workshop-worker (Kubernetes worker node)
Why we use kind in this workshop¶
- No cloud account required — everything runs locally inside the dev container
- Fast setup — a cluster is ready in under two minutes
- Lightweight — uses minimal resources, ideal for a laptop or a shared lab environment
- Reproducible — clusters are created from a config file, so everyone starts from the same state
- Easy reset — delete and recreate a cluster in seconds if something goes wrong
Why kind is not for production¶
kind is a development and testing tool only. You should not run production workloads on it because:
- Nodes are containers, not real machines — a container crash or Docker restart wipes the entire cluster
- No persistent storage by default — data does not survive a cluster restart
- No real network isolation — all nodes share the host's Docker network, which differs from how production networking works
- No high-availability guarantees — there is no support for rolling upgrades, node auto-repair, or production SLAs
- Resource limits — it is constrained by your local machine's available CPU and memory
Creating Your First Cluster¶
Step 1: Verify Workshop Environment¶
Make sure you're inside the workshop container:
# You should see this prompt:
vscode ➜ /workspaces/compose-to-kubernetes (main) $
# Verify tools are available
kubectl version --client
kind version
k9s version
Step 2: Create a Cluster¶
# Create a simple cluster (1 control-plane, 1 worker)
kind create cluster --config /workspaces/compose-to-kubernetes/setup/kind/simple.yaml
# This takes 1-2 minutes
# You'll see output like:
# Creating cluster "workshop" ...
# ✓ Ensuring node image (kindest/node:vX.XX.X)
# ✓ Preparing nodes
# ✓ Writing configuration
# ✓ Starting control-plane
# ✓ Installing CNI
# ✓ Installing StorageClass
# ✓ Joining worker nodes
# ✓ Ready after Xs
Step 3: Verify the Cluster¶
# Check cluster info
kubectl cluster-info
# Expected output:
# Kubernetes control plane is running at https://127.0.0.1:XXXXX
# CoreDNS is running at https://...
# List nodes
kubectl get nodes
# Expected output:
# NAME STATUS ROLES AGE VERSION
# workshop-control-plane Ready control-plane 1m v1.XX.X
# workshop-worker Ready <none> 1m v1.XX.X
What you see:
workshop-control-plane: The node running control plane componentsworkshop-worker: The node where your Pods will runSTATUS: Ready: Both nodes are healthyROLES: Identifies the node's role in the cluster
Understanding kubeconfig¶
What is kubeconfig?¶
kubeconfig is a configuration file that tells kubectl:
- Where the cluster is (API server address)
- Who you are (authentication)
- What you can do (authorization/context)
View Your kubeconfig¶
# Default location: ~/.kube/config
kubectl config view
# You'll see (simplified):
# clusters:
# - cluster:
# server: https://127.0.0.1:XXXXX
# name: kind-workshop
# contexts:
# - context:
# cluster: kind-workshop
# user: kind-workshop
# name: kind-workshop
# current-context: kind-workshop
# users:
# - name: kind-workshop
Contexts¶
A context combines:
- A cluster (where to connect)
- A user (how to authenticate)
- A namespace (optional default)
# List contexts
kubectl config get-contexts
# Current context (marked with *)
# * kind-workshop kind-workshop kind-workshop default
# Switch contexts (if you have multiple clusters)
kubectl config use-context kind-workshop
# Set default namespace for context
kubectl config set-context --current --namespace=kube-system
Introduction to kubectl¶
Basic kubectl Structure¶
Essential Commands¶
# Get resources
kubectl get nodes
kubectl get pods
kubectl get services
kubectl get all
# Describe (detailed info)
kubectl describe node workshop-worker
kubectl describe pod <pod-name>
# Create resources
kubectl create deployment nginx --image=nginx
kubectl apply -f myfile.yaml
# Delete resources
kubectl delete pod <pod-name>
kubectl delete deployment nginx
# Logs
kubectl logs <pod-name>
kubectl logs <pod-name> -f # Follow logs
# Execute commands in Pod
kubectl exec <pod-name> -- ls /
kubectl exec -it <pod-name> -- /bin/bash # Interactive shell
# Port forwarding (access Pod locally)
kubectl port-forward pod/<pod-name> 8080:80
Exploring with k9s¶
What is k9s?¶
k9s is a terminal UI for Kubernetes that provides:
- Visual cluster navigation
- Real-time updates
- Quick access to logs, events, and descriptions
- No need to remember kubectl commands
Launch k9s¶
k9s Navigation¶
| Key | Action |
|---|---|
:pods |
View Pods |
:deployments |
View Deployments |
:services |
View Services |
:nodes |
View Nodes |
/ |
Filter/search |
d |
Describe selected resource |
l |
View logs |
s |
Shell into Pod |
Ctrl+d |
Delete |
? |
Help |
:q or Ctrl+c |
Quit |
Try It Out¶
- Launch k9s:
k9s - Type
:nodesand press Enter - Use arrow keys to select a node
- Press
dto describe it - Press
Escto go back - Type
:qto quit
Your First Pod¶
Let's create and interact with a Pod:
# Create a Pod running nginx
kubectl run my-nginx --image=nginx:latest
# Wait for it to be ready
kubectl get pods -w
# Press Ctrl+C to stop watching
# Check its status
kubectl get pod my-nginx
# Get detailed information
kubectl describe pod my-nginx
# View logs
kubectl logs my-nginx
# Execute a command in the Pod
kubectl exec my-nginx -- nginx -v
# Get an interactive shell
kubectl exec -it my-nginx -- /bin/bash
# Try: ls, cat /etc/nginx/nginx.conf, exit
# Expose it locally
kubectl port-forward pod/my-nginx 8080:80 &
# Test it (in another terminal or stop port-forward first)
curl http://localhost:8080
# Clean up
kill %1 # Stop port-forward
kubectl delete pod my-nginx
Exploring the Cluster¶
System Pods¶
Kubernetes runs its own Pods for cluster functionality:
# View system Pods
kubectl get pods -n kube-system
# You'll see:
# - coredns-*: DNS server for the cluster
# - etcd-*: Key-value store
# - kube-apiserver-*: API server
# - kube-controller-manager-*: Controller manager# - kube-proxy-*: Network proxy
# - kube-scheduler-*: Scheduler
Namespaces¶
Namespaces provide logical separation:
# List namespaces
kubectl get namespaces
# Default namespaces:
# - default: Default namespace for resources
# - kube-system: System components
# - kube-public: Public resources
# - kube-node-lease: Node heartbeat information
# Get resources from specific namespace
kubectl get pods -n kube-system
# Get resources from ALL namespaces
kubectl get pods --all-namespaces
# or
kubectl get pods -A
Cluster Information¶
Comprehensive Cluster View¶
# Cluster info
kubectl cluster-info
kubectl cluster-info dump # Very detailed (lots of output!)
# Node resources
kubectl top nodes # Requires metrics-server (not in kind by default)
# API resources available
kubectl api-resources
# API versions
kubectl api-versions
# Check component status
kubectl get componentstatuses
# or
kubectl get cs
Cleanup (Optional)¶
If you want to start fresh:
# Delete the cluster
kind delete cluster --name workshop
# Recreate it
kind create cluster --config /workspaces/compose-to-kubernetes/setup/kind/simple.yaml
Tips¶
Alias kubectl to k:
Watch resources in real-time:
Use bash completion:
# Already configured in the workshop container
kubectl get <Tab><Tab> # Auto-complete resource types
Quick describe:
Troubleshooting¶
"Connection refused" error¶
# Check cluster is running
kind get clusters
# If not listed, recreate
kind create cluster --config /workspaces/compose-to-kubernetes/setup/kind/simple.yaml
"No resources found"¶
# Make sure you're in the right namespace
kubectl get pods -A # Check ALL namespaces
# Check current context
kubectl config current-context
k9s shows errors¶
Key takeaways¶
- kind creates local Kubernetes clusters using containers as nodes
- kubectl is the command-line tool to interact with the cluster
- kubeconfig tells kubectl where and how to connect
- contexts allow switching between clusters
- k9s provides a visual interface for cluster management
- Namespaces provide logical separation of resources
Check your understanding¶
- What command lists all nodes in your cluster?
- How do you view logs from a Pod?
- What's the difference between
kubectl getandkubectl describe? - What does a context contain?
- How do you view Pods in all namespaces?
Solution
kubectl get nodeskubectl logs <pod-name>getshows a list/table view;describeshows detailed information about a specific resource- A cluster, a user, and optionally a default namespace
kubectl get pods --all-namespacesorkubectl get pods -A
Hands-on¶
Apply the concepts from this section in the lab exercises.
Next section¶
Once you've reviewed the content and completed the lab, proceed to the next section.