|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: A Simple Walkthrough of Kubernetes Pod Creation |
| 4 | +date: 2024-12-03 |
| 5 | +author_name: Madhura C |
| 6 | +author_role: Kubernetes Enthusiast |
| 7 | +blurb_img: /assets/images/blog/20241203-Madhura-cover.png |
| 8 | +blurb_img_source: This image was created by AI. |
| 9 | +description: A detailed guide explaining the lifecycle of Kubernetes Pods, from YAML definition to live deployment. |
| 10 | +category: kubernetes |
| 11 | +--- |
| 12 | + |
| 13 | +<div class="text-justify"> |
| 14 | + <h1 class="section-header">From Pod Definition to Live Pod</h1> |
| 15 | + <p> |
| 16 | + By now, you likely know that Kubernetes is an open-source container orchestration engine for deploying, scaling, and managing containerised applications. There is no shortage of resources on Kubernetes. In fact, there is so much information out there that it feels overwhelming, especially for beginners. |
| 17 | + </p> |
| 18 | + <p> |
| 19 | + If you’re like me and already have a basic understanding of Kubernetes but want to dive deeper into how a Pod is actually created, then you’re in the right place. |
| 20 | + </p> |
| 21 | + <p> |
| 22 | + In this post, I’ll cover each step of Pod creation — from defining a Pod in YAML to seeing it live and running. |
| 23 | + </p> |
| 24 | + |
| 25 | + <h1 class="section-header">Define Pod</h1> |
| 26 | + <p> |
| 27 | + Let’s begin by creating a YAML file that details the specifications of the Pod. This file is like a blueprint, containing essential settings like container image, resources, and environment variables, which Kubernetes uses to create the Pod as you’ve envisioned it. |
| 28 | + </p> |
| 29 | + |
| 30 | + <p class="font-weight-bold">Action:</p> |
| 31 | + <p>Create a file called <code>nginx-pod.yaml</code>:</p> |
| 32 | + <pre> |
| 33 | +apiVersion: v1 |
| 34 | +kind: Pod |
| 35 | +metadata: |
| 36 | + name: nginx-pod |
| 37 | +spec: |
| 38 | + containers: |
| 39 | + - name: nginx |
| 40 | + image: nginx:latest |
| 41 | + ports: |
| 42 | + - containerPort: 80 |
| 43 | + </pre> |
| 44 | + |
| 45 | + <div class="article-media"> |
| 46 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-nginx-pod-yaml-file-vs-code.png" alt="nginx-pod.yaml file"> |
| 47 | + <div class="img-source">Image: nginx-pod.yaml file in VS Code</div> |
| 48 | + </div> |
| 49 | + |
| 50 | + <p> |
| 51 | + <strong>Explanation:</strong> This YAML file defines a Pod named <code>nginx-pod</code> with a container running the <code>nginx:latest</code> image and sets up port 80 to handle HTTP traffic. |
| 52 | + </p> |
| 53 | + |
| 54 | + <h1 class="section-header">API Server Receives the Request</h1> |
| 55 | + <p> |
| 56 | + When we apply our YAML file using the <code>kubectl</code> command, the Kubernetes API server validates the file for any errors and updates the etcd database with the Pod’s configuration. This step ensures the instructions are stored securely and are ready to guide the creation of the Pod. |
| 57 | + </p> |
| 58 | + |
| 59 | + <p class="font-weight-bold">Action:</p> |
| 60 | + <p><em>Run the following command to apply the file:</em></p> |
| 61 | + <p><em>I used Minikube as it lets you run a single-node Kubernetes cluster inside a virtual machine on your local computer. There are other options available like Docker Desktop Kubernetes, MicroK8s, Kind etc.</em></p> |
| 62 | + <p><em>Note - Docker desktop app should be running before running the Minikube command.</em></p> |
| 63 | + <pre> |
| 64 | +minikube start --driver=docker --addons=dashboard --addons=metrics-server --addons="ingress" --addons="ingress-dns" |
| 65 | +kubectl apply -f .\nginx-pod.yaml |
| 66 | + </pre> |
| 67 | + |
| 68 | + <div class="article-media"> |
| 69 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-minikube-start-command-output.png" alt="Minikube start command output"> |
| 70 | + <div class="img-source">Image: Minikube start command output</div> |
| 71 | + </div> |
| 72 | + <pre> |
| 73 | +kubectl apply -f .\nginx-pod.yaml |
| 74 | + </pre> |
| 75 | + <div class="article-media"> |
| 76 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-kubectl-apply-command.png" alt="kubectl apply command output"> |
| 77 | + <div class="img-source">Image: kubectl apply command output</div> |
| 78 | + </div> |
| 79 | + |
| 80 | + <p> |
| 81 | + <strong>Explanation:</strong> This command sends the Pod configuration to the API server, which validates it and records it in the <code>etcd</code> database. This is the first step in creating Nginx server Pod. |
| 82 | + </p> |
| 83 | + |
| 84 | + <h1 class="section-header">Controller Takes Action</h1> |
| 85 | + <p> |
| 86 | + The controller continuously monitors the cluster’s desired state against the actual state. If it detects that the Pod isn’t running as specified, it triggers adjustments to match our instructions, helping maintain a consistent environment. |
| 87 | + </p> |
| 88 | + |
| 89 | + <p class="font-weight-bold">Action:</p> |
| 90 | + <p>The controller sees that <code>nginx-pod</code> is not yet active in the cluster and initiates its creation.</p> |
| 91 | + |
| 92 | + <p> |
| 93 | + <strong>Explanation:</strong> The controller’s role here is to ensure that a Pod named <code>nginx-pod</code> is created and stays in the desired state. If it crashes or is removed, the controller will step in to recreate it, maintaining the desired configuration. |
| 94 | + </p> |
| 95 | + |
| 96 | + <h1 class="section-header">Scheduler Gets Involved</h1> |
| 97 | + <p> |
| 98 | + If the Pod is still in a “Pending” state, the scheduler steps in to find the most suitable node for it based on available resources and constraints. This ensures efficient use of cluster resources, so the Pod runs optimally without conflicts. |
| 99 | + </p> |
| 100 | + |
| 101 | + <p class="font-weight-bold">Action:</p> |
| 102 | + <p>The scheduler finds a node with available CPU and memory, and assigns <code>nginx-pod</code> to run on that node.</p> |
| 103 | + |
| 104 | + <p> |
| 105 | + <strong>Explanation:</strong> Here, the scheduler analyses the resource requirements of <code>nginx-pod</code> and picks a node with sufficient capacity. This helps balance the load across the cluster and ensures that the node has enough resources to handle the Nginx server workload. |
| 106 | + </p> |
| 107 | + |
| 108 | + <h1 class="section-header">Kubelet to the Rescue</h1> |
| 109 | + <p> |
| 110 | + Once a node is selected, the kubelet (an agent running on the node) retrieves the Pod’s specifications from the API server, downloads the necessary container images, and initiates the Pod. It’s responsible for maintaining the health and operation of the Pod on that node. |
| 111 | + </p> |
| 112 | + |
| 113 | + <p class="font-weight-bold">Action:</p> |
| 114 | + <p>The kubelet on the assigned node fetches the Pod specification, pulls the <code>nginx:latest</code> image if it’s not already available on the node, and starts the Nginx container.</p> |
| 115 | + <p><em>The kubelet will pull nginx:latest from public registry like Docker Hub.</em></p> |
| 116 | + <p><em>We can specify a custom registry by including the registry’s URL in the image name. For example, example.com/mynginx:latest tells the kubelet to pull the image from example.com.</em></p> |
| 117 | + <p><em>If the image is stored in a private registry then authentication credentials will be needed.</em></p> |
| 118 | + |
| 119 | + <p> |
| 120 | + <strong>Explanation:</strong> The kubelet is the primary agent responsible for actually running the container in the node environment. It pulls the <code>nginx</code> image, initialises the container, and manages its lifecycle, such as restarting it if it fails. |
| 121 | + </p> |
| 122 | + |
| 123 | + <h1 class="section-header">Pod is Live</h1> |
| 124 | + <p> |
| 125 | + After the kubelet finishes setting everything up, the Pod’s status changes from Pending to Running. This means all components are active, and our Pod is ready to handle any assigned workloads, completing the creation process! |
| 126 | + </p> |
| 127 | + |
| 128 | + <p class="font-weight-bold">Action:</p> |
| 129 | + <p>Check if the Pod is running with the command:</p> |
| 130 | + <pre> |
| 131 | +kubectl get pods |
| 132 | + </pre> |
| 133 | + |
| 134 | + <div class="article-media"> |
| 135 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-kubectl-get-pods.png" alt="kubectl get pods output"> |
| 136 | + <div class="img-source">Image: kubectl get pods output - Returns all the pods</div> |
| 137 | + </div> |
| 138 | + <div class="article-media"> |
| 139 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-kubectl-get-pods-output.png" alt="kubectl get pods nginx-pod"> |
| 140 | + <div class="img-source">Image: kubectl get pods nginx-pod output - Returns specific pod</div> |
| 141 | + </div> |
| 142 | + <p> |
| 143 | + <strong>Explanation:</strong> When the nginx-pod status shows as Running, the Nginx server is live and ready to serve requests within the Kubernetes network. We now have a fully operational Nginx Pod, all set up to handle web traffic in our cluster. |
| 144 | + </p>We have successfully deployed an Nginx web server in Kubernetes from a YAML specification to a fully running Pod in the cluster. |
| 145 | + </p>To open Minikube dashboard, run <code>minikube dashboard<code> |
| 146 | + </p> |
| 147 | + <div class="article-media"> |
| 148 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-minikube-dashboard-command-output.png" alt="Minikube dashboard command output"> |
| 149 | + <div class="img-source">Image: Minikube dashboard command output</div> |
| 150 | + </div> |
| 151 | +</div> |
| 152 | +<div class="article-media"> |
| 153 | + <img class="img-fluid" src="/assets/images/blog/20241203-Madhura-minikube-dashboard.png" alt="Minikube dashboard"> |
| 154 | + <div class="img-source">Image: Minikube dashboard (Note: you may have only one pod running)</div>"> |
| 155 | +</div> |
| 156 | +</div> |
| 157 | +<div class="article-media"> |
| 158 | + <img class="img-fluid" src="/assets/images/blog/220241203-Madhura-minikube-dashboard-pod-details.png" alt="Minikube dashboard Pod Details"> |
| 159 | + <div class="img-source">Image: Pod details</div> |
| 160 | +</div> |
| 161 | +<p> |
| 162 | + To stop Minikube, run <code>minikube stop</code>. |
| 163 | +</p> |
| 164 | +<div class="article-media"> |
| 165 | + <img class="img-fluid" src="/assets/images/blog/minikube-stopcommand.png" alt="Minikube stop command"> |
| 166 | + <div class="img-source">Image: Minikube stop command output</div> |
| 167 | +</div> |
| 168 | + |
| 169 | +<p> |
| 170 | + <strong>To recap:</strong> |
| 171 | +</p> |
| 172 | +<ul> |
| 173 | + <li>Define the Pod in a YAML file</li> |
| 174 | + <li>Apply the config through the API server</li> |
| 175 | + <li>Controller ensures it matches the desired state</li> |
| 176 | + <li>Scheduler assigns it to a node</li> |
| 177 | + <li>Kubelet on that node pulls the necessary image and starts the container</li> |
| 178 | + <li>Pod transitions to a Running state</li> |
| 179 | +</ul> |
0 commit comments