{"id":209,"date":"2026-10-18T06:13:58","date_gmt":"2026-10-18T06:13:58","guid":{"rendered":"https:\/\/devdojo.co.in\/?p=209"},"modified":"2026-10-18T06:13:59","modified_gmt":"2026-10-18T06:13:59","slug":"kubernetes-tutorial","status":"publish","type":"post","link":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/","title":{"rendered":"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step"},"content":{"rendered":"\n<div class=\"dd-post\">\n<style>\n.single article:has(.dd-hero) .entry-media{display:none}\n.dd-post{--navy:#0b1020;--blue:#3178c6;--violet:#7c5cff;--ink:#1d2433;--muted:#5b6478;--line:#e3e7f0;line-height:1.75;color:var(--ink)}\n.dd-post h2{margin-top:2.2em;scroll-margin-top:90px}\n.dd-post h3{margin-top:1.6em;scroll-margin-top:90px}\n.dd-post a{color:var(--blue)}\n.dd-post .dd-hero{margin:0 0 1.8em;border-radius:16px;overflow:hidden;background:#0b1020}\n.dd-post .dd-hero svg{display:block;width:100%;height:auto}\n.dd-post .dd-hero .node rect{transition:stroke .25s,fill .25s}\n.dd-post .dd-hero .node:hover rect{stroke:#7c5cff;fill:#1f2752}\n.dd-post .dd-hero .node:hover text{fill:#fff}\n.dd-post pre{background:#0f1430;color:#e6e9f5;padding:18px 20px;border-radius:12px;overflow-x:auto;font-size:14.5px !important;line-height:1.6;border:1px solid #1f2752;margin:1.2em 0}\n.dd-post pre code{font-size:1em !important;background:none;color:inherit;padding:0;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}\n.dd-post :not(pre)>code{background:#eef1fb;color:#3a2fa8;padding:2px 6px;border-radius:5px;font-size:.92em}\n.dd-post .dd-label{display:inline-block;font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#7c5cff;margin-bottom:-6px}\n.dd-post .dd-summary{background:linear-gradient(135deg,#f3f0ff,#eaf2fc);border:1px solid #d9d2ff;border-radius:14px;padding:18px 22px;margin:1.4em 0}\n.dd-post .dd-summary h3{margin:0 0 .4em;font-size:1.1em}\n.dd-post .dd-summary ul{margin:0;padding-left:1.2em}\n.dd-post .dd-toc{border:1px solid var(--line);border-radius:14px;padding:16px 22px;margin:1.4em 0;background:#fafbfe}\n.dd-post .dd-toc strong{display:block;margin-bottom:6px}\n.dd-post .dd-toc ol{margin:0;padding-left:1.3em;columns:2;column-gap:28px}\n.dd-post .dd-toc li{break-inside:avoid}\n.dd-post .dd-tip,.dd-post .dd-note,.dd-post .dd-warn{border-radius:12px;padding:14px 18px;margin:1.3em 0;border-left:5px solid}\n.dd-post .dd-tip{background:#ecf8f1;border-color:#22a06b}\n.dd-post .dd-note{background:#eaf2fc;border-color:#3178c6}\n.dd-post .dd-warn{background:#fff6e8;border-color:#e8a33d}\n.dd-post .dd-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin:1.3em 0}\n.dd-post .dd-card{border:1px solid var(--line);border-radius:14px;padding:14px 16px;background:#fff;box-shadow:0 2px 10px rgba(11,16,32,.05)}\n.dd-post .dd-card b{display:block;color:#3178c6;margin-bottom:4px}\n.dd-post table{width:100%;border-collapse:collapse;margin:1.3em 0;font-size:.95em;display:block;overflow-x:auto}\n.dd-post th,.dd-post td{border:1px solid var(--line);padding:10px 12px;text-align:left;vertical-align:top}\n.dd-post th{background:#0f1430;color:#fff}\n.dd-post tr:nth-child(even) td{background:#f7f8fc}\n.dd-post figure{margin:1.6em 0;text-align:center}\n.dd-post figure svg{max-width:100%;height:auto;border-radius:14px}\n.dd-post figcaption{font-size:.9em;color:var(--muted);margin-top:8px}\n.dd-post details{border:1px solid var(--line);border-radius:12px;padding:12px 16px;margin:10px 0;background:#fff}\n.dd-post details summary{cursor:pointer;font-weight:600}\n.dd-post details[open] summary{color:#3178c6;margin-bottom:6px}\n.dd-post .dd-tabs{border:1px solid var(--line);border-radius:14px;overflow:hidden;margin:1.4em 0;background:#fff}\n.dd-post .dd-tabs input{position:absolute;opacity:0;pointer-events:none}\n.dd-post .dd-tabs .dd-tab-bar{display:flex;flex-wrap:wrap;background:#0f1430}\n.dd-post .dd-tabs label{flex:1;min-width:110px;text-align:center;padding:12px 10px;color:#aab3d1;cursor:pointer;font-weight:600;border-bottom:3px solid transparent}\n.dd-post .dd-tabs label:hover{color:#fff}\n.dd-post .dd-tabs .dd-panel{display:none;padding:6px 18px 14px}\n.dd-post #ddt1:checked~.dd-tab-bar label[for=ddt1],.dd-post #ddt2:checked~.dd-tab-bar label[for=ddt2],.dd-post #ddt3:checked~.dd-tab-bar label[for=ddt3],.dd-post #ddt4:checked~.dd-tab-bar label[for=ddt4]{color:#fff;border-bottom-color:#7c5cff;background:#151b3b}\n.dd-post #ddt1:checked~.dd-panels .p1,.dd-post #ddt2:checked~.dd-panels .p2,.dd-post #ddt3:checked~.dd-panels .p3,.dd-post #ddt4:checked~.dd-panels .p4{display:block}\n.dd-post .dd-cta{background:linear-gradient(135deg,#0b1020,#151b3b);color:#e6e9f5;border-radius:16px;padding:24px 26px;margin:2em 0;text-align:center}\n.dd-post .dd-cta h3{color:#fff;margin:0 0 6px}\n.dd-post .dd-cta a{color:#9db8ff;font-weight:600}\n@media (max-width:640px){.dd-post .dd-toc ol{columns:1}}\n<\/style>\n\n<div class=\"dd-hero\">\n<svg viewBox=\"0 0 1200 520\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-labelledby=\"ddHeroT ddHeroD\">\n<title id=\"ddHeroT\">Kubernetes Tutorial for Beginners<\/title>\n<desc id=\"ddHeroD\">Animated banner showing a laptop sending a Node.js app through a Kubernetes cluster to three running pods.<\/desc>\n<defs>\n<linearGradient id=\"ddBg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#0b1020\"\/><stop offset=\"1\" stop-color=\"#151b3b\"\/><\/linearGradient>\n<linearGradient id=\"ddAcc\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0\" stop-color=\"#3178c6\"\/><stop offset=\"1\" stop-color=\"#7c5cff\"\/><\/linearGradient>\n<radialGradient id=\"ddGlow\" cx=\"0.8\" cy=\"0.2\" r=\"0.6\"><stop offset=\"0\" stop-color=\"#7c5cff\" stop-opacity=\".35\"\/><stop offset=\"1\" stop-color=\"#7c5cff\" stop-opacity=\"0\"\/><\/radialGradient>\n<\/defs>\n<rect x=\"0\" y=\"0\" width=\"1200\" height=\"520\" fill=\"url(#ddBg)\"\/>\n<rect x=\"0\" y=\"0\" width=\"1200\" height=\"520\" fill=\"url(#ddGlow)\"\/>\n<g opacity=\".08\" stroke=\"#9db8ff\"><path d=\"M0 130H1200M0 260H1200M0 390H1200M200 0V520M400 0V520M600 0V520M800 0V520M1000 0V520\"\/><\/g>\n<text x=\"70\" y=\"96\" fill=\"#9db8ff\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"20\" font-weight=\"600\" letter-spacing=\"3\">DEVDOJO \u00b7 DEVOPS<\/text>\n<text x=\"70\" y=\"160\" fill=\"#ffffff\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"52\" font-weight=\"800\">Kubernetes Tutorial<\/text>\n<text x=\"70\" y=\"220\" fill=\"#ffffff\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"52\" font-weight=\"800\">for Beginners<\/text>\n<rect x=\"70\" y=\"244\" width=\"190\" height=\"6\" rx=\"3\" fill=\"url(#ddAcc)\"\/>\n<text x=\"70\" y=\"292\" fill=\"#c9d1ee\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"23\">Run a local cluster, deploy a Node.js app,<\/text>\n<text x=\"70\" y=\"324\" fill=\"#c9d1ee\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"23\">then scale, update and debug it.<\/text>\n<path id=\"ddP1\" d=\"M700 300 C760 300 760 200 830 200\" fill=\"none\" stroke=\"#3178c6\" stroke-width=\"2\" stroke-dasharray=\"6 6\" opacity=\".7\"\/>\n<path id=\"ddP2\" d=\"M700 300 C770 300 780 300 830 300\" fill=\"none\" stroke=\"#3178c6\" stroke-width=\"2\" stroke-dasharray=\"6 6\" opacity=\".7\"\/>\n<path id=\"ddP3\" d=\"M700 300 C760 300 760 400 830 400\" fill=\"none\" stroke=\"#3178c6\" stroke-width=\"2\" stroke-dasharray=\"6 6\" opacity=\".7\"\/>\n<g class=\"node\"><rect x=\"560\" y=\"262\" width=\"140\" height=\"76\" rx=\"14\" fill=\"#151b3b\" stroke=\"#3178c6\" stroke-width=\"2\"\/><text x=\"630\" y=\"296\" text-anchor=\"middle\" fill=\"#c9d1ee\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"17\" font-weight=\"700\">Service<\/text><text x=\"630\" y=\"320\" text-anchor=\"middle\" fill=\"#8f9bc4\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"14\">hello-k8s:80<\/text><\/g>\n<g class=\"node\"><rect x=\"830\" y=\"168\" width=\"250\" height=\"64\" rx=\"14\" fill=\"#151b3b\" stroke=\"#7c5cff\" stroke-width=\"2\"\/><circle cx=\"862\" cy=\"200\" r=\"11\" fill=\"#22c55e\"\/><text x=\"886\" y=\"207\" fill=\"#e6e9f5\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"18\" font-weight=\"600\">Pod 1 \u00b7 Running<\/text><\/g>\n<g class=\"node\"><rect x=\"830\" y=\"268\" width=\"250\" height=\"64\" rx=\"14\" fill=\"#151b3b\" stroke=\"#7c5cff\" stroke-width=\"2\"\/><circle cx=\"862\" cy=\"300\" r=\"11\" fill=\"#22c55e\"\/><text x=\"886\" y=\"307\" fill=\"#e6e9f5\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"18\" font-weight=\"600\">Pod 2 \u00b7 Running<\/text><\/g>\n<g class=\"node\"><rect x=\"830\" y=\"368\" width=\"250\" height=\"64\" rx=\"14\" fill=\"#151b3b\" stroke=\"#7c5cff\" stroke-width=\"2\"\/><circle cx=\"862\" cy=\"400\" r=\"11\" fill=\"#22c55e\"\/><text x=\"886\" y=\"407\" fill=\"#e6e9f5\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"18\" font-weight=\"600\">Pod 3 \u00b7 Running<\/text><\/g>\n<circle r=\"7\" fill=\"#7c5cff\"><animateMotion dur=\"2.6s\" repeatCount=\"indefinite\"><mpath href=\"#ddP1\"\/><\/animateMotion><\/circle>\n<circle r=\"7\" fill=\"#3178c6\"><animateMotion dur=\"2.2s\" begin=\".6s\" repeatCount=\"indefinite\"><mpath href=\"#ddP2\"\/><\/animateMotion><\/circle>\n<circle r=\"7\" fill=\"#7c5cff\"><animateMotion dur=\"2.8s\" begin=\"1.1s\" repeatCount=\"indefinite\"><mpath href=\"#ddP3\"\/><\/animateMotion><\/circle>\n<rect x=\"800\" y=\"130\" width=\"310\" height=\"330\" rx=\"20\" fill=\"none\" stroke=\"#3178c6\" stroke-width=\"1.5\" stroke-dasharray=\"4 8\" opacity=\".55\"\/>\n<text x=\"955\" y=\"118\" text-anchor=\"middle\" fill=\"#8f9bc4\" font-family=\"Segoe UI,Roboto,Arial,sans-serif\" font-size=\"15\" letter-spacing=\"2\">DEPLOYMENT \u00b7 3 REPLICAS<\/text>\n<text x=\"70\" y=\"440\" fill=\"#8f9bc4\" font-family=\"Consolas,Menlo,monospace\" font-size=\"19\">$ kubectl apply -f k8s\/<\/text>\n<text x=\"70\" y=\"472\" fill=\"#22c55e\" font-family=\"Consolas,Menlo,monospace\" font-size=\"19\">deployment.apps\/hello-k8s created<\/text>\n<\/svg>\n<\/div>\n\n<p>If you have built a Docker image and wondered <em>\u201chow do big companies run hundreds of these without breaking things?\u201d<\/em>, the answer is usually Kubernetes. This <strong>Kubernetes tutorial for beginners<\/strong> takes you from zero to a working app: you will create a free local cluster on your laptop, deploy a small Node.js API, open it in your browser, scale it to more copies, ship a new version with zero downtime, and fix the most common errors along the way.<\/p>\n<p>No cloud account, no credit card, and no prior Kubernetes knowledge needed. If you know basic Docker, you are ready.<\/p>\n\n<div class=\"dd-summary\">\n<h3>Quick Summary<\/h3>\n<ul>\n<li><strong>Kubernetes<\/strong> runs your containers for you: it starts them, restarts them when they crash and spreads traffic between copies.<\/li>\n<li>You describe what you want in <strong>YAML files<\/strong> (a Deployment and a Service), and Kubernetes keeps reality matching that description.<\/li>\n<li>We use <strong>kind<\/strong> (Kubernetes in Docker) to get a real cluster on your laptop in about a minute.<\/li>\n<li>Key commands: <code>kubectl apply<\/code>, <code>kubectl get pods<\/code>, <code>kubectl logs<\/code>, <code>kubectl describe<\/code>, <code>kubectl rollout<\/code>.<\/li>\n<li>Most beginner errors (<code>ImagePullBackOff<\/code>, <code>CrashLoopBackOff<\/code>, <code>Pending<\/code>) are solved by reading <code>kubectl describe pod<\/code>.<\/li>\n<\/ul>\n<\/div>\n\n<nav class=\"dd-toc\" aria-label=\"Table of contents\">\n<strong>Table of Contents<\/strong>\n<ol>\n<li><a href=\"#what-is-kubernetes\">What Is Kubernetes?<\/a><\/li>\n<li><a href=\"#key-words\">Key Words You Need to Know<\/a><\/li>\n<li><a href=\"#setup\">Step 1: Install Tools and Create a Cluster<\/a><\/li>\n<li><a href=\"#app\">Step 2: Build the Node.js App Image<\/a><\/li>\n<li><a href=\"#deployment\">Step 3: Write Your First Deployment<\/a><\/li>\n<li><a href=\"#service\">Step 4: Expose the App with a Service<\/a><\/li>\n<li><a href=\"#configmap\">Step 5: Settings with a ConfigMap<\/a><\/li>\n<li><a href=\"#scale-update\">Step 6: Scale, Update and Roll Back<\/a><\/li>\n<li><a href=\"#cheatsheet\">kubectl Cheat Sheet (Interactive)<\/a><\/li>\n<li><a href=\"#errors\">Common Errors and Fixes<\/a><\/li>\n<li><a href=\"#best-practices\">Best Practices<\/a><\/li>\n<li><a href=\"#faq\">FAQ<\/a><\/li>\n<li><a href=\"#conclusion\">Conclusion<\/a><\/li>\n<\/ol>\n<\/nav>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"what-is-kubernetes\">What Is Kubernetes? (Explained Simply)<\/h2>\n<p>Kubernetes (often written <strong>K8s<\/strong> \u2014 \u201cK\u201d, then 8 letters, then \u201cs\u201d) is an open-source system that <strong>runs and manages containers across one or many machines<\/strong>. It was created at Google and is now maintained by the Cloud Native Computing Foundation. The current release at the time of writing is <a href=\"https:\/\/kubernetes.io\/blog\/2026\/08\/26\/kubernetes-v1-37-release\/\" target=\"_blank\" rel=\"noopener\">Kubernetes v1.37<\/a>, but everything in this guide uses stable features that work the same on recent versions.<\/p>\n<p>Think of Kubernetes like the manager of a busy restaurant kitchen. You do not tell each cook what to do every minute. You say <em>\u201cI always want 3 cooks making pizza\u201d<\/em>. If one cook goes home sick, the manager calls a replacement. If it gets busy, you change the number to 5. Kubernetes does exactly this for containers.<\/p>\n\n<div class=\"dd-cards\">\n<div class=\"dd-card\"><b>Self-healing<\/b>A crashed container is restarted automatically. A dead machine\u2019s work moves to a healthy one.<\/div>\n<div class=\"dd-card\"><b>Scaling<\/b>Change one number to go from 3 copies of your app to 30.<\/div>\n<div class=\"dd-card\"><b>Zero-downtime updates<\/b>New versions roll out gradually, and you can roll back with one command.<\/div>\n<div class=\"dd-card\"><b>Load balancing<\/b>A Service spreads incoming requests across all healthy copies.<\/div>\n<\/div>\n\n<p>If you already use Docker Compose (see our <a href=\"https:\/\/devdojo.co.in\/docker-compose-tutorial\/\">Docker Compose tutorial<\/a>), here is the simple difference: Compose runs containers on <strong>one machine<\/strong> and is great for local development. Kubernetes runs containers on <strong>many machines<\/strong> and keeps them healthy in production.<\/p>\n\n<figure>\n<svg viewBox=\"0 0 900 420\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-labelledby=\"ddF1T\">\n<title id=\"ddF1T\">Kubernetes cluster architecture: control plane and worker nodes running pods<\/title>\n<rect width=\"900\" height=\"420\" fill=\"#f7f8fc\"\/>\n<rect x=\"30\" y=\"30\" width=\"250\" height=\"360\" rx=\"16\" fill=\"#0f1430\"\/>\n<text x=\"155\" y=\"64\" text-anchor=\"middle\" fill=\"#fff\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"18\" font-weight=\"700\">Control Plane<\/text>\n<text x=\"155\" y=\"86\" text-anchor=\"middle\" fill=\"#9db8ff\" font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"13\">the \u201cbrain\u201d<\/text>\n<g font-family=\"Segoe UI,Arial,sans-serif\" font-size=\"14\" fill=\"#e6e9f5\">\n<rect x=\"55\" y=\"105\" width=\"200\" height=\"50\" rx=\"10\" fill=\"#151b3b\" stroke=\"#3178c6\"\/><text x=\"155\" y=\"135\" text-anchor=\"middle\">API Server (kubectl talks here)<\/text>\n<rect x=\"55\" y=\"170\" width=\"200\" height=\"50\" rx=\"10\" fill=\"#151b3b\" stroke=\"#3178c6\"\/><text x=\"155\" y=\"200\" text-anchor=\"middle\">etcd (saved desired state)<\/text>\n<rect x=\"55\" y=\"235\" width=\"200\" height=\"50\" rx=\"10\" fill=\"#151b3b\" stroke=\"#3178c6\"\/><text x=\"155\" y=\"265\" text-anchor=\"middle\">Scheduler (picks a node)<\/text>\n<rect x=\"55\" y=\"300\" width=\"200\" height=\"50\" rx=\"10\" fill=\"#151b3b\" stroke=\"#3178c6\"\/><text x=\"155\" y=\"330\" text-anchor=\"middle\">Controllers (fix differences)<\/text>\n<\/g>\n<path d=\"M280 210 H330\" stroke=\"#7c5cff\" stroke-width=\"3\" marker-end=\"url(#ddArr)\"\/>\n<defs><marker id=\"ddArr\" markerWidth=\"10\" markerHeight=\"10\" refX=\"8\" refY=\"5\" orient=\"auto\"><path d=\"M0 0 L10 5 L0 10 z\" fill=\"#7c5cff\"\/><\/marker><\/defs>\n<g font-family=\"Segoe UI,Arial,sans-serif\">\n<rect x=\"340\" y=\"30\" width=\"530\" height=\"170\" rx=\"16\" fill=\"#fff\" stroke=\"#c9d1ee\" stroke-width=\"2\"\/>\n<text x=\"360\" y=\"60\" fill=\"#1d2433\" font-size=\"17\" font-weight=\"700\">Worker Node 1<\/text>\n<text x=\"850\" y=\"60\" text-anchor=\"end\" fill=\"#5b6478\" font-size=\"13\">kubelet + container runtime<\/text>\n<rect x=\"365\" y=\"80\" width=\"150\" height=\"95\" rx=\"12\" fill=\"#eaf2fc\" stroke=\"#3178c6\"\/><text x=\"440\" y=\"115\" text-anchor=\"middle\" font-size=\"15\" font-weight=\"700\" fill=\"#1d2433\">Pod<\/text><rect x=\"385\" y=\"128\" width=\"110\" height=\"32\" rx=\"7\" fill=\"#3178c6\"\/><text x=\"440\" y=\"149\" text-anchor=\"middle\" font-size=\"13\" fill=\"#fff\">container<\/text>\n<rect x=\"530\" y=\"80\" width=\"150\" height=\"95\" rx=\"12\" fill=\"#eaf2fc\" stroke=\"#3178c6\"\/><text x=\"605\" y=\"115\" text-anchor=\"middle\" font-size=\"15\" font-weight=\"700\" fill=\"#1d2433\">Pod<\/text><rect x=\"550\" y=\"128\" width=\"110\" height=\"32\" rx=\"7\" fill=\"#3178c6\"\/><text x=\"605\" y=\"149\" text-anchor=\"middle\" font-size=\"13\" fill=\"#fff\">container<\/text>\n<rect x=\"340\" y=\"220\" width=\"530\" height=\"170\" rx=\"16\" fill=\"#fff\" stroke=\"#c9d1ee\" stroke-width=\"2\"\/>\n<text x=\"360\" y=\"250\" fill=\"#1d2433\" font-size=\"17\" font-weight=\"700\">Worker Node 2<\/text>\n<text x=\"850\" y=\"250\" text-anchor=\"end\" fill=\"#5b6478\" font-size=\"13\">kubelet + container runtime<\/text>\n<rect x=\"365\" y=\"270\" width=\"150\" height=\"95\" rx=\"12\" fill=\"#f3f0ff\" stroke=\"#7c5cff\"\/><text x=\"440\" y=\"305\" text-anchor=\"middle\" font-size=\"15\" font-weight=\"700\" fill=\"#1d2433\">Pod<\/text><rect x=\"385\" y=\"318\" width=\"110\" height=\"32\" rx=\"7\" fill=\"#7c5cff\"\/><text x=\"440\" y=\"339\" text-anchor=\"middle\" font-size=\"13\" fill=\"#fff\">container<\/text>\n<rect x=\"530\" y=\"270\" width=\"150\" height=\"95\" rx=\"12\" fill=\"#f3f0ff\" stroke=\"#7c5cff\"\/><text x=\"605\" y=\"305\" text-anchor=\"middle\" font-size=\"15\" font-weight=\"700\" fill=\"#1d2433\">Pod<\/text><rect x=\"550\" y=\"318\" width=\"110\" height=\"32\" rx=\"7\" fill=\"#7c5cff\"\/><text x=\"605\" y=\"339\" text-anchor=\"middle\" font-size=\"13\" fill=\"#fff\">container<\/text>\n<rect x=\"695\" y=\"270\" width=\"150\" height=\"95\" rx=\"12\" fill=\"#fff\" stroke=\"#c9d1ee\" stroke-dasharray=\"6 5\"\/><text x=\"770\" y=\"322\" text-anchor=\"middle\" font-size=\"13\" fill=\"#5b6478\">room for more<\/text>\n<\/g>\n<\/svg>\n<figcaption>Figure 1: A Kubernetes cluster. The control plane decides <em>what<\/em> should run; worker nodes actually run your Pods.<\/figcaption>\n<\/figure>\n\n<h2 id=\"key-words\">Key Words You Need to Know<\/h2>\n<p>Kubernetes has a lot of vocabulary. For this tutorial you only need six words:<\/p>\n<table>\n<thead><tr><th>Word<\/th><th>What it means in plain English<\/th><\/tr><\/thead>\n<tbody>\n<tr><td><strong>Cluster<\/strong><\/td><td>A group of machines (nodes) managed together by Kubernetes.<\/td><\/tr>\n<tr><td><strong>Node<\/strong><\/td><td>One machine in the cluster (a real server, a cloud VM, or a Docker container with kind).<\/td><\/tr>\n<tr><td><strong>Pod<\/strong><\/td><td>The smallest unit Kubernetes runs. Usually one container plus its network address.<\/td><\/tr>\n<tr><td><strong>Deployment<\/strong><\/td><td>A rule like \u201ckeep 3 Pods of this image running\u201d. It handles restarts and updates.<\/td><\/tr>\n<tr><td><strong>Service<\/strong><\/td><td>A stable name and address that sends traffic to the right Pods, even as Pods come and go.<\/td><\/tr>\n<tr><td><strong>kubectl<\/strong><\/td><td>The command-line tool you use to talk to the cluster (say \u201ccube-control\u201d or \u201ccube-C-T-L\u201d).<\/td><\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dd-note\"><strong>Note:<\/strong> You almost never create Pods directly. You create a <strong>Deployment<\/strong>, and the Deployment creates and replaces Pods for you.<\/div>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"setup\">Step 1: Install Tools and Create a Local Cluster<\/h2>\n<p>You need three tools: <strong>Docker<\/strong> (Docker Desktop on Windows\/macOS, or Docker Engine on Linux), <strong>kubectl<\/strong> and <strong>kind<\/strong>. kind runs each Kubernetes node as a Docker container, so it is light and quick to delete.<\/p>\n<pre><code># macOS (Homebrew)\nbrew install kubectl kind\n\n# Windows (winget) \u2014 run in PowerShell\nwinget install Kubernetes.kubectl\nwinget install Kubernetes.kind\n\n# Linux: follow the \"Installing From Release Binaries\" steps at\n# https:\/\/kind.sigs.k8s.io\/docs\/user\/quick-start\/\n\n# Check that everything works\ndocker version\nkubectl version --client\nkind version<\/code><\/pre>\n<p>Now create a cluster named <code>devdojo<\/code>:<\/p>\n<pre><code>kind create cluster --name devdojo\n\n# kind sets your kubectl \"context\" automatically. Confirm it:\nkubectl cluster-info --context kind-devdojo\nkubectl get nodes<\/code><\/pre>\n<p>You should see something like this:<\/p>\n<pre><code>NAME                    STATUS   ROLES           AGE   VERSION\ndevdojo-control-plane   Ready    control-plane   45s   v1.3x.x<\/code><\/pre>\n<div class=\"dd-tip\"><strong>Tip:<\/strong> Your exact version number depends on your kind version. That is fine \u2014 every command in this guide works on current Kubernetes releases. See the official <a href=\"https:\/\/kind.sigs.k8s.io\/docs\/user\/quick-start\/\" target=\"_blank\" rel=\"noopener\">kind quick start<\/a> for more options.<\/div>\n\n<h2 id=\"app\">Step 2: Build the Node.js App Image<\/h2>\n<p>Create a folder called <code>hello-k8s<\/code> with a tiny API. It uses only Node\u2019s built-in modules, so there is nothing to <code>npm install<\/code>. It returns the Pod\u2019s name, which lets you <em>see<\/em> load balancing later.<\/p>\n<pre><code>\/\/ server.js\nconst http = require('node:http');\nconst os = require('node:os');\n\nconst PORT = process.env.PORT || 3000;\nconst GREETING = process.env.GREETING || 'Hello from Kubernetes';\nconst VERSION = '1.0';\n\nconst server = http.createServer((req, res) =&gt; {\n  \/\/ Health check endpoint used by Kubernetes probes\n  if (req.url === '\/healthz') {\n    res.writeHead(200, { 'Content-Type': 'text\/plain' });\n    return res.end('ok');\n  }\n\n  res.writeHead(200, { 'Content-Type': 'application\/json' });\n  res.end(JSON.stringify({\n    message: GREETING,\n    version: VERSION,\n    pod: os.hostname() \/\/ each Pod has its own hostname\n  }));\n});\n\nserver.listen(PORT, () =&gt; console.log(`Listening on port ${PORT}`));\n\n\/\/ Kubernetes sends SIGTERM before stopping a Pod: finish requests, then exit\nprocess.on('SIGTERM', () =&gt; {\n  console.log('SIGTERM received, shutting down');\n  server.close(() =&gt; process.exit(0));\n});<\/code><\/pre>\n<pre><code># Dockerfile\nFROM node:24-alpine\nWORKDIR \/app\nCOPY server.js .\nENV NODE_ENV=production\nEXPOSE 3000\nUSER node\nCMD [\"node\", \"server.js\"]<\/code><\/pre>\n<p>Build the image and load it into the kind cluster. This \u201cload\u201d step is important: kind nodes cannot see images on your laptop until you copy them in.<\/p>\n<pre><code>docker build -t hello-k8s:1.0 .\nkind load docker-image hello-k8s:1.0 --name devdojo<\/code><\/pre>\n<div class=\"dd-warn\"><strong>Watch out:<\/strong> Always use a real tag like <code>1.0<\/code>, not <code>latest<\/code>. With the <code>latest<\/code> tag, Kubernetes tries to pull the image from Docker Hub every time, which fails for a local-only image and gives you <code>ImagePullBackOff<\/code>.<\/div>\n\n<h2 id=\"deployment\">Step 3: Write Your First Deployment<\/h2>\n<p>Kubernetes is <strong>declarative<\/strong>: you write down the result you want, not the steps. Create a folder <code>k8s\/<\/code> and add this file:<\/p>\n<pre><code># k8s\/deployment.yaml\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: hello-k8s\n  labels:\n    app: hello-k8s\nspec:\n  replicas: 3                  # keep 3 Pods running at all times\n  selector:\n    matchLabels:\n      app: hello-k8s           # manage Pods that have this label\n  template:                    # the blueprint for each Pod\n    metadata:\n      labels:\n        app: hello-k8s         # must match the selector above\n    spec:\n      containers:\n        - name: web\n          image: hello-k8s:1.0\n          imagePullPolicy: IfNotPresent\n          ports:\n            - containerPort: 3000\n          resources:\n            requests:          # what the Pod needs to be scheduled\n              cpu: \"100m\"      # 0.1 of a CPU core\n              memory: \"64Mi\"\n            limits:\n              memory: \"128Mi\"  # killed if it uses more than this\n          readinessProbe:      # \"ready to receive traffic?\"\n            httpGet:\n              path: \/healthz\n              port: 3000\n            initialDelaySeconds: 2\n            periodSeconds: 5\n          livenessProbe:       # \"still alive, or should I restart it?\"\n            httpGet:\n              path: \/healthz\n              port: 3000\n            initialDelaySeconds: 5\n            periodSeconds: 10<\/code><\/pre>\n<p>Apply it and watch the Pods start:<\/p>\n<pre><code>kubectl apply -f k8s\/deployment.yaml\nkubectl get pods -w        # -w = watch; press Ctrl+C to stop<\/code><\/pre>\n<pre><code>NAME                         READY   STATUS    RESTARTS   AGE\nhello-k8s-6d9f7c8b5d-4xk2p   1\/1     Running   0          12s\nhello-k8s-6d9f7c8b5d-9mzqt   1\/1     Running   0          12s\nhello-k8s-6d9f7c8b5d-tr7wl   1\/1     Running   0          12s<\/code><\/pre>\n<p>Now try the self-healing magic. Delete one Pod and immediately list them again:<\/p>\n<pre><code>kubectl delete pod hello-k8s-6d9f7c8b5d-4xk2p   # use one of YOUR pod names\nkubectl get pods<\/code><\/pre>\n<p>A brand-new Pod appears within seconds, because the Deployment says \u201c3\u201d, and Kubernetes sees only 2. This loop \u2014 <strong>compare desired state to real state, then fix the difference<\/strong> \u2014 is the heart of Kubernetes.<\/p>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"service\">Step 4: Expose the App with a Service<\/h2>\n<p>Pods get new IP addresses every time they are replaced, so you should never call a Pod directly. A <strong>Service<\/strong> gives your app one stable name and spreads requests over all <em>ready<\/em> Pods that match its label selector.<\/p>\n<pre><code># k8s\/service.yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: hello-k8s\nspec:\n  type: ClusterIP          # reachable inside the cluster\n  selector:\n    app: hello-k8s         # send traffic to Pods with this label\n  ports:\n    - port: 80             # port of the Service\n      targetPort: 3000     # port the container listens on<\/code><\/pre>\n<pre><code>kubectl apply -f k8s\/service.yaml\nkubectl get service hello-k8s\n\n# Forward a port from your laptop to the Service\nkubectl port-forward service\/hello-k8s 8080:80<\/code><\/pre>\n<p>Open <a href=\"http:\/\/localhost:8080\" rel=\"nofollow\">http:\/\/localhost:8080<\/a> or, in a second terminal, run <code>curl http:\/\/localhost:8080<\/code>:<\/p>\n<pre><code>{\"message\":\"Hello from Kubernetes\",\"version\":\"1.0\",\"pod\":\"hello-k8s-6d9f7c8b5d-9mzqt\"}<\/code><\/pre>\n<div class=\"dd-note\"><strong>Why does the Pod name not change on every refresh?<\/strong> <code>kubectl port-forward<\/code> picks <em>one<\/em> Pod behind the Service and sticks to it. Real traffic inside the cluster is spread across all Pods. To see that, run a temporary Pod and call the Service by name:\n<pre><code>kubectl run curl --rm -it --image=curlimages\/curl --restart=Never -- \\\n  sh -c 'for i in 1 2 3 4 5 6; do curl -s http:\/\/hello-k8s; echo; done'<\/code><\/pre>\nYou will see different Pod names in the answers. Notice that the URL is just <code>http:\/\/hello-k8s<\/code> \u2014 Kubernetes has built-in DNS for Service names.<\/div>\n\n<figure>\n<svg viewBox=\"0 0 900 340\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" role=\"img\" aria-labelledby=\"ddF2T\">\n<title id=\"ddF2T\">Request flow: client to Service to three Pods selected by label<\/title>\n<rect width=\"900\" height=\"340\" fill=\"#0f1430\"\/>\n<defs><marker id=\"ddArr2\" markerWidth=\"10\" markerHeight=\"10\" refX=\"8\" refY=\"5\" orient=\"auto\"><path d=\"M0 0 L10 5 L0 10 z\" fill=\"#9db8ff\"\/><\/marker><\/defs>\n<g font-family=\"Segoe UI,Arial,sans-serif\">\n<rect x=\"30\" y=\"135\" width=\"160\" height=\"70\" rx=\"14\" fill=\"#151b3b\" stroke=\"#9db8ff\"\/>\n<text x=\"110\" y=\"166\" text-anchor=\"middle\" fill=\"#fff\" font-size=\"16\" font-weight=\"700\">Client<\/text>\n<text x=\"110\" y=\"188\" text-anchor=\"middle\" fill=\"#9db8ff\" font-size=\"13\">curl \/ browser<\/text>\n<path d=\"M190 170 H290\" stroke=\"#9db8ff\" stroke-width=\"2.5\" marker-end=\"url(#ddArr2)\"\/>\n<rect x=\"300\" y=\"115\" width=\"220\" height=\"110\" rx=\"16\" fill=\"#151b3b\" stroke=\"#3178c6\" stroke-width=\"2.5\"\/>\n<text x=\"410\" y=\"150\" text-anchor=\"middle\" fill=\"#fff\" font-size=\"18\" font-weight=\"700\">Service<\/text>\n<text x=\"410\" y=\"174\" text-anchor=\"middle\" fill=\"#9db8ff\" font-size=\"14\">hello-k8s : 80<\/text>\n<text x=\"410\" y=\"200\" text-anchor=\"middle\" fill=\"#c9d1ee\" font-size=\"13\">selector: app=hello-k8s<\/text>\n<path d=\"M520 150 C580 150 580 70 640 70\" stroke=\"#9db8ff\" stroke-width=\"2.5\" fill=\"none\" marker-end=\"url(#ddArr2)\"\/>\n<path d=\"M520 170 H640\" stroke=\"#9db8ff\" stroke-width=\"2.5\" marker-end=\"url(#ddArr2)\"\/>\n<path d=\"M520 190 C580 190 580 270 640 270\" stroke=\"#9db8ff\" stroke-width=\"2.5\" fill=\"none\" marker-end=\"url(#ddArr2)\"\/>\n<rect x=\"650\" y=\"40\" width=\"220\" height=\"60\" rx=\"12\" fill=\"#1f2752\" stroke=\"#7c5cff\"\/>\n<text x=\"760\" y=\"66\" text-anchor=\"middle\" fill=\"#fff\" font-size=\"15\" font-weight=\"600\">Pod \u00b7 app=hello-k8s<\/text>\n<text x=\"760\" y=\"87\" text-anchor=\"middle\" fill=\"#9db8ff\" font-size=\"13\">:3000 \u00b7 ready \u2713<\/text>\n<rect x=\"650\" y=\"140\" width=\"220\" height=\"60\" rx=\"12\" fill=\"#1f2752\" stroke=\"#7c5cff\"\/>\n<text x=\"760\" y=\"166\" text-anchor=\"middle\" fill=\"#fff\" font-size=\"15\" font-weight=\"600\">Pod \u00b7 app=hello-k8s<\/text>\n<text x=\"760\" y=\"187\" text-anchor=\"middle\" fill=\"#9db8ff\" font-size=\"13\">:3000 \u00b7 ready \u2713<\/text>\n<rect x=\"650\" y=\"240\" width=\"220\" height=\"60\" rx=\"12\" fill=\"#1f2752\" stroke=\"#7c5cff\"\/>\n<text x=\"760\" y=\"266\" text-anchor=\"middle\" fill=\"#fff\" font-size=\"15\" font-weight=\"600\">Pod \u00b7 app=hello-k8s<\/text>\n<text x=\"760\" y=\"287\" text-anchor=\"middle\" fill=\"#9db8ff\" font-size=\"13\">:3000 \u00b7 ready \u2713<\/text>\n<text x=\"30\" y=\"310\" fill=\"#8f9bc4\" font-size=\"13\">Port 80 on the Service \u2192 targetPort 3000 on each container<\/text>\n<\/g>\n<\/svg>\n<figcaption>Figure 2: A Service finds Pods by <strong>label<\/strong>, not by name, and only sends traffic to Pods whose readiness probe passes.<\/figcaption>\n<\/figure>\n\n<h2 id=\"configmap\">Step 5: Move Settings into a ConfigMap<\/h2>\n<p>Hard-coding settings inside the image means rebuilding for every change. A <strong>ConfigMap<\/strong> stores plain settings (non-secret values) that are passed into the container as environment variables.<\/p>\n<pre><code># k8s\/configmap.yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: hello-config\ndata:\n  GREETING: \"Namaste from DevDojo on Kubernetes\"<\/code><\/pre>\n<p>Then tell the container to read it. Add <code>envFrom<\/code> under the container in <code>deployment.yaml<\/code> (same indent level as <code>ports<\/code>):<\/p>\n<pre><code>          envFrom:\n            - configMapRef:\n                name: hello-config<\/code><\/pre>\n<pre><code>kubectl apply -f k8s\/          # applies every file in the folder\nkubectl rollout restart deployment\/hello-k8s   # env vars are read at start-up<\/code><\/pre>\n<p>Refresh <code>localhost:8080<\/code> (restart the <code>port-forward<\/code> if it stopped) and you will see the new greeting.<\/p>\n<div class=\"dd-warn\"><strong>Passwords and API keys:<\/strong> do not put them in a ConfigMap. Use a <strong>Secret<\/strong> instead (<code>kubectl create secret generic db-pass --from-literal=PASSWORD=...<\/code>) and keep the real values out of Git. Note that Secrets are only base64-encoded by default, so production clusters should also enable encryption at rest or use an external secret manager.<\/div>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"scale-update\">Step 6: Scale, Update and Roll Back<\/h2>\n<h3>Scale up and down<\/h3>\n<pre><code>kubectl scale deployment\/hello-k8s --replicas=5\nkubectl get pods\n\n# Better long-term: change \"replicas: 5\" in deployment.yaml and run\nkubectl apply -f k8s\/deployment.yaml<\/code><\/pre>\n<div class=\"dd-tip\"><strong>Tip:<\/strong> Prefer editing the YAML file over one-off commands. The file in Git then always matches what is running, and teammates can review the change.<\/div>\n\n<h3>Ship version 2.0 with zero downtime<\/h3>\n<p>Change <code>const VERSION = '1.0';<\/code> to <code>'2.0'<\/code> in <code>server.js<\/code>, then:<\/p>\n<pre><code>docker build -t hello-k8s:2.0 .\nkind load docker-image hello-k8s:2.0 --name devdojo\n\n# Update the image of the \"web\" container\nkubectl set image deployment\/hello-k8s web=hello-k8s:2.0\nkubectl rollout status deployment\/hello-k8s<\/code><\/pre>\n<p>Kubernetes performs a <strong>rolling update<\/strong>: it starts new Pods, waits until their readiness probe passes, and only then removes old Pods. Users never see the app go down. This is why the readiness probe from Step 3 matters so much.<\/p>\n\n<h3>Something broke? Roll back<\/h3>\n<pre><code>kubectl rollout history deployment\/hello-k8s\nkubectl rollout undo deployment\/hello-k8s          # back to the previous version\nkubectl rollout undo deployment\/hello-k8s --to-revision=1<\/code><\/pre>\n\n<h2 id=\"cheatsheet\">kubectl Cheat Sheet (Interactive)<\/h2>\n<p>Click a tab to see the commands you will use most for each job.<\/p>\n<div class=\"dd-tabs\">\n<input type=\"radio\" name=\"ddtabs\" id=\"ddt1\" checked>\n<input type=\"radio\" name=\"ddtabs\" id=\"ddt2\">\n<input type=\"radio\" name=\"ddtabs\" id=\"ddt3\">\n<input type=\"radio\" name=\"ddtabs\" id=\"ddt4\">\n<div class=\"dd-tab-bar\">\n<label for=\"ddt1\">\ud83d\udc40 Look<\/label>\n<label for=\"ddt2\">\ud83d\udd0d Debug<\/label>\n<label for=\"ddt3\">\u270f\ufe0f Change<\/label>\n<label for=\"ddt4\">\ud83e\uddf9 Clean up<\/label>\n<\/div>\n<div class=\"dd-panels\">\n<div class=\"dd-panel p1\">\n<pre><code>kubectl get pods                 # list Pods\nkubectl get pods -o wide         # + node and IP\nkubectl get deploy,svc,cm        # several kinds at once\nkubectl get all                  # common objects in the namespace\nkubectl get events --sort-by=.lastTimestamp<\/code><\/pre>\n<\/div>\n<div class=\"dd-panel p2\">\n<pre><code>kubectl describe pod &lt;pod-name&gt;      # events = the reason it fails\nkubectl logs &lt;pod-name&gt;              # app output\nkubectl logs &lt;pod-name&gt; --previous   # logs from the crashed run\nkubectl logs -f deploy\/hello-k8s     # follow logs of one Pod in it\nkubectl exec -it &lt;pod-name&gt; -- sh    # open a shell inside<\/code><\/pre>\n<\/div>\n<div class=\"dd-panel p3\">\n<pre><code>kubectl apply -f k8s\/                         # create or update\nkubectl diff -f k8s\/                          # preview a change\nkubectl scale deploy\/hello-k8s --replicas=4\nkubectl set image deploy\/hello-k8s web=hello-k8s:2.0\nkubectl rollout undo deploy\/hello-k8s<\/code><\/pre>\n<\/div>\n<div class=\"dd-panel p4\">\n<pre><code>kubectl delete -f k8s\/                 # remove what you applied\nkind delete cluster --name devdojo     # delete the whole cluster\nkind get clusters                      # check what is left<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n\n<h2 id=\"errors\">Common Errors and Fixes<\/h2>\n<p>When something goes wrong, your first command is almost always <code>kubectl describe pod &lt;name&gt;<\/code>. Scroll to the <strong>Events<\/strong> section at the bottom \u2014 the reason is usually written there in plain words.<\/p>\n<table>\n<thead><tr><th>Error \/ Status<\/th><th>What it usually means<\/th><th>How to fix it<\/th><\/tr><\/thead>\n<tbody>\n<tr><td><code>ImagePullBackOff<\/code> \/ <code>ErrImagePull<\/code><\/td><td>The node cannot get the image.<\/td><td>With kind, run <code>kind load docker-image name:tag --name devdojo<\/code>. Check the image name and tag spelling. Avoid the <code>latest<\/code> tag for local images.<\/td><\/tr>\n<tr><td><code>CrashLoopBackOff<\/code><\/td><td>The container starts and then exits again and again.<\/td><td>Run <code>kubectl logs &lt;pod&gt; --previous<\/code> to see the crash. Common causes: missing env var, wrong start command, app listening on a different port than the probe checks.<\/td><\/tr>\n<tr><td><code>Pending<\/code> (forever)<\/td><td>No node has enough free CPU\/memory for the requests.<\/td><td>Lower <code>resources.requests<\/code>, reduce replicas, or give Docker Desktop more memory.<\/td><\/tr>\n<tr><td><code>0\/1 READY<\/code> but <code>Running<\/code><\/td><td>The readiness probe is failing, so the Service sends no traffic.<\/td><td>Check that the probe path and port match the app (<code>\/healthz<\/code> on <code>3000<\/code>).<\/td><\/tr>\n<tr><td><code>OOMKilled<\/code><\/td><td>The container used more memory than its limit.<\/td><td>Raise <code>limits.memory<\/code> or fix the memory leak.<\/td><\/tr>\n<tr><td><code>connection to the server localhost:8080 was refused<\/code><\/td><td>kubectl has no cluster configured, or the wrong context.<\/td><td>Run <code>kubectl config get-contexts<\/code> and <code>kubectl config use-context kind-devdojo<\/code>. Is Docker running?<\/td><\/tr>\n<tr><td><code>selector does not match template labels<\/code><\/td><td>The Deployment\u2019s <code>selector.matchLabels<\/code> and Pod labels differ.<\/td><td>Make both exactly <code>app: hello-k8s<\/code>. Note that a Deployment\u2019s selector cannot be changed later; delete and recreate it.<\/td><\/tr>\n<tr><td>Service returns nothing \/ times out<\/td><td>The Service selector matches no Pods.<\/td><td>Run <code>kubectl get endpointslices -l kubernetes.io\/service-name=hello-k8s<\/code>. If empty, fix the labels.<\/td><\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n\n\n\n<div class=\"dd-post\">\n<h2 id=\"best-practices\">Kubernetes Best Practices for Beginners<\/h2>\n<ol>\n<li><strong>Keep all YAML in Git.<\/strong> Treat the <code>k8s\/<\/code> folder like code: review it, version it, and apply it from CI. Our <a href=\"https:\/\/devdojo.co.in\/github-actions-ci-cd-nodejs\/\">GitHub Actions CI\/CD guide<\/a> is a good next step for automating builds.<\/li>\n<li><strong>Always use specific image tags<\/strong> (<code>1.4.2<\/code> or a Git commit SHA), never <code>latest<\/code>, so you know exactly what runs and can roll back.<\/li>\n<li><strong>Add readiness and liveness probes<\/strong> to every web container. Without readiness, rolling updates can send users to Pods that are not ready yet.<\/li>\n<li><strong>Set resource requests<\/strong> so the scheduler can place Pods sensibly, and a memory limit to stop one app from starving the node.<\/li>\n<li><strong>Handle <code>SIGTERM<\/code><\/strong> in your app (like our <code>server.js<\/code>) so in-flight requests finish before a Pod stops.<\/li>\n<li><strong>Run at least 2 replicas<\/strong> of anything users depend on, so one Pod restarting never causes an outage.<\/li>\n<li><strong>Use namespaces<\/strong> (<code>kubectl create namespace staging<\/code>) to separate environments or teams in one cluster.<\/li>\n<li><strong>Keep secrets out of images and ConfigMaps.<\/strong> Use Secrets plus a proper secret manager in production.<\/li>\n<li><strong>Run containers as a non-root user<\/strong> (we used <code>USER node<\/code> in the Dockerfile).<\/li>\n<li><strong>Start managed in production.<\/strong> Services like Amazon EKS, Google GKE and Azure AKS run the control plane for you, so you can focus on your apps.<\/li>\n<\/ol>\n\n<h3>Where to go after this tutorial<\/h3>\n<div class=\"dd-cards\">\n<div class=\"dd-card\"><b>Ingress \/ Gateway API<\/b>Expose many apps on real domain names with HTTPS.<\/div>\n<div class=\"dd-card\"><b>Helm<\/b>Package your YAML into reusable, configurable charts.<\/div>\n<div class=\"dd-card\"><b>Horizontal Pod Autoscaler<\/b>Add or remove Pods automatically based on CPU or other metrics.<\/div>\n<div class=\"dd-card\"><b>StatefulSets and volumes<\/b>Run databases and apps that need to keep data.<\/div>\n<\/div>\n<p>The official <a href=\"https:\/\/kubernetes.io\/docs\/tutorials\/kubernetes-basics\/\" target=\"_blank\" rel=\"noopener\">Kubernetes Basics tutorial<\/a> is an excellent free resource for each of these topics.<\/p>\n\n<h2 id=\"faq\">Frequently Asked Questions<\/h2>\n<details><summary>Is Kubernetes hard to learn for beginners?<\/summary><p>The basics are not hard. If you understand Docker, you can learn Pods, Deployments and Services in a weekend by following this Kubernetes tutorial for beginners. The difficult parts (networking, security, storage) can be learned slowly, when you need them.<\/p><\/details>\n<details><summary>Do I need to learn Docker before Kubernetes?<\/summary><p>Yes, at least the basics: what an image is, how to write a Dockerfile, and how to run a container. Kubernetes runs container images, so Docker knowledge makes everything easier.<\/p><\/details>\n<details><summary>What is the difference between kind, minikube and k3s?<\/summary><p>All three run Kubernetes locally. <strong>kind<\/strong> runs nodes as Docker containers and is fast to create and delete (great for learning and CI). <strong>minikube<\/strong> has many add-ons and a dashboard. <strong>k3s<\/strong> is a lightweight Kubernetes distribution that is also used on small servers and edge devices.<\/p><\/details>\n<details><summary>Should I use Kubernetes for a small project?<\/summary><p>Often no. For a simple app with low traffic, a single server with Docker Compose, or a platform like Render, Railway or Vercel, is cheaper and simpler. Kubernetes shines when you have many services, need high availability, or your company already uses it. Learning it is still a strong career skill.<\/p><\/details>\n<details><summary>What is the difference between a Pod and a container?<\/summary><p>A container is one running image. A Pod is a wrapper around one or more containers that share the same network address and storage. Most Pods hold exactly one container.<\/p><\/details>\n<details><summary>Is Kubernetes knowledge useful for jobs in India and abroad?<\/summary><p>Yes. DevOps, SRE, cloud and backend roles at Indian product companies, IT service firms and global startups commonly list Kubernetes. Being able to deploy, scale and debug an app like you did here is a practical skill you can show in interviews.<\/p><\/details>\n\n<h2 id=\"conclusion\">Wrapping Up This Kubernetes Tutorial for Beginners<\/h2>\n<p>You just did what many developers find scary: you created a Kubernetes cluster, deployed a Node.js app with three replicas, exposed it with a Service, moved settings into a ConfigMap, scaled it, shipped a new version with zero downtime, and rolled it back. The key idea to remember is simple \u2014 <strong>you describe the desired state in YAML, and Kubernetes keeps working to make it true<\/strong>.<\/p>\n<p>Next, try adding a second service (for example a Redis Pod), put your YAML into a Git repo, and deploy it from a CI pipeline. When you are done experimenting, clean up with <code>kind delete cluster --name devdojo<\/code>.<\/p>\n\n<div class=\"dd-cta\">\n<h3>New posts every day on DevDojo<\/h3>\n<p>Practical tutorials on AI, Frontend, Backend and DevOps \u2014 written in simple English for developers in India and around the world.<\/p>\n<p><a href=\"https:\/\/devdojo.co.in\/\">Read more DevDojo tutorials \u2192<\/a> \u00b7 Found this useful? Leave a comment with your questions below.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.<\/p>\n","protected":false},"author":1,"featured_media":208,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57,8],"tags":[61,60,109,108,43],"class_list":["post-209","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-nodejs","tag-devops","tag-docker","tag-kubectl","tag-kubernetes","tag-node-js"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Lokendra\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"DevDojo - Empowering Developers\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Kubernetes Tutorial for Beginners: Deploy a Node.js App\" \/>\n\t\t<meta property=\"og:description\" content=\"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-18T06:13:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-18T06:13:59+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Kubernetes Tutorial for Beginners: Deploy a Node.js App\" \/>\n\t\t<meta name=\"twitter:description\" content=\"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#blogposting\",\"name\":\"Kubernetes Tutorial for Beginners: Deploy a Node.js App\",\"headline\":\"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step\",\"author\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/kubernetes-tutorial.jpg\",\"width\":1200,\"height\":630,\"caption\":\"Kubernetes tutorial for beginners banner showing a Service sending traffic to three running Pods\"},\"datePublished\":\"2026-10-18T06:13:58+00:00\",\"dateModified\":\"2026-10-18T06:13:59+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#webpage\"},\"articleSection\":\"DevOps, NodeJS, DevOps, Docker, kubectl, Kubernetes, Node.js\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/devdojo.co.in\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/#listItem\",\"name\":\"Backend\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/#listItem\",\"position\":2,\"name\":\"Backend\",\"item\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/nodejs\\\/#listItem\",\"name\":\"NodeJS\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/nodejs\\\/#listItem\",\"position\":3,\"name\":\"NodeJS\",\"item\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/nodejs\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#listItem\",\"name\":\"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/#listItem\",\"name\":\"Backend\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#listItem\",\"position\":4,\"name\":\"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/category\\\/backend\\\/nodejs\\\/#listItem\",\"name\":\"NodeJS\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\",\"name\":\"DevDojo\",\"description\":\"Empowering Developers\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/\",\"name\":\"Lokendra\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/99f102f0cc9080237ce54b91304fd1b3b6fa29925cbaeba93cd796872e58b45c?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Lokendra\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#webpage\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/\",\"name\":\"Kubernetes Tutorial for Beginners: Deploy a Node.js App\",\"description\":\"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/author\\\/lokendra\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/kubernetes-tutorial.jpg\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#mainImage\",\"width\":1200,\"height\":630,\"caption\":\"Kubernetes tutorial for beginners banner showing a Service sending traffic to three running Pods\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/index.php\\\/2026\\\/10\\\/18\\\/kubernetes-tutorial\\\/#mainImage\"},\"datePublished\":\"2026-10-18T06:13:58+00:00\",\"dateModified\":\"2026-10-18T06:13:59+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#website\",\"url\":\"https:\\\/\\\/devdojo.co.in\\\/\",\"name\":\"DevDojo\",\"description\":\"Empowering Developers\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/devdojo.co.in\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.","canonical_url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#blogposting","name":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","headline":"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step","author":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"publisher":{"@id":"https:\/\/devdojo.co.in\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/devdojo.co.in\/wp-content\/uploads\/2026\/10\/kubernetes-tutorial.jpg","width":1200,"height":630,"caption":"Kubernetes tutorial for beginners banner showing a Service sending traffic to three running Pods"},"datePublished":"2026-10-18T06:13:58+00:00","dateModified":"2026-10-18T06:13:59+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#webpage"},"isPartOf":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#webpage"},"articleSection":"DevOps, NodeJS, DevOps, Docker, kubectl, Kubernetes, Node.js"},{"@type":"BreadcrumbList","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/#listItem","position":1,"name":"Home","item":"https:\/\/devdojo.co.in\/","nextItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/#listItem","name":"Backend"}},{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/#listItem","position":2,"name":"Backend","item":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/","nextItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/#listItem","name":"NodeJS"},"previousItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/#listItem","position":3,"name":"NodeJS","item":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/","nextItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#listItem","name":"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step"},"previousItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/#listItem","name":"Backend"}},{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#listItem","position":4,"name":"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step","previousItem":{"@type":"ListItem","@id":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/#listItem","name":"NodeJS"}}]},{"@type":"Organization","@id":"https:\/\/devdojo.co.in\/#organization","name":"DevDojo","description":"Empowering Developers","url":"https:\/\/devdojo.co.in\/"},{"@type":"Person","@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author","url":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/","name":"Lokendra","image":{"@type":"ImageObject","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/99f102f0cc9080237ce54b91304fd1b3b6fa29925cbaeba93cd796872e58b45c?s=96&d=mm&r=g","width":96,"height":96,"caption":"Lokendra"}},{"@type":"WebPage","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#webpage","url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/","name":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/devdojo.co.in\/#website"},"breadcrumb":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#breadcrumblist"},"author":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"creator":{"@id":"https:\/\/devdojo.co.in\/index.php\/author\/lokendra\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/devdojo.co.in\/wp-content\/uploads\/2026\/10\/kubernetes-tutorial.jpg","@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#mainImage","width":1200,"height":630,"caption":"Kubernetes tutorial for beginners banner showing a Service sending traffic to three running Pods"},"primaryImageOfPage":{"@id":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/#mainImage"},"datePublished":"2026-10-18T06:13:58+00:00","dateModified":"2026-10-18T06:13:59+00:00"},{"@type":"WebSite","@id":"https:\/\/devdojo.co.in\/#website","url":"https:\/\/devdojo.co.in\/","name":"DevDojo","description":"Empowering Developers","inLanguage":"en-US","publisher":{"@id":"https:\/\/devdojo.co.in\/#organization"}}]},"og:locale":"en_US","og:site_name":"DevDojo - Empowering Developers","og:type":"article","og:title":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","og:description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.","og:url":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/","article:published_time":"2026-10-18T06:13:58+00:00","article:modified_time":"2026-10-18T06:13:59+00:00","twitter:card":"summary_large_image","twitter:title":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","twitter:description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it."},"aioseo_meta_data":{"post_id":"209","title":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.","keywords":null,"keyphrases":{"focus":{"keyphrase":"Kubernetes tutorial for beginners"},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":"Kubernetes Tutorial for Beginners: Deploy a Node.js App","og_description":"This Kubernetes tutorial for beginners shows you how to create a local cluster with kind, deploy a Node.js app, then scale, update and debug it.","og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":0,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-10-18 06:08:40","updated":"2026-10-18 12:56:39","focus_keyword":"Kubernetes tutorial for beginners","additional_keywords":null,"truseo_locale":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/devdojo.co.in\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/devdojo.co.in\/index.php\/category\/backend\/\" title=\"Backend\">Backend<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/\" title=\"NodeJS\">NodeJS<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tKubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/devdojo.co.in\/"},{"label":"Backend","link":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/"},{"label":"NodeJS","link":"https:\/\/devdojo.co.in\/index.php\/category\/backend\/nodejs\/"},{"label":"Kubernetes Tutorial for Beginners: Deploy a Node.js App Step by Step","link":"https:\/\/devdojo.co.in\/index.php\/2026\/10\/18\/kubernetes-tutorial\/"}],"_links":{"self":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/comments?post=209"}],"version-history":[{"count":1,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/209\/revisions"}],"predecessor-version":[{"id":210,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/posts\/209\/revisions\/210"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/media\/208"}],"wp:attachment":[{"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/media?parent=209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/categories?post=209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devdojo.co.in\/index.php\/wp-json\/wp\/v2\/tags?post=209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}