Deploying Your First App in Kubernetes
The complete journey from a program on your laptop to a running, self-healing, updatable service in a cluster, explained one small step at a time from zero.
Imagine you have baked the best cake of your life at home. Your friends love it, and now you want to sell it in a busy shopping street. You cannot just carry it there in your hands and hope for the best. You need a sturdy box so it arrives in one piece, a shop unit with your name on the door, a few helpers so customers are never left waiting, a plan for what to do when someone drops a tray, and a way to change the recipe without closing the shop.
Deploying an application in Kubernetes is exactly that journey. Your program works on your laptop. Now you want it to run somewhere reliable, be reachable by real people, survive crashes, and be updated without downtime. Kubernetes gives you all of that, but its many new words can feel like a wall on the first day.
In this guide we will climb over that wall together. You will learn what each piece is, why it exists, and how to take a tiny web application from your laptop to a running, healthy service. You will also learn how to check on it, update it, scale it, protect it and fix it when something goes wrong. Every new word will be explained the first time it appears.
1The Goal: From “It Works on My Laptop” to “It Works for Everyone”
Before any commands or files, let us be clear about what we are trying to achieve and why a simple approach is not enough.
The old way
In the past, deploying meant renting a computer, logging in, copying your program onto it and starting it. That works for one program on one machine. But problems appear quickly.
- If the program crashes at night, nobody restarts it until someone notices.
- If more customers arrive, one machine is not enough, and adding machines by hand is slow.
- If you update the program, it stops for a moment, and users see errors.
- If the machine breaks, your program is gone until someone builds a new one.
- Every machine is a little different, so “it works on my laptop” often means “it breaks somewhere else”.
The Kubernetes way
Kubernetes is a free, open-source system that runs your programs on a group of computers and keeps them healthy for you. You do not tell it the steps to follow. Instead, you describe the end result you want, such as “run three copies of this program and make them reachable on the network”. Kubernetes then works tirelessly to make reality match your description, and to keep it that way when things break.
Old-style deployment is like cooking dinner yourself every night: you do each step, and if you are sick, nobody eats. Kubernetes is like hiring a restaurant manager. You say, “I want three waiters on the floor at all times, and the menu on every table by six.” If a waiter falls ill, the manager brings in another one without being asked.
The mindset shift is this: you declare what you want, and Kubernetes keeps making it true. You describe the destination, and the cluster handles the driving.
2Building Blocks You Need First
Ten small ideas carry this whole guide. Learn them once and every later step will make sense.
Container image
A sealed, ready-to-run package containing your program and everything it needs. Think of it as a frozen meal: the same every time you heat it up.
Container
A running copy of an image. One image can produce many containers, like one recipe producing many cakes.
Registry
An online warehouse for images. You upload your image once, and the cluster downloads it whenever it needs a copy.
Cluster and node
A cluster is a group of computers managed together. Each computer in it is a node. Your containers run on the nodes.
Pod
The smallest thing Kubernetes runs. A small wrapper around one container, or a few tightly linked ones. Pods are disposable and replaceable.
Deployment
A manager for Pods. You tell it how many copies you want and which image to use, and it creates them, replaces broken ones and rolls out new versions.
Service
A permanent address and name in front of a changing group of Pods, which shares incoming visitors between them.
Namespace
A named room inside a cluster that keeps one project’s things apart from another’s.
Manifest
A text file that describes what you want Kubernetes to create. It is written in a simple, readable format called YAML.
kubectl
The command-line tool you use to talk to a cluster. It reads your manifests and sends them to the cluster.
Picture a pizza chain. The image is the sealed pizza kit. The registry is the central kitchen that stores the kits. The Pod is one oven cooking one pizza. The Deployment is the shop manager who says “keep three ovens running”. The Service is the shop’s front counter with one phone number, no matter which oven cooks your order.
3What You Need Before You Start
Only four things are required. None of them are hard to get, and most are free.
A small application
Any program that answers requests over the network will do. A simple web page or a tiny API is perfect. It should listen on a port, such as 8080, and print its messages to the screen instead of a private file.
A tool to build container images
Docker is the best-known tool. Alternatives such as Podman and Buildah do the same job. Many cloud services can also build images for you from your code.
A Kubernetes cluster
You do not need a big one to learn. Options range from a tiny cluster on your laptop to a managed cluster in the cloud, as shown in the table below.
The kubectl tool
Installed on your computer and pointed at your cluster. Most cluster tools set up the connection for you and store it in a small settings file.
Choosing a cluster to learn on
| Option | Where it runs | Good for | Cost |
|---|---|---|---|
| minikube | Your laptop, in a small virtual machine or container | Learning and experiments | Free |
| kind | Your laptop, using containers as nodes | Learning and testing pipelines | Free |
| Docker Desktop cluster | Your laptop, switched on with one setting | The very easiest start | Free for personal use |
| k3s and k3d | Laptop, small servers or edge devices | Lightweight clusters | Free |
| Managed cloud (EKS, GKE, AKS) | Amazon, Google or Microsoft data centers | Real internet-facing apps | Paid, with some trial credits |
For your first app, choose a cluster on your own laptop. It costs nothing, you cannot break anything important, and you can delete it and start again whenever you like.
4The Journey at a Glance
Here is the whole trip in one picture. Each step will get its own chapter, but it helps to see where we are going.
flowchart LR
CODE["Your code on your laptop"] --> BUILD["Build a container image"]
BUILD --> REG["Image Registry"]
YOU["You apply a manifest"] --> API
subgraph CL["Kubernetes Cluster"]
API["API Server"] --> DEP["Deployment"]
DEP --> RS["ReplicaSet"]
RS --> P1["Pod 1"]
RS --> P2["Pod 2"]
RS --> P3["Pod 3"]
SVC["Service"] --> P1
SVC --> P2
SVC --> P3
end
REG -. images are pulled .-> P1
REG -. images are pulled .-> P2
REG -. images are pulled .-> P3
USERS["Users"] --> SVC
The nine steps
Package the app
Build a container image that holds your program.
Publish the image
Upload it to a registry the cluster can reach.
Describe what you want
Write manifests, the text files that state your wishes.
Create the Deployment
Tell Kubernetes which image to run and how many copies.
Create the Service
Give the Pods a stable address for visitors.
Apply and watch
Send the manifests and watch Kubernetes do the work.
Check health
Read statuses, events and logs to confirm all is well.
Update safely
Roll out a new version with no downtime, and roll back if needed.
Scale and self-heal
Add more copies and watch broken ones replace themselves.
5Step 1: Package Your App as a Container Image
Kubernetes does not run raw programs. It runs container images. So the first job is turning your app into one.
The recipe file
An image is built from a short text file, most often called a Dockerfile. It is a recipe with a few lines, each doing one job.
- Start from a base. Choose a ready-made image that already contains the language or system your app needs, such as one with the right version of your programming language.
- Copy in your code. Place your program files inside the image.
- Install what it needs. Add libraries or packages your program depends on.
- Say how to start it. Name the command that runs when a container begins, and note which port it listens on.
Then you ask your build tool to follow the recipe. It produces an image and stores it on your computer, ready to be tested.
Names and tags
Every image has a name and a tag, which is a label for its version, such as “1.0” or “2.3”. Together they look like “my-shop-web:1.0”. Tags are how you tell versions apart, so pick clear ones. Avoid the tag called “latest” for real work, because it means different things on different days and makes it impossible to know exactly what is running.
Making the image small and safe
- Use small base images. Less software inside means faster downloads and fewer things that can be attacked.
- Use multi-stage builds. Build your program in one stage, then copy only the finished result into a small final image, leaving compilers and tools behind.
- Do not include secrets. Passwords and keys must never be baked into an image, since anyone with the image can read them.
- Run as a normal user. Tell the image to run your program as a non-administrator user.
- Print logs to the screen. Write messages to standard output so that Kubernetes can collect them.
Building an image is like packing a lunch box. You choose a box (the base image), put in your food (your code), add cutlery (dependencies), and stick a label on the lid saying what is inside and how to eat it (the start command). A neat, small lunch box travels easily. A giant suitcase full of things you never need is slow and awkward to carry.
Test your image on your own computer first by running it as a container. If it does not work there, it will not work in Kubernetes either, and finding the problem on your laptop is far easier.
6Step 2: Publish the Image to a Registry
The nodes in your cluster need to download your image. A registry is the shared place where they find it.
Your image currently lives only on your laptop. The cluster’s nodes cannot see your laptop’s storage. So you upload, or push, the image to a registry, and later the nodes pull it down when they need to start a container.
| Registry | Run by | Notes |
|---|---|---|
| Docker Hub | Docker | The best-known public registry. Anonymous downloads are limited in number, so heavy use needs an account. |
| GitHub Container Registry | GitHub | Convenient if your code is already on GitHub. |
| Amazon ECR | Amazon | Fits neatly with clusters on Amazon. |
| Google Artifact Registry | Fits neatly with clusters on Google Cloud. | |
| Azure Container Registry | Microsoft | Fits neatly with clusters on Azure. |
Public or private?
A public image can be downloaded by anyone, so the cluster needs no special permission. A private image needs credentials. In Kubernetes you store those credentials in a special object and tell your Pods to use it when they pull. Real company code should almost always be in a private registry.
A shortcut for laptop clusters
Local tools such as minikube and kind can load an image straight from your computer into the cluster, skipping the registry. This is a handy shortcut while learning, but it does not exist on real clusters, so it is worth learning the registry route early.
Pushing an image is like posting your packaged product to a central warehouse. Any shop in the chain can then order a copy from the warehouse. If you left the product on your kitchen table at home, no shop could ever sell it.
The most common first-day failure is a Pod that cannot download its image. The name or tag may be misspelled, the image may be private without credentials, or the registry may be limiting free downloads. We will learn how to spot this shortly.
7Step 3: Understand Manifests, the “What I Want” Files
A manifest is how you talk to Kubernetes. Once you understand its four-part shape, every manifest looks familiar.
Declarative: describe the result
There are two ways to give orders. In the imperative way you say each action: “start this”, “add one more”, “stop that”. In the declarative way you write the final picture you want, and hand it over. Kubernetes compares your picture with reality and changes whatever is different. Professionals prefer the declarative way, because the picture can be saved, reviewed and repeated.
The four parts of every manifest
API version
Says which version of Kubernetes’ vocabulary the file uses. Deployments and Services each have a standard value that you copy from the documentation.
Kind
Says what type of object you are describing: a Deployment, a Service, a ConfigMap and so on.
Metadata
The name of the object, the namespace it belongs to, and any labels you want to stick on it.
Spec
The heart of the file: the detailed description of what you want. Its contents differ for each kind.
Labels: the sticky notes that connect things
A label is a small tag with a name and a value, like “app” with the value “shop-web”. Kubernetes uses labels to connect objects. A Deployment says “manage the Pods that carry this label”. A Service says “send visitors to the Pods that carry this label”. Labels are the glue of Kubernetes, and a wrong label is the number one cause of “my Service reaches nothing”.
A manifest is like a work order handed to a builder. The top of the form says what type of job it is and what to call it. The body lists the details. Colored stickers on the pipes (labels) let different tradespeople find the pipes they are supposed to work on.
Keep your manifests in a folder in version control, next to your code. Then you can see who changed what, roll back mistakes, and rebuild everything on a fresh cluster in seconds.
8Step 4: The Deployment
The Deployment is the star of your first app. It runs your Pods, keeps them alive and manages updates.
flowchart TB
DEP["Deployment: wants 3 copies of image v1"] --> RS1["ReplicaSet for version 1"]
RS1 --> A["Pod"]
RS1 --> B["Pod"]
RS1 --> C["Pod"]
DEP -. keeps an old copy for rollback .-> RS0["Older ReplicaSet with 0 Pods"]
Why not create Pods directly?
You can create a bare Pod, but if it dies, nobody brings it back, and if its node fails, it is gone. A Deployment fixes both. It hires a middle manager called a ReplicaSet, whose only job is to keep the exact number of Pods you asked for. When you update the app, the Deployment creates a new ReplicaSet for the new version and gradually hands work over, keeping the old one around in case you need to go back.
What you write inside a Deployment
Replicas
How many identical copies of your Pod should run. Start with two or three so the app survives the loss of one.
Selector
The label rule that says which Pods belong to this Deployment. It must match the labels in the Pod template.
Pod template
A blueprint for every Pod the Deployment creates: its labels, its containers and their settings. Change the template and a new version rolls out.
Image and port
The exact image and tag to run, and the port your app listens on inside the container.
Resource requests and limits
A request is the minimum memory and processing power your Pod needs, used to choose a node. A limit is the most it may use.
Probes
Small checks Kubernetes runs on your container. A readiness probe says “am I ready for visitors?”. A liveness probe says “am I still alive, or should I be restarted?”.
A Deployment is a staffing plan for a shop. The plan says “three cashiers on shift, all trained with this uniform and this checklist”. The readiness probe is the manager checking that a new cashier has logged into the till before letting customers queue at their lane. The liveness probe is checking that a cashier has not silently fainted at their desk.
The selector in a Deployment cannot be changed after creation, and it must match the Pod template’s labels exactly. A mismatch is rejected outright. Choose your label names carefully at the start.
9Step 5: The Service, Your App’s Front Door
Pods come and go and their addresses change. A Service gives visitors one steady place to knock.
The problem a Service solves
Every Pod gets its own private address, but that address disappears with the Pod. If your Deployment replaces a Pod, the new one has a different address. Visitors and other apps cannot keep up with such changes. A Service provides a fixed name and a fixed address, watches which Pods currently match its label rule, and shares incoming traffic among them.
Choosing the type
| Type | Who can reach it | Best for |
|---|---|---|
| ClusterIP (default) | Only things inside the cluster | Internal apps, databases, back-end services |
| NodePort | Anyone who can reach a node, on a high port number between 30000 and 32767 | Quick tests on a laptop cluster |
| LoadBalancer | The internet or a private network, through a cloud load balancer | Public apps on cloud clusters |
Ports, explained simply
A Service has a port, which is the door number visitors knock on, and a target port, which is the door number of your container. They can differ. For example, visitors may use the normal web port 80 while your app listens on 8080 inside. The Service translates between them.
Names inside the cluster
Kubernetes also runs a small phone book, called DNS. Every Service gets a name in it. Other apps in the same namespace can simply use the Service’s name to reach it, without ever knowing an address. That is how your front-end will find your back-end later.
Trying it out safely
To peek at your app from your laptop without exposing it, you can use port-forwarding, a feature that creates a temporary private tunnel from a port on your computer to your Pod or Service. It is perfect for a first look and is closed the moment you stop it.
A Service is the phone number printed on your shop’s sign. The staff behind the counter change from hour to hour, but the number stays the same, and the phone system routes each call to a free person. Port-forwarding is you walking into the back door with a staff pass to check that the phones ring properly, before the sign goes up.
For websites with many pages and domains, teams usually add an Ingress or a Gateway in front of Services. For a first app, a Service alone is enough.
10Step 6: Apply the Manifests and Watch the Magic
The moment of truth. Let us follow exactly what happens after you hand your manifests to the cluster.
sequenceDiagram
participant You
participant API as API Server
participant DC as Deployment Controller
participant SCH as Scheduler
participant KUB as Kubelet
participant REG as Registry
You->>API: Apply the manifest
API-->>DC: New Deployment saved
DC->>API: Create ReplicaSet and Pods
API-->>SCH: Pods need a node
SCH->>API: Assign each Pod to a node
API-->>KUB: Pod assigned to your node
KUB->>REG: Pull the image
REG-->>KUB: Image downloaded
KUB->>KUB: Start the container
KUB-->>API: Pod is running and ready
You apply the files
kubectl reads your manifests and sends them to the API server, the cluster’s front desk. The desk checks that you are allowed to do this and that the files make sense, then stores your wishes in the cluster’s database.
The Deployment controller notices
A caretaker program sees the new Deployment and creates a ReplicaSet for it. The ReplicaSet in turn creates the requested number of Pod records. At this point the Pods exist on paper, but they have no home yet.
The scheduler picks a node for each Pod
It looks at the free memory and processing power of every node and at the requests in your Pod template, and assigns each Pod to a node with room.
The kubelet takes over on each node
The kubelet is the local manager on every node. It sees a Pod assigned to it and asks the container runtime to prepare it.
The image is pulled and the container starts
The runtime downloads your image from the registry, if the node does not already have it, and starts the container. This is often the slowest step the first time.
Probes pass and the Pod becomes ready
Once the readiness check succeeds, the Pod is added to the Service’s list. Only now does traffic start to reach it.
The caretakers never stop
From now on, controllers keep comparing what you asked for with what exists. If a Pod dies, they create another. That is the self-healing you came for.
Applying a manifest is like handing a hotel manager a written request for a wedding. The manager assigns staff (controllers), the room planner picks the halls (scheduler), each hall supervisor (kubelet) gets the tables and food (image) delivered, and once everything is ready, guests are finally let in (readiness). You wrote one page; a whole team carried it out.
11Step 7: Check That Everything Is Healthy
After applying, do not just hope. Learn to read the signs. Three questions solve almost every problem.
The three questions
What is the status?
List the Pods and read the status and ready columns. This tells you which stage each Pod is at.
What did Kubernetes say?
Describe the Pod and read its events at the bottom. Events explain scheduling, image pulling and probe failures in words.
What did the app say?
Read the container logs. They show the messages your program printed, including crashes and errors.
Reading Pod statuses
| Status | Meaning | What to do |
|---|---|---|
| Pending | No node has been chosen yet | Read the events. Often no node has enough free memory or processing power, or a rule cannot be satisfied. |
| ContainerCreating | The node is preparing the container, often downloading the image | Wait a little. If it lasts too long, read the events. |
| ErrImagePull or ImagePullBackOff | The image could not be downloaded | Check the image name and tag, and registry credentials. |
| CrashLoopBackOff | The container starts, crashes, and keeps repeating, with longer pauses each time | Read the logs of the previous run to see why it dies. |
| Running but not ready (0/1) | Alive, but the readiness check is failing | Check that the probe’s path and port match what your app serves. |
| Running and ready (1/1) | All is well | Test the Service. |
| OOMKilled | The container used more memory than its limit | Raise the limit or fix the memory hunger. |
Checking your first deployment is like a doctor’s routine. First glance at the chart (status). Then read the nurse’s notes (events). Finally, listen to what the patient says about how they feel (logs). Together these three sources almost always point to the cause.
If the Service seems to reach nothing, check whether it has any endpoints, the list of Pods it currently sends traffic to. An empty list almost always means the Service’s label rule does not match the Pods’ labels, or no Pod is ready.
12Step 8: Updating Your App With No Downtime
Your app is live. Tomorrow you will change it. Kubernetes can swap versions while visitors keep being served.
The rolling update
To release a new version, you build and push a new image with a new tag, then change the image name in your Deployment and apply it again. Kubernetes notices that the Pod blueprint changed and starts a rolling update. Instead of switching everything at once, it swaps Pods a few at a time.
flowchart LR
S1["Start: 3 Pods on v1"] --> S2["Add 1 Pod on v2 and wait until it is ready"]
S2 --> S3["Remove 1 Pod on v1"]
S3 --> S4["Add another Pod on v2"]
S4 --> S5["Remove another Pod on v1"]
S5 --> S6["Finish: 3 Pods on v2"]
A new ReplicaSet appears
The Deployment creates a second manager for the new version, alongside the old one.
New Pods start, old Pods stay
The new ReplicaSet adds Pods. The old ReplicaSet keeps serving until the new ones prove they are ready through their readiness checks.
Old Pods retire gradually
As each new Pod becomes ready, one old Pod is removed. At every moment, enough Pods are serving visitors.
The old ReplicaSet is kept, empty
When all Pods run the new version, the old ReplicaSet stays with zero Pods. It is a bookmark that lets you go back. By default the last ten are remembered.
Controlling the pace
Two settings decide how bold the update is. Max surge is how many extra Pods may be created above your normal count during the update. Max unavailable is how many Pods may be missing at once. By default each is a quarter of your Pods. A cautious team might allow no missing Pods at all, trading speed for safety.
Going back
If the new version turns out to be bad, you can ask the Deployment to undo the last change. It simply re-activates the previous ReplicaSet and rolls back the same gentle way. You can also view the history of revisions and return to a specific one.
A rolling update is like replacing the cashiers in a busy shop with new ones trained on a new till. You do not send everyone home at once. A new cashier sits at a lane, proves they can serve, and only then does an old cashier leave. If the new system turns out to be faulty, the old cashiers are still on speed dial to come straight back.
Rolling updates rely on honest readiness probes. Without a probe, Kubernetes assumes a Pod is ready the moment it starts, and it may send traffic to a container that is still warming up or has failed to start properly.
13Step 9: Scaling and Self-Healing
Two of the biggest reasons people move to Kubernetes are handling more visitors and surviving failures. Both are one-line experiences.
Scaling by hand
To handle more visitors, raise the replica count in the Deployment. Kubernetes creates the extra Pods, schedules them, and adds them to the Service. To scale down, lower the count and extra Pods are retired gracefully. This can be done in seconds, without touching the app itself.
Scaling automatically
A feature called the Horizontal Pod Autoscaler watches how busy your Pods are and adjusts the replica count for you. For example, it can add Pods when average processor use climbs above a target and remove them when things calm down. It needs a small helper called the metrics server to read usage numbers, and it needs your Pods to declare resource requests so it can calculate a percentage.
Watching self-healing happen
A great first experiment: delete one of your running Pods on purpose. Within a moment, the ReplicaSet notices that the count is below what you asked for, and a fresh Pod appears. Visitors barely notice, since the Service simply stops sending traffic to the removed one and starts using the new one when it is ready.
A Pod crashes
The container is restarted automatically by the kubelet, with growing delays if it keeps failing.
A Pod is deleted
The ReplicaSet creates a replacement immediately to keep the count.
A node dies
After a short wait to be sure, the Pods on that node are recreated on healthy nodes.
An app hangs
The liveness probe fails, and Kubernetes restarts the container.
Manual scaling is like calling in extra staff for a busy Saturday. Automatic scaling is a manager who watches the queue at the door and calls staff in or sends them home on their own. Self-healing is the same manager noticing that a waiter has walked out, and quietly putting a replacement on the floor before customers complain.
Scaling works best for stateless apps, which keep no important data inside the Pod. If your app stores files or sessions in memory, extra copies will not share them. We will look at that next.
14Settings, Secrets and Storage
Real apps need settings, passwords and sometimes data that survives restarts. Kubernetes has a place for each.
ConfigMap
Holds ordinary settings such as the shop’s name, a feature switch or a web address of another service. Pods read it as environment settings or as files, so you can change settings without rebuilding the image.
Secret
Holds passwords, tokens and keys. It works like a ConfigMap but is treated with more care. Note that by default a Secret is only encoded, not truly encrypted, so you should turn on encryption at rest and restrict who can read it.
Persistent Volume
Storage that outlives Pods, for things like databases and uploaded files. A Pod asks for it with a claim, and Kubernetes attaches the real disk.
emptyDir
A scratch folder that lives as long as the Pod does. Good for caches and temporary work, but lost when the Pod is removed.
The golden rule: build once, configure anywhere
The same image should run in testing and in production, with only its settings changing. Never bake environment-specific values or secrets into the image. Put them in ConfigMaps and Secrets and let each environment supply its own.
Start with stateless
For your very first app, choose one that keeps no important data inside itself. It reads from a database or file service elsewhere and can be freely copied, moved and replaced. Stateful software such as databases is possible in Kubernetes, but it needs extra care around storage, identity and backups, so save it for your second or third project.
The image is a uniform that every staff member wears. The ConfigMap is a notice board with today’s specials. The Secret is the locked drawer with the till key. Persistent storage is the warehouse out the back, where stock stays even if the whole shop team changes shift.
15Advantages, Disadvantages and Trade-offs
Kubernetes is powerful, but it is not free of cost. An honest view helps you decide when it is the right tool.
Advantages
- Self-healing: crashed Pods and failed nodes are replaced automatically.
- Rolling updates and easy rollbacks with no downtime.
- Scaling up and down by changing one number, or automatically.
- The same description works on a laptop, in your data center and in any major cloud.
- A huge ecosystem of tools, guides and community help.
- Everything is described in files that can be reviewed and reused.
Disadvantages
- A steep learning curve with many new words and concepts.
- More moving parts than a single server, so more to understand and secure.
- Running your own cluster takes real operational effort.
- Costs can rise quietly through load balancers, disks and idle nodes.
- Overkill for a tiny site that gets ten visitors a day.
- Stateful apps need extra design and care.
The trade-offs behind the choices
Managed versus self-run. A managed cluster from a cloud provider removes most of the operating chores, but costs money and ties you to that provider’s way of doing things. Running your own gives full control and demands full responsibility.
Simple app hosting versus Kubernetes. A basic hosting service can be far easier for a small website. Kubernetes shines when you have several services, need reliable updates, or expect growth.
Speed of learning versus depth. You can deploy a first app in an afternoon using just a Deployment and a Service. Mastering networking, security and storage takes months of practice.
Few big Pods versus many small ones. More, smaller replicas spread risk and scale smoothly, but each carries overhead. Find a balance that fits your app.
16Security: Safe Habits From Day One
It is far easier to build good habits at the beginning than to fix bad ones later. Here are the essentials for your very first app.
Trust your images
Use official or well-known base images, pin exact version tags, and scan images for known weaknesses before deploying. Only pull from registries you trust.
Do not run as the boss
Run containers as a normal user, not as the all-powerful root user, and forbid privilege escalation. If an attacker breaks in, they land in a small room, not the master office.
Lock the filesystem
Make the container’s file system read-only where possible, and drop special powers it does not need.
Protect secrets
Keep passwords in Secrets, not in images or manifests in public repositories. Turn on encryption for Secrets and limit who can read them.
Limit who can do what
Use role-based access control so each person and each program has only the permissions it needs. Never share an administrator login.
Control the network
By default any Pod can talk to any other Pod. Use network policies to allow only the conversations you expect.
Use your own namespace
Put your app in a dedicated namespace instead of the default one, so that permissions, limits and cleanup can be applied to it as a group.
Set safety standards for Pods
Kubernetes has built-in Pod security standards, at levels called privileged, baseline and restricted. You can require a level for a whole namespace so that risky Pods are rejected.
Exposing a Service to the internet before your app is ready for it. A LoadBalancer Service makes your app reachable by the whole world within minutes. Make sure the app has proper sign-in, updated software and limits before you open the door.
Good security is like moving into a new house. You check that the doors lock, you do not leave a spare key under the mat, you give different keys to different family members, and you do not put your valuables in the front window. None of it is difficult, but it is much harder to fix after a break-in.
17Monitoring, Logging and Metrics
A running app that nobody watches is a surprise waiting to happen. A few simple signals make problems visible early.
Logs
What your app says. Read them with the logs command for quick checks, and send them to a central store so they survive Pod replacement. Print to the screen and let the platform collect the messages.
Events
What Kubernetes says about your Pods, such as scheduling, image pulling and probe failures. They are kept only for a short time, so look at them soon after a problem.
Resource use
How much memory and processing power each Pod uses. With the metrics server installed, a simple top command shows this. Compare it with your requests and limits.
Health checks
Probe results tell you whether Pods are ready and alive. Restart counts show containers that keep failing.
Business signals
Request rate, error rate and response time from your app’s point of view. These say how customers experience the service, which is what really matters.
Alarms worth setting
- Pods stuck in Pending, image pull failures or crash loops for more than a few minutes.
- Restart counts rising quickly.
- Fewer ready Pods than the count you asked for.
- Memory use approaching the limit.
- Error rate or response time above your agreed target.
The popular open-source pairing of Prometheus, which collects numbers, and Grafana, which draws dashboards, is a great next step once your first app is running. Many managed clouds also offer built-in dashboards.
18Design Patterns and Anti-patterns
Patterns are solutions that many teams found reliable. Anti-patterns are traps many teams fell into.
Patterns that work
Pattern: Stateless app, state elsewhere
Keep the app free of important local data and store state in a database or object storage. Any copy can then be replaced or added at will.
Pattern: At least two replicas with probes
Run two or more copies with honest readiness and liveness checks. One can fail or update while the others serve.
Pattern: Build once, promote everywhere
Build one image, tag it with a version, and use the same image in testing, staging and production, changing only the configuration.
Pattern: Manifests in version control
Keep all files in a repository. Changes are reviewed like code, and the whole setup can be recreated from scratch.
Pattern: Automated pipeline
A pipeline builds the image, runs tests, pushes it to the registry and updates the Deployment. Humans review; machines deploy.
Pattern: Requests and limits on every container
State what each container needs and the most it may use, so the scheduler places Pods sensibly and no single Pod can starve its neighbors.
Traps to avoid
What it looks like
Creating bare Pods by hand instead of using a Deployment.
Why it hurts
If the Pod or its node fails, nothing brings it back, and you cannot roll out updates smoothly.
Better approach
Always wrap your Pods in a Deployment, or another controller suited to the workload.
What it looks like
Using the “latest” image tag everywhere.
Why it hurts
You cannot tell which version is running, rollbacks do not work reliably, and different nodes may have different copies.
Better approach
Use specific version tags, or better, exact image digests for critical systems.
What it looks like
Running everything in the default namespace, with no limits and administrator rights for all.
Why it hurts
Projects become tangled, mistakes spread widely, and one runaway app can starve the rest.
Better approach
Give each project its own namespace with quotas and narrow permissions.
What it looks like
Editing live objects by hand and never updating the files.
Why it hurts
The cluster drifts away from what is written down, and nobody can recreate it after a disaster.
Better approach
Change the files, review the change, and apply them, so the files always describe reality.
19Best Practices and Common Mistakes
A few habits and a short checklist will save you hours of confusion.
Habits that pay off
- Test the image on your laptop first. Fix problems where they are easiest to see.
- Set readiness and liveness probes. They make updates safe and repairs automatic.
- Set resource requests and limits. Without them, scheduling and autoscaling cannot work well.
- Use clear, consistent labels. Names like app, version and team make everything easier to find and connect.
- Start with two or more replicas. One copy is a single point of failure.
- Log to standard output. Kubernetes and log tools can collect it without extra work.
- Handle shutdown politely. Let your app finish current requests when it is told to stop.
- Keep everything in version control. Files, not memory, are your source of truth.
- Clean up experiments. Delete test namespaces and cloud load balancers you no longer need, since they cost money.
Mistakes beginners make
Labels that do not match
The Service’s label rule and the Pod’s labels differ by a letter, so the Service reaches nothing.
Wrong port
The Service’s target port is not the port your app actually listens on, so connections are refused.
Image cannot be pulled
A typo in the image name or tag, a private registry without credentials, or a rate limit.
App listens only on localhost
The program accepts connections only from inside its own container. It must listen on all addresses so that traffic from the network can reach it.
Probes that do not fit
A readiness check pointing at a page that does not exist, so the Pod never becomes ready. Or a liveness check that is too strict and restarts a healthy app.
Memory limit too low
The container is killed for using more memory than allowed. Watch for the out-of-memory status and give it a sensible limit.
When something is wrong, work from the outside in. Is the Deployment healthy? Are the Pods running and ready? Does the Service have endpoints? Do the labels and ports match? What do the events and logs say? Following this order finds most problems within minutes.
20Real-World and Industry Examples
Here is how this same journey looks in practice for different kinds of teams.
Where Kubernetes comes from
Kubernetes grew out of ideas from Google’s internal systems for running containers at giant scale, and was shared with the world in 2014. It is now looked after by the Cloud Native Computing Foundation, and the project’s own website offers beginner tutorials and a guided walkthrough that follow the same path as this guide.
Learning on a laptop
Most people take their first steps with minikube, kind or the cluster built into Docker Desktop. They deploy a tiny web app, break it on purpose, watch Kubernetes repair it, and delete the cluster when they are done.
A start-up shipping its first product
A small team runs a web front end, an API and a background worker on a managed cluster from Amazon, Google or Microsoft. Each part is a Deployment with two or three replicas, the front end sits behind a LoadBalancer or Ingress, and a pipeline builds and pushes a new image on every approved change.
GitOps in action
Tools such as Argo CD and Flux watch a Git repository containing manifests and keep the cluster in sync with it. Deploying becomes as simple as merging a change, and rolling back means reverting it.
A typical online shop
Picture a store with a product page service, a cart service and a checkout service. Each one is packaged as an image and run by its own Deployment. A shared Ingress sends visitors to the right Service. During a sale, an autoscaler adds product-page Pods within minutes. When a new cart version misbehaves, the team rolls it back in seconds while the rest of the shop keeps running.
Scheduled and one-off work
Not every app is a web server. A nightly report generator runs as a Job or CronJob, which starts a Pod, lets it finish and keeps its logs. The same images, registries and manifests idea apply.
21Frequently Asked Questions
Quick answers to the questions beginners ask most often.
22Summary and Key Takeaways
You began with a cake baked in your own kitchen. Now you know how to open a reliable shop for it.
Key Takeaways
- The idea: You describe the result you want, and Kubernetes keeps making it true, replacing broken parts on its own.
- The journey: Package the app as an image, push it to a registry, describe a Deployment and a Service in manifests, apply them, then check, update, scale and protect the app.
- The key objects: A Deployment manages ReplicaSets, which manage Pods, and a Service gives those Pods one steady address, connected by matching labels.
- Health matters: Readiness and liveness probes, and resource requests and limits, make updates safe, repairs automatic and scheduling sensible.
- Debug in order: Check the status, then the events, then the logs, and always confirm that labels and ports match.
- Updates and rollbacks: Rolling updates replace Pods gradually with no downtime, and a rollback simply brings back the previous version.
- Start safe: Use versioned image tags, run as a normal user, keep secrets out of images, use your own namespace, limit permissions, and begin with a stateless app.