A

Ahmed

DevOps Engineer · Software Engineer

Egyptahmed@example.comOperational
Back to Blog
KubernetesDevOps

Getting Started with Kubernetes: A Practical Guide

A hands-on walkthrough of deploying your first application on Kubernetes, from pods to services to ingress.

A

Ahmed

Feb 10, 20268 min read

Kubernetes (K8s) has become the de-facto standard for container orchestration in production environments. Whether you're running a single microservice or a fleet of hundreds, Kubernetes provides the primitives to deploy, scale, and manage containerized applications with confidence.

Note

This guide assumes basic familiarity with Docker and containers. If you're new to Docker, I'd recommend getting comfortable with building and running images before diving in.

Core Concepts You Must Know

Before touching kubectl, let's establish the mental model. Kubernetes introduces several abstractions that map closely to how you think about running applications:

  • Pod — the smallest deployable unit, wrapping one or more containers that share network and storage
  • Deployment — declares desired state (how many replicas, which image) and reconciles continuously
  • Service — gives your pods a stable network identity and load balances traffic between them
  • Ingress — routes external HTTP/HTTPS traffic to the right Service based on rules
  • ConfigMap / Secret — externalise configuration and sensitive data away from container images
  • Namespace — logical isolation between teams, environments, or projects within a single cluster

Setting Up a Local Cluster

The fastest way to get a Kubernetes cluster locally is with kind (Kubernetes IN Docker) or minikube. I prefer kind for its simplicity and speed:

bash
# Install kind (macOS/Linux)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind

# Create a cluster
kind create cluster --name dev

# Verify it's running
kubectl cluster-info --context kind-dev
kubectl get nodes

Your First Deployment

Let's deploy a simple Nginx application. Instead of using imperative commands, we'll write declarative YAML — the Kubernetes way:

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

Tip

Always set resource requests and limits on your containers. Without them, a single noisy pod can starve the entire node of resources.

bash
# Apply the manifest
kubectl apply -f deployment.yaml

# Watch pods come up
kubectl get pods -w

# Check rollout status
kubectl rollout status deployment/nginx-app

Exposing with a Service

A Deployment on its own is not reachable. We need a Service to assign a stable IP and DNS name, and to load balance traffic across the pods:

yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx        # matches our Deployment's pod labels
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP     # internal only; use LoadBalancer for cloud

Adding an Ingress Layer

For HTTP routing, deploy an Ingress controller (nginx-ingress is the most common) and then define routing rules:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myapp.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-svc
                port:
                  number: 80

Scaling and Self-Healing

One of Kubernetes' superpowers is automatic reconciliation. If a node dies or a pod crashes, the control plane reschedules it. Scaling is a one-liner:

bash
# Scale manually
kubectl scale deployment nginx-app --replicas=5

# Enable Horizontal Pod Autoscaler (HPA)
kubectl autoscale deployment nginx-app \
  --cpu-percent=60 \
  --min=3 \
  --max=10

Warning

HPA requires the metrics-server to be installed in your cluster. Run: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Next Steps

  1. 1Learn Helm for packaging and deploying complex applications
  2. 2Explore NetworkPolicies to restrict pod-to-pod communication
  3. 3Set up RBAC to control who can do what in your cluster
  4. 4Try GitOps workflows with ArgoCD or Flux
  5. 5Dive into StatefulSets for databases and stateful workloads
“

Kubernetes is not about containers — it's about building reliable, self-healing distributed systems. The containers are just the packaging.

— Kelsey Hightower