MervCodes

Tech Reviews From A Programmer

Kubernetes Basics for Developers: Deploy Your First App

1 min read

Kubernetes has a reputation for being intimidating. The terminology alone—pods, deployments, services, ingress, control planes—can make a developer want to back away slowly and go write a simple Dockerfile instead. But the truth is that you can deploy your first application to Kubernetes in an afternoon, and once the core mental model clicks, the rest of the ecosystem starts making sense.

This guide is written for developers who already understand containers but have never run a Kubernetes cluster. By the end, you'll have a real app running, exposed, and scalable, plus the vocabulary to keep learning.

Why Developers Should Care About Kubernetes

You might wonder why you need Kubernetes at all when docker run works fine on your laptop. The answer is everything that happens after the happy path. Your container crashes—who restarts it? Traffic spikes—who adds more copies? You ship a new version—how do you roll it out without downtime, and roll it back when it breaks?

Kubernetes (often abbreviated "k8s") is a container orchestrator. It takes your declared desired state—"I want three copies of this app running"—and continuously works to make reality match that declaration. This declarative model is the single most important concept to internalize. You don't tell Kubernetes how to do things step by step; you tell it what you want, and its controllers reconcile the difference.

The Core Objects You Actually Need

Kubernetes has dozens of resource types, but you only need four to be productive on day one.

  • Pod: The smallest deployable unit. A pod wraps one (or occasionally a few tightly-coupled) containers. You rarely create pods directly.
  • Deployment: Manages a set of identical pods. It handles scaling, rolling updates, and self-healing. This is what you'll create most often.
  • Service: A stable network endpoint. Pods are ephemeral and get new IP addresses constantly; a Service gives them a consistent name and load-balances across them.
  • Namespace: A logical partition of the cluster, useful for separating environments or teams.

Think of it this way: you describe a Deployment, the Deployment creates and supervises Pods, and a Service makes those Pods reachable.

Setting Up a Local Cluster

You don't need a cloud account to start. The fastest local options are minikube, kind (Kubernetes in Docker), or the single-node cluster built into Docker Desktop. Let's use minikube.

# Install minikube (macOS example)
brew install minikube

# Start a cluster
minikube start

# Verify it's running
kubectl get nodes

You should see a single node with status Ready. kubectl is the command-line tool you'll use for everything—it talks to the cluster's API server.

If kubectl isn't installed, grab it separately or use minikube kubectl --. A handy habit is aliasing k=kubectl since you'll type it hundreds of times.

Deploying Your First App

Let's deploy a simple web server. We'll use a public image so there's nothing to build. Create a file called deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-web
  template:
    metadata:
      labels:
        app: hello-web
    spec:
      containers:
        - name: hello-web
          image: nginxdemos/hello:plain-text
          ports:
            - containerPort: 80

A few things to notice. The replicas: 3 line says "always keep three pods alive." The selector and template.metadata.labels must match—this is how the Deployment knows which pods it owns. Labels are the glue that holds Kubernetes together.

Apply it:

kubectl apply -f deployment.yaml
kubectl get pods

Within seconds you'll see three pods spinning up. Try deleting one with kubectl delete pod <pod-name>—Kubernetes immediately creates a replacement. That's the reconciliation loop in action, and it's the feature that makes the whole system trustworthy.

Exposing the App with a Service

Your pods are running, but nothing can reach them yet. Create service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: hello-web
spec:
  type: NodePort
  selector:
    app: hello-web
  ports:
    - port: 80
      targetPort: 80

The Service selects pods with the label app: hello-web and load-balances traffic across all three. Apply it and open it:

kubectl apply -f service.yaml
minikube service hello-web

This opens your browser to the running app. Refresh a few times—because requests are distributed across pods, you may see different pod names in the response. You just built a load-balanced, self-healing web service.

Scaling and Updating

Here's where Kubernetes earns its keep. Scaling is one command:

kubectl scale deployment hello-web --replicas=5

Updating to a new image triggers a rolling update—Kubernetes replaces pods gradually so the app stays available:

kubectl set image deployment/hello-web hello-web=nginxdemos/hello:latest
kubectl rollout status deployment/hello-web

If something goes wrong, roll back instantly:

kubectl rollout undo deployment/hello-web

Notice you never manually stopped or started anything. You changed the desired state and let the controllers do the work.

Inspecting and Debugging

When things break—and they will—these commands are your lifeline:

kubectl get pods                 # high-level status
kubectl describe pod <name>      # events, why a pod won't start
kubectl logs <name>             # application output
kubectl logs <name> --previous   # logs from a crashed container
kubectl exec -it <name> -- sh    # shell into a running container

The most common beginner mistakes show up here: an ImagePullBackOff means Kubernetes can't fetch your image (check the name and registry access), and CrashLoopBackOff means your container starts and immediately exits (check the logs).

Practical Advice for Going Further

A few habits will save you pain as you grow beyond this tutorial.

Always set resource requests and limits. Without them, one runaway pod can starve the whole node. Add a resources block specifying CPU and memory so the scheduler can place pods intelligently.

Add health checks. Liveness and readiness probes tell Kubernetes when a pod is healthy and when it's ready to receive traffic. Without a readiness probe, the Service may route requests to a pod that's still booting.

Keep your manifests in version control. Your YAML files are the source of truth. Storing them in Git—and eventually adopting a GitOps tool like Argo CD or Flux—means your cluster state is reproducible and auditable.

Don't store config in your image. Use ConfigMaps for non-sensitive configuration and Secrets for credentials, injecting them as environment variables or mounted files.

Resist the urge to over-engineer early. You don't need a service mesh, custom operators, or multi-cluster federation to ship your first few apps. Master Deployments and Services first.

FAQ

Do I need Kubernetes for a small project? Probably not. If you're running a single container with modest traffic, a managed platform like a PaaS or a single VM is simpler and cheaper. Kubernetes shines when you have multiple services, need high availability, or want consistent deployment workflows across a team.

What's the difference between a Deployment and a Pod? A Pod is a single running instance. A Deployment is a manager that keeps a desired number of identical Pods alive, handles updates, and replaces failures. You almost always create Deployments, not Pods directly.

Is kubectl apply better than kubectl create? Yes, for most workflows. apply is declarative—it creates resources if they don't exist and updates them if they do, based on your YAML. create is imperative and errors if the resource already exists. Stick with apply and keep your manifests in files.

How do I move from minikube to a real cloud cluster? The same manifests work on managed services like GKE, EKS, or AKS. You'll mainly change the Service type from NodePort to LoadBalancer (or add an Ingress) and configure cloud-specific storage and networking. The portability of your YAML is a core benefit of Kubernetes.

What should I learn next? After Deployments and Services, explore Ingress (for HTTP routing and TLS), ConfigMaps and Secrets, persistent volumes for stateful apps, and Helm for packaging. Then look into observability with Prometheus and Grafana.

Wrapping Up

You've now deployed a multi-replica application, exposed it through a load-balanced Service, scaled it, performed a rolling update, and rolled it back—all by declaring desired state rather than issuing manual commands. That declarative, self-healing model is the heart of Kubernetes. Everything more advanced is a variation on the same theme. Keep your manifests in Git, add health checks and resource limits, and build from this foundation one concept at a time.

Sources

Related Articles