KUBERNETES TUTORIAL

Kubernetes: Deploy your first app (Deployment + pods)

You'll write a minimal Deployment, `kubectl apply` it, watch three pods schedule and become Ready, then open your app in the browser.*

What we're doing

When you hit Start, you're on a clean 3-node Kubernetes cluster (nothing deployed yet). You'll write a short Deployment manifest, apply it, watch the pods come up live, and reach the running app in your browser. The app image is already loaded on the cluster, so your apply comes up in seconds.

Watch the video first, then run these as you read. kubectl is already set up; nothing needs sudo. This is the happy path: write it, apply it, watch it work.

The idea: you describe, Kubernetes builds

You don't start things by hand in Kubernetes. You write down what you want in a YAML file (a Deployment), hand it over with kubectl apply, and Kubernetes makes it real and keeps it that way. That's the whole move.

Step 1: Read the manifest

The provided manifest is already on the box. Open it:

cat ~/web-deployment.yaml
apiVersion: apps/v1          # which API group this object belongs to
kind: Deployment             # what KIND of object to create
metadata:
  name: web                  # the Deployment's name
spec:
  replicas: 3                # how many copies (Pods) to keep running
  selector:
    matchLabels:
      app: web               # "my Pods are the ones labeled app=web"
  template:                  # the BLUEPRINT for each Pod:
    metadata:
      labels:
        app: web             # the label stamped on every Pod
    spec:
      containers:
        - name: hello
          image: nginxdemos/hello:0.4   # the app to run
          ports:
            - containerPort: 80          # the port it listens on

Read it top to bottom:

  • apiVersion + kind, what this is: a Deployment.
  • metadata.name, its name: web.
  • spec.replicas, how many copies you want: 3.
  • spec.template, the blueprint for each Pod, its image (nginxdemos/hello) and port (80).
  • spec.selector, how the Deployment recognises its Pods.

Notice selector.matchLabels.app: web and template.metadata.labels.app: web are the same. That's the link between the Deployment and its Pods. More on that in Step 5.

Step 2: Apply it

kubectl apply -f ~/web-deployment.yaml
deployment.apps/web created

apply means "make the cluster match this file." One line of output, but behind it Kubernetes created three things: the Deployment, a ReplicaSet (which does the counting), and the three Pods. You manage the Deployment; it manages the rest.

Step 3: Watch the pods come up

kubectl get pods -w
NAME                  READY   STATUS              AGE
web-xxxxxxxxxx-aaaaa   0/1     Pending             1s
web-xxxxxxxxxx-aaaaa   0/1     ContainerCreating   2s
web-xxxxxxxxxx-aaaaa   1/1     Running             4s
...

-w means watch, the list stays live. Each Pod climbs the same ladder:

  • Pending, the scheduler is picking a node.
  • ContainerCreating, the kubelet is starting the container (fast here, the image is pre-loaded).
  • Running, the process is up.
  • Ready 1/1, it passed its check and can serve.

Give it a few seconds, then Ctrl+C to stop watching. (Those are the scheduler and kubelet from FUND-002, doing their jobs on your app.)

Step 4: Confirm it

kubectl get deployment web
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    3/3     3            3           30s

READY 3/3, three asked for, three ready. You declared a wish and the cluster made it true. And the pods:

kubectl get pods -o wide

Three web-... pods, Running, spread across the worker nodes (check the NODE column).

Step 5: How the Deployment finds its pods (labels)

A Deployment doesn't track its pods by name (names are random and pods come and go). It tracks them by label. See them:

kubectl get pods --show-labels        # every web pod carries app=web
kubectl get pods -l app=web           # select pods by that label (what the Deployment does)

-l app=web means "pods with this label," and you get your three. That shared app=web is the string tying the Deployment to its pods, which is exactly why the selector and the template label in the manifest must match. If they didn't, the Deployment couldn't find its own pods, and Kubernetes would reject the file.

Step 6: See it live in the browser

The pods run on an internal cluster network your browser can't reach. Open a quick tunnel with port-forward:

kubectl port-forward deployment/web 8080:80

This forwards port 8080 on this box straight into a web pod's port 80. Leave it running. Now add port 8080 in the environment and open it in your browser.

You'll see a "Hello World" page that prints the Server name, which is the pod's name. That's the proof: your app is real and serving, and there really are separate copies of it. Stop the forward with Ctrl+C when done.

port-forward is a developer's quick way to reach a pod. The proper way to expose an app (a Service) comes in a later tutorial; you don't need it to see your work here.

What you just did

Object What it is
Deployment (web) your declaration: "keep 3 of this image running"
ReplicaSet created by the Deployment; keeps the count at 3
Pods (x3) created by the ReplicaSet; run your container

One file, one apply, three running copies of your app.

Cheat sheet

cat ~/web-deployment.yaml                       # the manifest
kubectl apply -f ~/web-deployment.yaml          # create it
kubectl get pods -w                             # watch Pending -> Running -> Ready
kubectl get deployment web                      # READY 3/3
kubectl get pods -o wide                         # the pods + their nodes
kubectl get pods -l app=web                     # select pods by label
kubectl port-forward deployment/web 8080:80     # then open http://VM:8080

The one thing to remember: you describe what you want in a Deployment file, kubectl apply it, and Kubernetes builds and keeps three running pods. Write it, apply it, watch it run.

Next tutorial: organising your resources with namespaces.


What's next

Just hit Start and go try this out in a live environment !

Start KUBERNETES
Spec 4 CPU / 12 GiB ·Disk 20 GiB ·Lifetime 7 days
Up next in Apache Airflow Mastery Chapter 3 of 5

DAG Patterns & Best Practices

Continue