Skip to content
AyoKoding

Quick Start

Want to orchestrate containers at scale with automatic healing and scaling? This quick start introduces essential Kubernetes concepts through practical examples. You'll build from simple pods to production-ready deployments.

This tutorial provides 5-30% coverage using the touchpoints approach - 10 core concepts with runnable examples. After completing this guide, continue to By Example - Beginner for comprehensive 0-40% coverage.

Prerequisites

Before starting, ensure you have completed Initial Setup. You should have:

  • kubectl installed and configured
  • Local Kubernetes cluster running (Minikube or Docker Desktop)
  • Experience deploying basic pods
  • A terminal and text editor ready

Learning Path

This quick start covers 10 essential Kubernetes touchpoints:

%% Color Palette: Blue #0173B2, Orange #DE8F05, Teal #029E73, Purple #CC78BC
graph TD
    A["1. Pods"] --> B["2. Deployments"]
    B --> C["3. Services"]
    C --> D["4. ConfigMaps"]
    D --> E["5. Secrets"]
    E --> F["6. Namespaces"]
    F --> G["7. Labels & Selectors"]
    G --> H["8. Scaling"]
    H --> I["9. Rolling Updates"]
    I --> J["10. Persistent Volumes"]
 
    style A fill:#0173B2,color:#fff
    style B fill:#0173B2,color:#fff
    style C fill:#029E73,color:#fff
    style D fill:#029E73,color:#fff
    style E fill:#DE8F05,color:#fff
    style F fill:#DE8F05,color:#fff
    style G fill:#CC78BC,color:#fff
    style H fill:#CC78BC,color:#fff
    style I fill:#0173B2,color:#fff
    style J fill:#DE8F05,color:#fff

Concept 1: Pods

What: Smallest deployable units containing one or more containers.

Why: Group tightly-coupled containers sharing network and storage.

Example: Multi-Container Pod

Create pod-multi.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: web-with-sidecar
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:alpine
      ports:
        - containerPort: 80
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx
 
    - name: log-reader
      image: busybox
      command: ["sh", "-c", "tail -f /logs/access.log"]
      volumeMounts:
        - name: shared-logs
          mountPath: /logs
 
  volumes:
    - name: shared-logs
      emptyDir: {}

Deploy and interact:

kubectl apply -f pod-multi.yaml
 
kubectl get pods
 
kubectl logs web-with-sidecar -c nginx
kubectl logs web-with-sidecar -c log-reader
 
kubectl exec web-with-sidecar -c nginx -- nginx -v
 
kubectl port-forward web-with-sidecar 8080:80
 
 
kubectl delete pod web-with-sidecar

Key points:

  • Pods are ephemeral - not for direct production use
  • Containers in pod share network namespace (localhost communication)
  • Containers can share volumes (emptyDir, configMap, secret)
  • Use -c flag to target specific container
  • Pod IP address changes when recreated

Concept 2: Deployments

What: Declarative updates for pods with replica management.

Why: Ensure desired number of pods running with automatic recovery.

Example: Scalable Deployment

Create deployment-web.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        version: "1.0"
    spec:
      containers:
        - name: nginx
          image: nginx:1.25-alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "128Mi"
              cpu: "200m"

Deploy and manage:

kubectl apply -f deployment-web.yaml
 
kubectl get pods -w
 
kubectl get deployments
 
kubectl describe deployment nginx-deployment
 
kubectl delete pod <pod-name>
 
kubectl get pods
 
kubectl get replicasets
 
kubectl delete deployment nginx-deployment

Key points:

  • Deployments manage ReplicaSets
  • ReplicaSets ensure desired replica count
  • Automatic pod replacement on failure
  • selector must match template labels
  • Resources: requests (scheduling), limits (enforcement)

Concept 3: Services

What: Stable network endpoints for accessing pods.

Why: Pods are ephemeral with changing IPs - services provide stable access.

Example: Service Types

Create service-demo.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
 
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
 
---
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

Deploy and access:

kubectl apply -f service-demo.yaml
 
kubectl get services
 
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
apk add curl
curl http://web-service
exit
 
minikube ip  # For Minikube users
 
curl http://<minikube-ip>:30080
 
kubectl port-forward service/web-service 8080:80
curl http://localhost:8080
 
kubectl get endpoints web-service
 
kubectl delete -f service-demo.yaml

Key points:

  • ClusterIP: Internal cluster access only (default)
  • NodePort: External access via node IP + port (30000-32767)
  • LoadBalancer: Cloud provider load balancer (AWS ELB, GCP GLB)
  • Services use selectors to find pods
  • Endpoints update automatically as pods change

Concept 4: ConfigMaps

What: Store non-sensitive configuration data as key-value pairs.

Why: Decouple configuration from container images.

Example: Application Configuration

Create configmap-demo.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgres://db:5432/myapp"
  log_level: "info"
  feature_flag: "true"
  app.properties: |
    server.port=8080
    server.host=0.0.0.0
    cache.enabled=true
 
---
apiVersion: v1
kind: Pod
metadata:
  name: config-demo
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "env && cat /config/app.properties && sleep 3600"]
      env:
        - name: DATABASE_URL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_url
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: log_level
      volumeMounts:
        - name: config-volume
          mountPath: /config
  volumes:
    - name: config-volume
      configMap:
        name: app-config

Deploy and verify:

# Create ConfigMap and Pod
kubectl apply -f configmap-demo.yaml
 
# View ConfigMap
kubectl get configmaps
kubectl describe configmap app-config
 
# Check environment variables
kubectl logs config-demo | grep DATABASE_URL
kubectl logs config-demo | grep LOG_LEVEL
 
# Check mounted file
kubectl exec config-demo -- cat /config/app.properties
 
# Update ConfigMap
kubectl edit configmap app-config
# Change log_level to "debug", save and exit
 
# Restart pod to pick up changes
kubectl delete pod config-demo
kubectl apply -f configmap-demo.yaml
 
# Verify updated value
kubectl logs config-demo | grep LOG_LEVEL
 
# Cleanup
kubectl delete -f configmap-demo.yaml

Key points:

  • ConfigMaps store configuration separate from code
  • Inject as environment variables or files
  • Changes require pod restart (unless using special tools)
  • Use for non-sensitive data only
  • Can be created from files: kubectl create configmap my-config --from-file=config.txt

Concept 5: Secrets

What: Store sensitive data (passwords, tokens, keys) encoded in base64.

Why: Separate secrets from application code with encrypted storage.

Example: Database Credentials

Create secrets:

# Create secret from literal values
kubectl create secret generic db-credentials \
  --from-literal=username=admin \
  --from-literal=password=SuperSecret123
 
# Create secret from file
echo -n "my-api-token-xyz" > api-token.txt
kubectl create secret generic api-secret \
  --from-file=token=api-token.txt
rm api-token.txt

Create secret-demo.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
    - name: app
      image: busybox
      command: ["sh", "-c", "env | grep DB_ && cat /secrets/token && sleep 3600"]
      env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: password
      volumeMounts:
        - name: api-secret-volume
          mountPath: /secrets
          readOnly: true
  volumes:
    - name: api-secret-volume
      secret:
        secretName: api-secret

Deploy and verify:

# Create pod
kubectl apply -f secret-demo.yaml
 
# View secrets (values are base64 encoded)
kubectl get secrets
kubectl describe secret db-credentials
 
# Decode secret value
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d
echo
 
# Check pod environment variables
kubectl logs secret-demo | grep DB_
 
# Check mounted secret file
kubectl exec secret-demo -- cat /secrets/token
 
# Cleanup
kubectl delete -f secret-demo.yaml
kubectl delete secret db-credentials api-secret

Key points:

  • Secrets are base64 encoded (not encrypted by default)
  • Enable encryption at rest in production clusters
  • Inject as environment variables or files
  • Avoid logging secret values
  • Use RBAC to restrict secret access
  • Types: Opaque, TLS, Docker registry credentials

Concept 6: Namespaces

What: Virtual clusters for resource isolation within physical cluster.

Why: Multi-tenancy, resource quotas, access control.

Example: Environment Isolation

Create namespace-based environments:

# Create namespaces
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
 
# List namespaces
kubectl get namespaces
 
# Create deployment in specific namespace
kubectl create deployment nginx --image=nginx:alpine -n development
 
# List resources in namespace
kubectl get all -n development
 
# Set default namespace for current context
kubectl config set-context --current --namespace=development
 
# Now commands default to development namespace
kubectl get pods
 
# Switch back to default namespace
kubectl config set-context --current --namespace=default
 
# Create resource quota in namespace
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    pods: "10"
EOF
 
# View quota
kubectl describe quota dev-quota -n development
 
# Delete resources in namespace
kubectl delete deployment nginx -n development
 
# Delete namespaces
kubectl delete namespace development staging production

Key points:

  • Namespaces isolate resources logically
  • Default namespaces: default, kube-system, kube-public
  • Use for environments (dev, staging, prod)
  • Resource quotas limit namespace consumption
  • RBAC policies can be namespace-scoped
  • Services can reference across namespaces: service.namespace.svc.cluster.local

Concept 7: Labels and Selectors

What: Key-value pairs for organizing and selecting resources.

Why: Flexible grouping without rigid hierarchies.

Example: Label-Based Selection

Create labels-demo.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: web-prod-1
  labels:
    app: web
    environment: production
    tier: frontend
    version: "1.0"
---
apiVersion: v1
kind: Pod
metadata:
  name: web-dev-1
  labels:
    app: web
    environment: development
    tier: frontend
    version: "1.0"
---
apiVersion: v1
kind: Pod
metadata:
  name: api-prod-1
  labels:
    app: api
    environment: production
    tier: backend
    version: "2.0"
---
apiVersion: v1
kind: Pod
metadata:
  name: api-dev-1
  labels:
    app: api
    environment: development
    tier: backend
    version: "2.0"

Deploy and query:

kubectl apply -f labels-demo.yaml
 
kubectl get pods --show-labels
 
kubectl get pods -l environment=production
 
kubectl get pods -l environment=production,tier=frontend
 
kubectl get pods -l app
 
kubectl get pods -l '!version'
 
kubectl get pods -l 'environment in (production,staging)'
kubectl get pods -l 'version notin (1.0)'
 
kubectl label pod web-dev-1 region=us-west
 
kubectl label pod web-dev-1 version=1.1 --overwrite
 
kubectl label pod web-dev-1 region-
 
kubectl delete pods -l environment=development
 
kubectl delete -f labels-demo.yaml

Key points:

  • Labels are key-value metadata
  • Selectors filter resources by labels
  • Equality-based: =, !=
  • Set-based: in, notin, exists
  • Services and Deployments use selectors
  • Best practice: consistent labeling scheme (app, env, version, tier)

Concept 8: Scaling

What: Adjust number of pod replicas dynamically.

Why: Handle varying load and ensure availability.

Example: Manual and Automatic Scaling

Create scaling-demo.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-scale
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 100m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 128Mi

Manual scaling:

kubectl apply -f scaling-demo.yaml
 
kubectl get deployment web-scale
 
kubectl scale deployment web-scale --replicas=5
 
kubectl get pods -l app=web -w
 
kubectl scale deployment web-scale --replicas=2
 
kubectl get pods -l app=web

Automatic scaling (HPA):

 
kubectl autoscale deployment web-scale --cpu-percent=50 --min=2 --max=10
 
kubectl get hpa
 
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh
while sleep 0.01; do wget -q -O- http://web-scale; done
 
kubectl get hpa -w
kubectl get pods -l app=web -w
 
kubectl delete deployment web-scale
kubectl delete hpa web-scale

Key points:

  • Manual scaling: kubectl scale
  • HPA: automatic scaling based on metrics
  • Requires metrics server for CPU/memory metrics
  • HPA checks metrics every 15 seconds (default)
  • Scale-up: faster, scale-down: slower (stabilization)
  • Set resource requests for HPA to work

Concept 9: Rolling Updates

What: Update deployments without downtime using gradual replacement.

Why: Zero-downtime deployments with automatic rollback.

Example: Update and Rollback

Create rolling-update.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-rolling
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.24-alpine
          ports:
            - containerPort: 80

Deploy and update:

kubectl apply -f rolling-update.yaml
 
kubectl rollout status deployment web-rolling
 
kubectl rollout history deployment web-rolling
 
kubectl set image deployment/web-rolling nginx=nginx:1.25-alpine
 
kubectl rollout status deployment web-rolling
kubectl get pods -l app=web -w
 
kubectl rollout history deployment web-rolling
 
kubectl rollout history deployment web-rolling --revision=2
 
kubectl set image deployment/web-rolling nginx=nginx:invalid-tag
 
kubectl rollout status deployment web-rolling
 
kubectl rollout undo deployment web-rolling
 
kubectl rollout undo deployment web-rolling --to-revision=1
 
kubectl rollout pause deployment web-rolling
kubectl set image deployment/web-rolling nginx=nginx:1.26-alpine
 
kubectl rollout resume deployment web-rolling
 
kubectl delete deployment web-rolling

Key points:

  • RollingUpdate: default strategy (zero downtime)
  • maxSurge: extra pods during update
  • maxUnavailable: max pods down during update
  • kubectl rollout status: monitor progress
  • kubectl rollout undo: revert to previous version
  • Deployment history stored (default: 10 revisions)

Concept 10: Persistent Volumes

What: Storage abstraction independent of pod lifecycle.

Why: Preserve data across pod restarts and rescheduling.

Example: PersistentVolume and PersistentVolumeClaim

Create pvc-demo.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/k8s-data
  storageClassName: manual
 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi
  storageClassName: manual
 
---
apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
spec:
  containers:
    - name: app
      image: nginx:alpine
      volumeMounts:
        - name: data-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: data-storage
      persistentVolumeClaim:
        claimName: data-claim

Deploy and test persistence:

kubectl apply -f pvc-demo.yaml
 
kubectl get pv
kubectl get pvc
 
kubectl exec pvc-pod -- sh -c "echo '<h1>Persistent Data</h1>' > /usr/share/nginx/html/index.html"
 
kubectl exec pvc-pod -- cat /usr/share/nginx/html/index.html
 
kubectl delete pod pvc-pod
 
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod-2
spec:
  containers:
    - name: app
      image: nginx:alpine
      volumeMounts:
        - name: data-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: data-storage
      persistentVolumeClaim:
        claimName: data-claim
EOF
 
kubectl exec pvc-pod-2 -- cat /usr/share/nginx/html/index.html
 
kubectl delete pod pvc-pod-2
kubectl delete pvc data-claim
kubectl delete pv local-pv

Key points:

  • PV: Cluster-level storage resource
  • PVC: User request for storage
  • Access modes: ReadWriteOnce, ReadOnlyMany, ReadWriteMany
  • StorageClass: dynamic provisioning (cloud providers)
  • Data persists beyond pod lifecycle
  • Reclaim policies: Retain, Delete, Recycle

Learning Path Summary

You've completed 10 essential Kubernetes touchpoints:

%% Color Palette: Blue #0173B2, Orange #DE8F05, Teal #029E73, Purple #CC78BC
graph TD
    A["Pods &<br/>Deployments"] --> B["Services &<br/>Config"]
    B --> C["Secrets &<br/>Namespaces"]
    C --> D["Labels &<br/>Scaling"]
    D --> E["Updates &<br/>Storage"]
 
    style A fill:#0173B2,color:#fff
    style B fill:#029E73,color:#fff
    style C fill:#DE8F05,color:#fff
    style D fill:#CC78BC,color:#fff
    style E fill:#0173B2,color:#fff

Next Steps

Now that you understand core Kubernetes concepts:

  1. By Example - Beginner: Deep dive into 0-40% coverage with 25+ annotated examples
  2. By Example - Intermediate: Advance to 40-75% coverage with StatefulSets and Jobs
  3. By Example - Advanced: Master 75-95% coverage with operators and CRDs

Further Resources

Official Documentation:

Key Concepts:

  • Pods: Smallest deployable units
  • Deployments: Replica management and updates
  • Services: Stable network endpoints
  • ConfigMaps: Configuration data
  • Secrets: Sensitive data management
  • Namespaces: Resource isolation
  • Labels: Flexible resource organization
  • Scaling: Manual and automatic replica adjustment
  • Rolling Updates: Zero-downtime deployments
  • Persistent Volumes: Durable storage

Summary

You've completed the Kubernetes Quick Start with 5-30% coverage! You now understand:

  • Pod structure and multi-container patterns
  • Deployment management and self-healing
  • Service types and networking
  • ConfigMap and Secret configuration
  • Namespace-based isolation
  • Label-based resource selection
  • Manual and automatic scaling
  • Rolling update strategies
  • Persistent volume management
  • Production-ready Kubernetes patterns

Continue your journey with comprehensive By Example tutorials for deeper mastery of Kubernetes orchestration.

Last updated January 28, 2025

Command Palette

Search for a command to run...