DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    Join the waitlist
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    Kubernetes & HelmLesson 1 of 15
    Your progress · 0%
    On this page
    1. The problem after containers
    2. Desired state and the control loop
    3. The objects you'll use every day
    4. The parts of a cluster
    5. When you don't need Kubernetes
    ↖ Course roadmap
    Lesson 1 · Introduction

    Kubernetes: what it solves, and when you don't need it

    The problems that appear once you run many containers, how desired state and control loops fix them, the core objects and parts of a cluster, and the honest alternatives.

    25 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 5 complete

    The problem after containers

    On one server, Docker is all you need. docker run starts the app, and if it crashes you restart it. Now picture 30 servers running 200 containers for 15 services, and ask:

    • Which server has room for the next container?
    • A server dies at 3 a.m. Who restarts its containers somewhere else?
    • How do you roll out a new version without downtime, and roll it back when it's bad?
    • Containers move between servers and their IPs change. How does one service find another?
    • Traffic triples on sale day. Who adds copies, and removes them afterwards?

    Doing that by hand or with scripts is a full-time job. Kubernetes is a system that does it for you: you give it a cluster of machines and a description of what should run, and it keeps it running. It grew out of Borg, Google's internal cluster manager, was open-sourced in 2014 and is now looked after by the CNCF.

    Desired state and the control loop

    This is the one idea that makes Kubernetes click. You don't tell it what to do; you tell it what you want, and it works out the steps.

    # web.yaml: "I want three copies of nginx running, always."
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web
      template:
        metadata:
          labels:
            app: web
        spec:
          containers:
            - name: nginx
              image: nginx:1.27
              ports:
                - containerPort: 80
    
    $ kubectl apply -f web.yaml
    deployment.apps/web created
    
    kubectl apply -f web.yaml
    • kubectltalk to a Kubernetes cluster
    • applycreate or update from a file
    • -ffrom this file
    • web.yamla value the command works on

    From then on, controllers run a loop that never stops: look at what's running, compare it with what you declared, and fix the difference. A Pod crashes? Start another. A node disappears? Recreate its Pods elsewhere. You change replicas to 5? Two more appear.

    That's why the same file is your documentation, your deploy and your disaster recovery.

    The objects you'll use every day

    ObjectWhat it is
    ClusterA set of machines Kubernetes manages as one
    NodeOne machine (usually a VM) in the cluster that runs your Pods
    PodThe smallest unit: one or more containers sharing an IP address and storage
    DeploymentKeeps N identical Pods running and rolls out new versions gradually
    ServiceOne stable name and IP in front of a changing set of Pods
    NamespaceA folder for objects, to separate teams or environments in one cluster

    Everything is an object with the same shape: apiVersion, kind, metadata and spec. Learn to read one and you can read them all.

    The parts of a cluster

    kubectl talks to the API server. The control plane decides; the nodes run the Pods.© Diagram: DevOps Academy

    kubectl talks to the API server. The control plane decides; the nodes run the Pods.© Diagram: DevOps Academy

    The control plane is the brain:

    • API server: the front door. kubectl, the other components and your CI all talk to it, and only it.
    • etcd: a key-value store holding every object and its desired state.
    • Scheduler: picks a node for each new Pod, based on free CPU and memory and your rules.
    • Controller manager: runs the control loops, like the one that keeps a Deployment at 3 Pods.

    Worker nodes do the work:

    • kubelet: an agent on each node that starts the Pods it's given and reports their health.
    • kube-proxy: sets up the networking rules that make Services reach the right Pods.
    • Container runtime: usually containerd, which actually runs the containers.

    So kubectl apply means: the API server stores your Deployment in etcd, a controller creates three Pod objects, the scheduler assigns each to a node, and each node's kubelet starts the containers.

    When you don't need Kubernetes

    Kubernetes is powerful, and it's also a lot to run and to learn. Be honest about the job:

    SituationOften a better fit
    One or two services, steady trafficOne VM with Docker Compose
    Containers on AWS without managing a clusterAmazon ECS with Fargate, or App Runner
    Containers on Google Cloud or AzureCloud Run, or Azure Container Apps
    A web app and no ops teamA PaaS such as Render, Fly.io or Heroku
    Mixed workloads, containers and plain binariesHashiCorp Nomad

    Kubernetes earns its cost with many services, several teams, real scaling needs, or the need to run the same way across clouds. Until then, simpler is faster.

    In production, use a managed control plane

    Running etcd and the control plane yourself is hard to get right. Most teams use EKS, GKE or AKS, where the cloud provider runs and upgrades the control plane and you manage the nodes and what runs on them.

    ⌘
    Mini mission

    Watch Kubernetes heal an app

    Prove the control loop to yourself. On a local kind cluster, run three nginx Pods, record their names, kill one, and record the names again. The file should show that one Pod was replaced and three are still running.

    Input: A kind cluster named academyOutput: ~/self-healing.txt
    Reveal one safe solution
    $ kind create cluster --name academy
    $ kubectl create deployment web --image=nginx:1.27 --replicas=3
    $ kubectl rollout status deployment/web
    deployment "web" successfully rolled out
    $ kubectl get pods -l app=web -o name > ~/self-healing.txt
    $ kubectl delete $(head -n 1 ~/self-healing.txt)
    pod "web-7c5d8bf7b-2xk9q" deleted
    $ echo "--- after ---" >> ~/self-healing.txt
    $ kubectl get pods -l app=web -o name >> ~/self-healing.txt
    $ cat ~/self-healing.txt              # your Pod names will differ
    pod/web-7c5d8bf7b-2xk9q
    pod/web-7c5d8bf7b-8hjtm
    pod/web-7c5d8bf7b-qz4wd
    --- after ---
    pod/web-7c5d8bf7b-8hjtm
    pod/web-7c5d8bf7b-qz4wd
    pod/web-7c5d8bf7b-vn5lp
    $ kind delete cluster --name academy
    
    kind create cluster --name academy
    • kindKubernetes in Docker: local clusters
    • createcreate
    • clustera value the command works on
    • --namecluster name
    • academya value the command works on
    kubectl create deployment web --image=nginx:1.27 --replicas=3
    • kubectltalk to a Kubernetes cluster
    • createcreate an object
    • deploymenta value the command works on
    • weba value the command works on
    • --image=nginx:1.27container image
    • --replicas=3how many copies
    kubectl rollout status deployment/web
    • kubectltalk to a Kubernetes cluster
    • rolloutmanage a rollout
    • statusa value the command works on
    • deployment/weba value the command works on
    kubectl get pods -l app=web -o name > ~/self-healing.txt
    • kubectltalk to a Kubernetes cluster
    • getlist objects
    • podsa value the command works on
    • -lonly objects with this label
    • app=weba value the command works on
    • -ooutput format
    • namea value the command works on
    • >write output to a file, replacing it
    • ~/self-healing.txta path
    kubectl delete $(head -n 1 ~/self-healing.txt)
    • kubectltalk to a Kubernetes cluster
    • deletedelete an object
    • $(head -n 1 ~/self-healing.txt)the output of another command
    echo "--- after ---" >> ~/self-healing.txt
    • echoprint text
    • "--- after ---"text, kept together by the quotes
    • >>append output to a file
    • ~/self-healing.txta path
    kubectl get pods -l app=web -o name >> ~/self-healing.txt
    • kubectltalk to a Kubernetes cluster
    • getlist objects
    • podsa value the command works on
    • -lonly objects with this label
    • app=weba value the command works on
    • -ooutput format
    • namea value the command works on
    • >>append output to a file
    • ~/self-healing.txta path
    cat ~/self-healing.txt
    • catprint a file
    • ~/self-healing.txta path
    kind delete cluster --name academy
    • kindKubernetes in Docker: local clusters
    • deletedelete
    • clustera value the command works on
    • --namecluster name
    • academya value the command works on

    The Deployment's controller saw two Pods instead of three and created vn5lp within seconds. Nobody ran a restart command. kubectl create deployment labels the Pods app=web, which is how -l app=web finds them.

    Try it yourself

    0 of 5 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 5

    You told Kubernetes to run 3 replicas. A node dies and takes one Pod with it. What happens?

    Go deeper

    Official reading for this lesson

    • DocsKubernetes overviewKubernetes Docs ↗
    • DocsKubernetes componentsKubernetes Docs ↗
    • DocsDeploymentsKubernetes Docs ↗
    • ToolInstall tools (kubectl, kind, minikube)Kubernetes Docs ↗
    • Guidekind quick startkind ↗
    • ArticleLarge-scale cluster management at Google with BorgGoogle Research ↗
    • GuideKubernetes the hard wayKelsey Hightower ↗

    Or get every quiz answer right and it completes itself.

    Next lesson →Containers refresher