<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aisalkyn Aidarova</title>
    <description>The latest articles on DEV Community by Aisalkyn Aidarova (@jumptotech).</description>
    <link>https://dev.to/jumptotech</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3549986%2F7a403ca9-0459-412a-b618-71699480d58d.png</url>
      <title>DEV Community: Aisalkyn Aidarova</title>
      <link>https://dev.to/jumptotech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jumptotech"/>
    <language>en</language>
    <item>
      <title>2-2 The Midnight Payment Processing Incident — Kubernetes, PostgreSQL, Terraform, CI/CD, Grafana and PagerDuty</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Fri, 30 Oct 2026 02:04:16 +0000</pubDate>
      <link>https://dev.to/jumptotech/2-2-the-midnight-payment-processing-incident-kubernetes-postgresql-terraform-cicd-grafana-33a5</link>
      <guid>https://dev.to/jumptotech/2-2-the-midnight-payment-processing-incident-kubernetes-postgresql-terraform-cicd-grafana-33a5</guid>
      <description>&lt;p&gt;Student hands-on guide · 3 classes × 3 hours · AWS EKS training environment&lt;/p&gt;

&lt;h3&gt;
  
  
  Your mission
&lt;/h3&gt;

&lt;p&gt;You are a DevOps/SRE engineer supporting a banking payment-processing platform. At midnight, PagerDuty notifies the primary on-call engineer that payment transactions are failing.&lt;/p&gt;

&lt;p&gt;You open Grafana and see increasing HTTP 503 errors. But when you inspect Kubernetes, the application Pods are all &lt;code&gt;Running&lt;/code&gt; and &lt;code&gt;Ready&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How can the application be healthy according to Kubernetes while customers cannot complete payments?&lt;/p&gt;

&lt;p&gt;You will investigate the application, its PostgreSQL database, Kubernetes networking, deployment history, monitoring, and the infrastructure changes that could have caused the incident.&lt;/p&gt;

&lt;p&gt;This is a realistic fictional production case study, supported by a real, runnable training lab. You must not claim that it is an actual incident at a named bank.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Incident ticket
&lt;/h2&gt;

&lt;p&gt;INC-2026-1047&lt;/p&gt;

&lt;p&gt;SEV-1 · Scenario&lt;/p&gt;

&lt;p&gt;Payment Processing API — Elevated 5xx Error Rate&lt;/p&gt;

&lt;p&gt;PagerDuty · Payments Production · 12:05 AM&lt;/p&gt;

&lt;p&gt;Reported impact: Payment submissions failing across the customer-facing banking application.&lt;/p&gt;

&lt;p&gt;Monitoring: HTTP 503 responses increasing, payment success rate declining, API Pods still Ready.&lt;/p&gt;

&lt;p&gt;Initial hypothesis: Application dependency failure, database connectivity, or recent infrastructure change.&lt;/p&gt;

&lt;p&gt;Assigned: Primary On-Call SRE&lt;/p&gt;

&lt;p&gt;Escalation: Incident Commander, Backend Engineering, DBA, Cloud Platform, Release Engineering, Security.&lt;/p&gt;

&lt;p&gt;In the hypothetical production architecture, the application runs on AWS EKS across three Availability Zones and connects to Amazon RDS PostgreSQL. Terraform manages security groups and networking; GitHub Actions handles application and infrastructure pipelines.&lt;/p&gt;

&lt;p&gt;For the actual student lab, we use two Payment API replicas and PostgreSQL inside Kubernetes to keep costs and resource requirements low.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Production architecture and team responsibilities
&lt;/h2&gt;

&lt;p&gt;Reference production architecture. The classroom lab replaces RDS and AWS security-group failure with an in-cluster database and NetworkPolicy.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;th&gt;Responsibility during incident&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary On-Call SRE&lt;/td&gt;
&lt;td&gt;Acknowledge alert, assess impact, investigate, mitigate and communicate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident Commander&lt;/td&gt;
&lt;td&gt;Coordinate teams, severity, updates and escalation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend/Application Team&lt;/td&gt;
&lt;td&gt;Investigate application errors, connection pooling, configuration and code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database Administrator&lt;/td&gt;
&lt;td&gt;Check database availability, active connections, locks, CPU, I/O and query performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud/Platform Team&lt;/td&gt;
&lt;td&gt;Investigate EKS, VPC, security groups, routing and network policies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Release/CI/CD Team&lt;/td&gt;
&lt;td&gt;Check recent releases, GitHub Actions workflows and Terraform changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Team&lt;/td&gt;
&lt;td&gt;Review and approve necessary access-rule changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A primary on-call engineer may initially perform several of these functions, especially on a small team. Do not wait for a meeting before checking the impact and following your incident-response runbook.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What you will build
&lt;/h2&gt;

&lt;p&gt;The lab creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespace &lt;code&gt;payments-incident-lab&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL database with a &lt;code&gt;simulated_payments&lt;/code&gt; table&lt;/li&gt;
&lt;li&gt;Python Payment API with two replicas&lt;/li&gt;
&lt;li&gt;Kubernetes Services and health probes&lt;/li&gt;
&lt;li&gt;Prometheus metrics for requests, errors and latency&lt;/li&gt;
&lt;li&gt;A controlled database connectivity incident&lt;/li&gt;
&lt;li&gt;Recovery and verification procedures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lab uses synthetic payments only. It does not charge cards or connect to real payment processors.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Requirements
&lt;/h2&gt;

&lt;p&gt;You need a training EKS cluster, working &lt;code&gt;kubectl&lt;/code&gt;, Docker with permission to push images to a registry, and enough capacity for three small Pods in addition to monitoring.&lt;/p&gt;

&lt;p&gt;For the NetworkPolicy incident, the cluster must have NetworkPolicy enforcement enabled. Installing a NetworkPolicy resource without an enforcing CNI will not necessarily block traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  First, verify your environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config current-context
kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl get namespaces
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
kubectl get storageclass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not perform this exercise in a real production namespace.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part A — Create all application and Kubernetes files
&lt;/h1&gt;

&lt;p&gt;Create the project folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; payment-incident-lab/&lt;span class="o"&gt;{&lt;/span&gt;app,k8s,scripts,grafana,terraform&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;payment-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 1 — &lt;code&gt;app/requirements.txt&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flask==3.1.1
psycopg[binary]==3.2.9
prometheus-client==0.22.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 2 — &lt;code&gt;app/app.py&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is the application students will troubleshoot. Notice that &lt;code&gt;/readyz&lt;/code&gt; checks the application process, but deliberately does not check database connectivity. This allows Pods to remain Ready while payment requests fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="n"&gt;REQ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/db-check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;200&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reachable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database connectivity failed: %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="n"&gt;DB_ERRORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="n"&gt;REQ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/db-check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;503&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database_unavailable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/payments&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;DURATION&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/payments&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;silent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Idempotency-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;            &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount_cents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount_cents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount_cents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;        &lt;span class="p"&gt;):&lt;/span&gt;            &lt;span class="n"&gt;REQ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/payments&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;400&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Idempotency-Key and integer &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;                      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount_cents 1..100000 required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;            &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;                        INSERT INTO simulated_payments                        (idempotency_key, amount_cents)                        VALUES (%s, %s)                        ON CONFLICT (idempotency_key)                        DO NOTHING                        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount_cents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;                    &lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;                        SELECT id, amount_cents, status                        FROM simulated_payments                        WHERE idempotency_key = %s                        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,),&lt;/span&gt;                    &lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 3 — &lt;code&gt;app/Dockerfile&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.12-slim&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; app.py .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;useradd &lt;span class="nt"&gt;--uid&lt;/span&gt; 10001 &lt;span class="nt"&gt;--create-home&lt;/span&gt; appuser

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; 10001&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "app.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 4 — &lt;code&gt;k8s/00-namespace.yaml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Namespace&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 5 — &lt;code&gt;k8s/01-postgres.yaml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This database is disposable. Its storage uses &lt;code&gt;emptyDir&lt;/code&gt;, so deleting or replacing the database Pod can destroy its data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secret&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-auth&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Opaque&lt;/span&gt;
&lt;span class="na"&gt;stringData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;classroom-only-not-production&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ConfigMap&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-init&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;001-init.sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;CREATE TABLE IF NOT EXISTS simulated_payments (&lt;/span&gt;
      &lt;span class="s"&gt;id BIGSERIAL PRIMARY KEY,&lt;/span&gt;
      &lt;span class="s"&gt;idempotency_key TEXT NOT NULL UNIQUE,&lt;/span&gt;
      &lt;span class="s"&gt;amount_cents INTEGER NOT NULL&lt;/span&gt;
        &lt;span class="s"&gt;CHECK (amount_cents &amp;gt; 0),&lt;/span&gt;
      &lt;span class="s"&gt;status TEXT NOT NULL&lt;/span&gt;
        &lt;span class="s"&gt;DEFAULT 'simulated_approved',&lt;/span&gt;
      &lt;span class="s"&gt;created_at TIMESTAMPTZ NOT NULL DEFAULT now()&lt;/span&gt;
    &lt;span class="s"&gt;);&lt;/span&gt;
&lt;span class="s"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Recreate&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labuser&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-auth&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
              &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/docker-entrypoint-initdb.d&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data&lt;/span&gt;
              &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/postgresql/data&lt;/span&gt;
          &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sh&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-c&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pg_isready -U labuser -d payments&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;50m&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;128Mi&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;512Mi&lt;/span&gt;
      &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
          &lt;span class="na"&gt;configMap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-init&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;data&lt;/span&gt;
          &lt;span class="na"&gt;emptyDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 6 — &lt;code&gt;k8s/02-payment-api.yaml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Replace &lt;code&gt;REPLACE_WITH_YOUR_IMAGE&lt;/code&gt; with the container image you build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RollingUpdate&lt;/span&gt;
    &lt;span class="na"&gt;rollingUpdate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;maxSurge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;maxUnavailable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;REPLACE_WITH_YOUR_IMAGE&lt;/span&gt;
          &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
              &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_HOST&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_NAME&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_USER&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labuser&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-auth&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/readyz&lt;/span&gt;
              &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
          &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/healthz&lt;/span&gt;
              &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;50m&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;64Mi&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;256Mi&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 7 — &lt;code&gt;k8s/03-networkpolicy-outage.yaml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is the controlled failure. It blocks new incoming connections to the PostgreSQL Pod from the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NetworkPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;block-postgres-ingress&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;podSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;policyTypes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
  &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: This only works when your cluster enforces Kubernetes NetworkPolicy. On EKS, check the Amazon VPC CNI NetworkPolicy configuration before running this exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 8 — &lt;code&gt;k8s/04-servicemonitor-optional.yaml&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;monitoring.coreos.com/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceMonitor&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;monitoring&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;monitoring&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;namespaceSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchNames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-api&lt;/span&gt;
  &lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/metrics&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;release: monitoring&lt;/code&gt; label must match the selector of your Prometheus installation. This file requires the Prometheus Operator ServiceMonitor CRD.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part B — Build, deploy and verify
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 1. Build and push the Docker image
&lt;/h2&gt;

&lt;p&gt;Run from inside &lt;code&gt;payment-incident-lab&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Replace the Docker Hub username with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;IMAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'YOUR_DOCKERHUB_USERNAME/jumptotech-payment-api:v1'&lt;/span&gt;

docker buildx build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--platform&lt;/span&gt; linux/amd64 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IMAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--push&lt;/span&gt; ./app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your EKS worker nodes are ARM64, use &lt;code&gt;linux/arm64&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Deploy PostgreSQL
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s/00-namespace.yaml

kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s/01-postgres.yaml

kubectl rollout status deployment/lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PostgreSQL Pod should show &lt;code&gt;1/1 Running&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3. Deploy Payment API
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s2"&gt;"s|REPLACE_WITH_YOUR_IMAGE|&lt;/span&gt;&lt;span class="nv"&gt;$IMAGE&lt;/span&gt;&lt;span class="s2"&gt;|"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  k8s/02-payment-api.yaml | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -

kubectl rollout status deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s

kubectl get deployments &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected baseline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME           READY   UP-TO-DATE   AVAILABLE
lab-postgres   1/1     1            1
payment-api    2/2     2            2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Verify the database table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  deployment/lab-postgres &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  psql &lt;span class="nt"&gt;-U&lt;/span&gt; labuser &lt;span class="nt"&gt;-d&lt;/span&gt; payments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'\dt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the &lt;code&gt;simulated_payments&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Check the number of synthetic payments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  deployment/lab-postgres &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  psql &lt;span class="nt"&gt;-U&lt;/span&gt; labuser &lt;span class="nt"&gt;-d&lt;/span&gt; payments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'SELECT COUNT(*) FROM simulated_payments;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5. Test the application
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;scripts/02-smoke-test.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;NS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;payments-incident-lab

kubectl run &lt;span class="s2"&gt;"smoke-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl:8.11.1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'
    echo "READINESS:"
    curl -sS -i --max-time 10 \
      http://payment-api:8080/readyz

    echo
    echo "DB CHECK:"
    curl -sS -i --max-time 10 \
      http://payment-api:8080/api/db-check

    echo
    echo "SYNTHETIC PAYMENT:"
    curl -sS -i --max-time 10 \
      -X POST \
      http://payment-api:8080/api/payments \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: classroom-$(date +%s)" \
      -d "{\"amount_cents\":1250}"
'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/02-smoke-test.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Expected HTTP status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/readyz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/db-check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/payments&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The temporary curl Pod may display an attach warning after completing its request. Focus on the actual HTTP response.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part C — Configure Grafana and Prometheus
&lt;/h1&gt;

&lt;p&gt;First verify the monitoring components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring

kubectl get crd servicemonitors.monitoring.coreos.com

kubectl get prometheus &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the ServiceMonitor selectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get prometheus &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring &lt;span class="nt"&gt;-o&lt;/span&gt; yaml &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A12&lt;/span&gt; serviceMonitorSelector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the ServiceMonitor label matches your Prometheus configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s/04-servicemonitor-optional.yaml

kubectl get servicemonitor &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Grafana, select your Prometheus data source and create the following panels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Panel 1 — Payment API request rate by HTTP status
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_http_requests_total&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinguishes successful requests from HTTP 400, 409 and 503 responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Panel 2 — HTTP 5xx error rate
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_http_requests_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="s2"&gt;"5.."&lt;/span&gt;&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Panel 3 — Database errors over five minutes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_db_errors_total&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Panel 4 — Available replicas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_status_replicas_available&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payments-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Panel 5 — Desired replicas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_spec_replicas&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payments-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Panel 6 — Pod readiness
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;kube_pod_status_ready&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payments-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="na"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="s2"&gt;"payment-api-.*"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Panel 7 — Payment request p95 latency
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nb"&gt;histogram_quantile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;le&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;payment_http_request_duration_seconds_bucket&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;        &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/api/payments"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;      &lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate test traffic before expecting request metrics to appear. Check that Prometheus is actually scraping the Payment API target. The metrics may remain absent if the ServiceMonitor selector is incorrect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key learning point
&lt;/h3&gt;

&lt;p&gt;A dashboard can show:&lt;/p&gt;

&lt;p&gt;Available Pods&lt;/p&gt;

&lt;h1&gt;
  
  
  2 / 2
&lt;/h1&gt;

&lt;p&gt;Kubernetes sees healthy processes&lt;/p&gt;

&lt;p&gt;Payment API&lt;/p&gt;

&lt;h1&gt;
  
  
  503
&lt;/h1&gt;

&lt;p&gt;Database-dependent requests fail&lt;/p&gt;

&lt;p&gt;This is not contradictory. Kubernetes readiness and application business functionality are different signals.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part D — Create the incident
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Class 2: Midnight outage simulation
&lt;/h2&gt;

&lt;p&gt;Your instructor announces:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is 12:05 AM. PagerDuty has triggered a critical alert. Customers cannot complete payment transactions. Grafana shows elevated HTTP 503 errors, but all Payment API Pods appear healthy. You are the primary on-call engineer. Investigate the incident and identify the failing dependency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 1. Confirm the healthy baseline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

bash scripts/02-smoke-test.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not continue until the database check and payment request return HTTP 200.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2. Introduce the controlled failure
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;scripts/03-inject-outage.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s/03-networkpolicy-outage.yaml

kubectl get networkpolicy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nRun the smoke test and investigate.\n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/03-inject-outage.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/02-smoke-test.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When NetworkPolicy enforcement is active, expected behavior is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Payment API Pods&lt;/td&gt;
&lt;td&gt;Running, Ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL Pod&lt;/td&gt;
&lt;td&gt;Running, Ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API readiness endpoint&lt;/td&gt;
&lt;td&gt;HTTP 200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database connectivity endpoint&lt;/td&gt;
&lt;td&gt;HTTP 503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Synthetic payment request&lt;/td&gt;
&lt;td&gt;HTTP 503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application logs&lt;/td&gt;
&lt;td&gt;Database connectivity errors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If requests still succeed, verify that NetworkPolicy enforcement is enabled. Do not assume the incident is active simply because &lt;code&gt;kubectl apply&lt;/code&gt; succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3. Investigate the incident
&lt;/h2&gt;

&lt;p&gt;Start with the Kubernetes resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide

kubectl get deployments &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get endpointslices &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the API Deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe deployment payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the API Pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pods &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect application logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-log-requests&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for errors indicating the application cannot communicate with PostgreSQL.&lt;/p&gt;

&lt;p&gt;Inspect the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl logs deployment/lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the NetworkPolicies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get networkpolicy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl describe networkpolicy block-postgres-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get networkpolicy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check rollout history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl rollout status deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: In this particular incident, the API Deployment may have had no recent rollout at all. The problem is a networking configuration change, not necessarily a new container version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Student investigation script
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;scripts/04-investigate.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;NS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;payments-incident-lab

kubectl get pods,deploy,svc,endpointslices &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

kubectl describe deployment payment-api &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

kubectl logs deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-log-requests&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10

kubectl get networkpolicy &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; yaml

kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/payment-api &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/04-investigate.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Root-cause analysis
&lt;/h3&gt;

&lt;p&gt;In this lab, the NetworkPolicy selects the PostgreSQL Pod and allows no incoming traffic. The application can still start and answer &lt;code&gt;/readyz&lt;/code&gt;, but new PostgreSQL connections fail.&lt;/p&gt;

&lt;p&gt;The root cause is therefore database connectivity blocked by Kubernetes NetworkPolicy, not a crashed application Pod.&lt;/p&gt;

&lt;p&gt;A blind &lt;code&gt;kubectl rollout undo&lt;/code&gt; of the Payment API is not an appropriate fix because the network policy would remain in effect.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part E — Restore service
&lt;/h1&gt;

&lt;p&gt;After identifying the policy and following the classroom change procedure, remove the offending rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete networkpolicy block-postgres-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check that the application is still available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;120s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the payment tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/02-smoke-test.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the database contains the successful synthetic payments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  deployment/lab-postgres &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  psql &lt;span class="nt"&gt;-U&lt;/span&gt; labuser &lt;span class="nt"&gt;-d&lt;/span&gt; payments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'SELECT id, amount_cents, status, created_at
      FROM simulated_payments
      ORDER BY id DESC
      LIMIT 10;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;scripts/05-recover.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

kubectl delete networkpolicy block-postgres-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ignore-not-found&lt;/span&gt;

kubectl rollout status deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;120s

bash scripts/02-smoke-test.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash scripts/05-recover.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recovery is verified when new database checks and synthetic payment requests succeed. In a real payment system, the application and database teams would also need to verify transaction integrity, retries and reconciliation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part F — Terraform and AWS RDS investigation
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Why Terraform matters
&lt;/h2&gt;

&lt;p&gt;In a production environment, PostgreSQL may run on Amazon RDS rather than inside Kubernetes.&lt;/p&gt;

&lt;p&gt;Suppose a GitHub Actions workflow applies a Terraform change that accidentally removes the security-group rule allowing the EKS application to reach RDS on TCP port 5432.&lt;/p&gt;

&lt;p&gt;The symptoms could resemble our lab: Kubernetes Pods are Ready, but application requests fail because database connections cannot be established.&lt;/p&gt;

&lt;p&gt;The two failure mechanisms are different:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Classroom lab&lt;/th&gt;
&lt;th&gt;Production reference scenario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes NetworkPolicy blocks PostgreSQL ingress&lt;/td&gt;
&lt;td&gt;AWS security group blocks EKS-to-RDS traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL runs inside EKS&lt;/td&gt;
&lt;td&gt;PostgreSQL runs on Amazon RDS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix the Kubernetes NetworkPolicy&lt;/td&gt;
&lt;td&gt;Restore the correct AWS security-group rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Investigate &lt;code&gt;kubectl get networkpolicy&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Investigate AWS VPC, security groups, CloudTrail and Terraform changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  File 9 — &lt;code&gt;terraform/EXAMPLE_ONLY.tf&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This is a teaching example. Do not run &lt;code&gt;terraform apply&lt;/code&gt; on this file against an existing AWS environment. The correct security group and identity must first be established.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"rds_security_group_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"approved_eks_application_security_group_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc_security_group_ingress_rule"&lt;/span&gt; &lt;span class="s2"&gt;"postgres_from_eks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rds_security_group_id&lt;/span&gt;

  &lt;span class="nx"&gt;referenced_security_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;approved_eks_application_security_group_id&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;ip_protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;

  &lt;span class="nx"&gt;from_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;

  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Approved EKS application traffic to PostgreSQL"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Terraform investigation commands
&lt;/h3&gt;

&lt;p&gt;For an actual managed Terraform project, first identify the correct repository, workspace, state and pipeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform version

terraform workspace show

terraform state list

terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review the plan and the last GitHub Actions run. Determine whether a rule was removed, replaced, or changed.&lt;/p&gt;

&lt;p&gt;Do not assume that the latest Terraform deployment caused the incident merely because it happened recently. Correlate the change timestamp with application errors, RDS connection failures, AWS configuration history and network evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD investigation
&lt;/h2&gt;

&lt;p&gt;Students should be able to explain this workflow:&lt;/p&gt;

&lt;p&gt;Developer creates pull request&lt;/p&gt;

&lt;p&gt;GitHub Actions: test, build, security checks&lt;/p&gt;

&lt;p&gt;Terraform fmt, validate, plan and review&lt;/p&gt;

&lt;p&gt;Approved infrastructure change&lt;/p&gt;

&lt;p&gt;Application deployment and post-deploy tests&lt;/p&gt;

&lt;p&gt;Prometheus / Grafana validation and alerting&lt;/p&gt;

&lt;p&gt;An important production lesson: a pipeline can finish successfully while the system is broken. Successful execution of &lt;code&gt;terraform apply&lt;/code&gt; only proves Terraform applied the requested changes; it does not prove payment processing still works.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part G — Three-class teaching schedule
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Activities&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Class 1&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;Architecture, team roles, Docker, PostgreSQL, EKS Deployment, Services, API testing, Grafana&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class 2&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;PagerDuty ticket, incident injection, logs, database investigation, NetworkPolicy, Terraform and CI/CD analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class 3&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;Recovery, verification, incident report, prevention, mock interview and follow-up questions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Class 1 — Build the platform
&lt;/h2&gt;

&lt;p&gt;Students must finish with a working Payment API, two healthy replicas, PostgreSQL connectivity, successful synthetic payments and visible metrics.&lt;/p&gt;

&lt;p&gt;Instructor questions: What is the difference between a Deployment and a Service? Why do we use a Secret? What does a readiness probe check? How does the API connect to PostgreSQL? Why might database availability differ from Pod readiness?&lt;/p&gt;

&lt;h2&gt;
  
  
  Class 2 — Investigate the outage
&lt;/h2&gt;

&lt;p&gt;Do not immediately tell students the root cause. Present the incident ticket and ask them to gather evidence.&lt;/p&gt;

&lt;p&gt;Students should identify that the Pods are Ready, the database Pod is running, the API reports database connectivity errors, and a NetworkPolicy is blocking the connection.&lt;/p&gt;

&lt;p&gt;Instructor questions: Is this an application crash? Why are there no container restarts? Why does the HTTP 503 error appear? Why would restarting the Pods not fix the problem? What evidence would connect this to a Terraform change in AWS?&lt;/p&gt;

&lt;h2&gt;
  
  
  Class 3 — Recover and explain
&lt;/h2&gt;

&lt;p&gt;Students must explain the root cause, restore connectivity, validate synthetic payments, review Grafana, and present an incident report.&lt;/p&gt;

&lt;p&gt;They should distinguish between mitigation (restoring service), root cause (identifying the failing rule), and prevention (adding change controls and connectivity tests).&lt;/p&gt;

&lt;h1&gt;
  
  
  Part H — Interview preparation
&lt;/h1&gt;

&lt;p&gt;These are the questions students should practice aloud, with technically accurate answers.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Your Pods are Running and Ready, but customers receive HTTP 503. What do you investigate?
&lt;/h3&gt;

&lt;p&gt;Sample answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I would first assess the customer impact using Grafana or another monitoring tool. I would check the HTTP 5xx error rate, latency, and affected endpoints. Then I would inspect the Kubernetes Deployments, Pods, Services and application logs. Since the Pods are Ready, I would not assume Kubernetes itself is healthy end to end. I would investigate downstream dependencies such as the database, networking, authentication and external APIs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. How can all Pods be Ready while payment processing is failing?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubernetes readiness only checks what the configured readiness probe verifies. If the probe checks only the application process, the Pod can remain Ready even when the database is unreachable. That's why I would also monitor transaction success rates and perform synthetic end-to-end checks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. What would you check first to determine whether the database is the problem?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would examine the application logs for connection timeouts, authentication failures, connection-pool exhaustion and query errors. Then I would check database health and connectivity. I would also review database metrics such as CPU, memory, connections, I/O and wait events.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. How would you prove that a Terraform change caused the outage?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would correlate the incident start time with the Terraform pipeline execution. Then I would review the Terraform plan, the applied changes and AWS configuration history. If the change removed a required RDS security-group rule, I would verify that the affected application could no longer reach the database. I would use that evidence to establish causation rather than relying only on timing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Would you immediately run &lt;code&gt;kubectl rollout undo&lt;/code&gt;?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not automatically. I would first determine whether the application deployment caused the failure. If the root cause is a network rule or database configuration, rolling back the application might not help. I would follow the incident runbook and select the safest mitigation supported by the evidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  6. What is the difference between HTTP 502, 503 and 504?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Common example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;502 Bad Gateway&lt;/td&gt;
&lt;td&gt;Gateway received an invalid response from an upstream server&lt;/td&gt;
&lt;td&gt;Reverse proxy cannot obtain a valid upstream response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;503 Service Unavailable&lt;/td&gt;
&lt;td&gt;Service cannot currently handle the request&lt;/td&gt;
&lt;td&gt;Payment API deliberately returns 503 when database is unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;504 Gateway Timeout&lt;/td&gt;
&lt;td&gt;Gateway did not receive an upstream response in time&lt;/td&gt;
&lt;td&gt;ALB or proxy times out waiting for an application response&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A database timeout does not automatically mean the customer receives 504. In this lab, the application catches the error and explicitly returns 503.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Who would you involve in a SEV-1 incident?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would follow the company's incident-response procedure. Depending on the impact, I would involve the incident commander, application engineers, database team, platform engineers and release team. I would communicate the symptoms, current impact, evidence collected, and mitigation plan so the teams could work in parallel.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  8. How would you investigate a delayed failure after a successful release?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would compare the release timestamp with the first customer errors and infrastructure changes. I would investigate whether the failure was triggered by connection-pool exhaustion, database load, expired credentials, a scheduled job, network changes or traffic growth. I would also check whether the application had existing connections that continued working temporarily before new connections started failing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  9. What database metrics would you inspect?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would review CPU utilization, available memory, connection counts, disk I/O, read and write latency, active sessions, slow queries, locks and wait events. I would use those metrics to distinguish between database overload, slow queries, connection exhaustion and network connectivity failures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  10. What is a database connection pool?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A connection pool maintains reusable database connections so an application doesn't need to establish a new connection for every request. If the pool is exhausted or connections become invalid, requests may wait, time out or fail. I would check active connections, pool utilization, wait time and timeout settings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  11. How would you restore service without creating additional risk?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would first identify the failing dependency and the last known good configuration. I would coordinate the mitigation through the incident process, restore only the necessary access, and verify recovery using application requests, database checks, monitoring and synthetic transactions. I would avoid broad security-group changes or unnecessary restarts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  12. What would you do after recovery?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I would confirm that error rates and payment success metrics returned to baseline. Then I would document the incident timeline, impact, root cause, mitigation and prevention actions. I would recommend post-deployment database connectivity checks, better dependency monitoring, Terraform plan review and appropriate change approvals.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Part I — Student incident report
&lt;/h1&gt;

&lt;p&gt;Every student must complete this report after Class 3.&lt;/p&gt;

&lt;p&gt;Incident report template&lt;/p&gt;

&lt;p&gt;Incident ID: INC-2026-1047&lt;/p&gt;

&lt;p&gt;Severity: SEV-1 (training scenario)&lt;/p&gt;

&lt;p&gt;Affected service: Payment Processing API&lt;/p&gt;

&lt;p&gt;Detection: PagerDuty / Grafana&lt;/p&gt;

&lt;p&gt;Start time: Record actual lab injection time&lt;/p&gt;

&lt;p&gt;Recovery time: Record actual successful verification time&lt;/p&gt;

&lt;p&gt;Customer impact: Synthetic payment requests failed in the lab; production customer impact is hypothetical&lt;/p&gt;

&lt;p&gt;Observed symptoms: API Pods Ready, database-dependent requests returned HTTP 503&lt;/p&gt;

&lt;p&gt;Root cause: PostgreSQL ingress blocked by Kubernetes NetworkPolicy&lt;/p&gt;

&lt;p&gt;Mitigation: Removed the offending policy in the isolated lab&lt;/p&gt;

&lt;p&gt;Verification: Database checks and synthetic payments returned HTTP 200&lt;/p&gt;

&lt;p&gt;Prevention: Network change reviews, dependency checks, monitoring, and automated connectivity tests&lt;/p&gt;

&lt;p&gt;Evidence: Attach command outputs, relevant logs, Grafana screenshots and the exact configuration change.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 10 — &lt;code&gt;scripts/01-check.sh&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

kubectl get nodes
kubectl get ns
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring

kubectl get pods,deploy,svc &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get networkpolicy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 11 — &lt;code&gt;scripts/06-cleanup.sh&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Use only after the classes are finished. This deletes the entire training namespace and its synthetic database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'Delete ENTIRE payments-incident-lab namespace? Type DELETE: '&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  answer

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$answer&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"DELETE"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;kubectl delete namespace payments-incident-lab
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Canceled."&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To clean up the optional ServiceMonitor separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete servicemonitor payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ignore-not-found&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final student challenge
&lt;/h2&gt;

&lt;p&gt;Your instructor will ask:&lt;/p&gt;

&lt;p&gt;"It is 12:05 AM. Your Payment API has two healthy Pods, PostgreSQL is Running, and your application deployment has not changed. However, payment requests are returning HTTP 503. What are your first actions, how do you identify the root cause, who do you involve, and how do you restore service safely?"&lt;/p&gt;

&lt;p&gt;You must be able to explain the investigation in your own words, demonstrate the relevant commands, identify the exact failed dependency, and verify the recovery.&lt;/p&gt;

&lt;p&gt;Your goal is not to memorize commands. Your goal is to think and communicate like a DevOps/SRE engineer responding to a production incident.&lt;/p&gt;

&lt;p&gt;JumpToTech DevOps Engineering · Practical Incident Response Training&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JumpToTech DevOps Production Incident Lab #2 The Midnight Payment Processing Incident</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Fri, 30 Oct 2026 01:05:13 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-devops-production-incident-lab-2-the-midnight-payment-processing-incident-575m</link>
      <guid>https://dev.to/jumptotech/jumptotech-devops-production-incident-lab-2-the-midnight-payment-processing-incident-575m</guid>
      <description>&lt;p&gt;Student training handbook | 3 classes × 3 hours | AWS EKS · Terraform · GitHub Actions · PostgreSQL RDS · Prometheus · Grafana · PagerDuty&lt;/p&gt;

&lt;p&gt;Students, welcome to your next production incident investigation.&lt;/p&gt;

&lt;p&gt;In our previous incident, you investigated Kubernetes Pods that became unavailable after a deployment. This time, the challenge is different.&lt;/p&gt;

&lt;p&gt;All Kubernetes Pods are healthy. The deployment succeeded. The application is reachable. But customers cannot complete payments.&lt;/p&gt;

&lt;p&gt;This is the type of scenario that tests whether you understand the entire production system—not just Kubernetes commands.&lt;/p&gt;

&lt;p&gt;You will work as an on-call DevOps/SRE engineer at a fictional enterprise payment platform. The scenario is designed to resemble incidents that could occur in large financial technology companies, banks, and e-commerce organizations. All company details, ticket numbers, figures, and incident events below are fictional training data.&lt;/p&gt;

&lt;p&gt;By the end of three classes, you should be able to investigate a multi-system incident, identify an infrastructure change, coordinate with other engineering teams, restore service safely, explain database connectivity, and defend your decisions during a technical interview.&lt;/p&gt;

&lt;p&gt;INC-2026-1047 — Payment Authorization Failures&lt;/p&gt;

&lt;p&gt;SEV-1&lt;/p&gt;

&lt;p&gt;Payment success rate&lt;/p&gt;

&lt;h1&gt;
  
  
  41%
&lt;/h1&gt;

&lt;p&gt;Baseline: 99.95%&lt;/p&gt;

&lt;p&gt;HTTP 5xx rate&lt;/p&gt;

&lt;h1&gt;
  
  
  37%
&lt;/h1&gt;

&lt;p&gt;On payment API&lt;/p&gt;

&lt;p&gt;Kubernetes Pods&lt;/p&gt;

&lt;h1&gt;
  
  
  12/12
&lt;/h1&gt;

&lt;p&gt;Ready and Running&lt;/p&gt;

&lt;p&gt;Database&lt;/p&gt;

&lt;h1&gt;
  
  
  Available
&lt;/h1&gt;

&lt;p&gt;RDS instance is running&lt;/p&gt;

&lt;p&gt;Incident clue: A Terraform deployment completed approximately 20 minutes before the payment failures began.&lt;/p&gt;

&lt;p&gt;The critical interview question is:&lt;/p&gt;

&lt;p&gt;“If all Kubernetes Pods are healthy and the RDS database is available, why are customers receiving payment failures?”&lt;/p&gt;

&lt;p&gt;You are not allowed to answer, “I would restart the Pods,” without first explaining what evidence justifies that action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your three-class mission
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Your objective&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Class 1 — Detection and triage&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;Understand the ticket, production architecture, incident roles, and evidence collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class 2 — Deep troubleshooting&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;Investigate Kubernetes, CI/CD, Terraform, networking, and PostgreSQL; identify the root cause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class 3 — Recovery and interviews&lt;/td&gt;
&lt;td&gt;3 hours&lt;/td&gt;
&lt;td&gt;Restore service, verify transactions, complete the postmortem, and pass a mock technical interview&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You will not be given the root cause at the beginning. Your instructor will reveal additional evidence as you progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The company and production environment
&lt;/h2&gt;

&lt;p&gt;You work for NorthStar Payments, a fictional payment technology company processing transactions for online retailers.&lt;/p&gt;

&lt;p&gt;NorthStar provides payment authorization, order management, transaction history, refunds, and customer account services.&lt;/p&gt;

&lt;p&gt;The production system runs on AWS. The platform team manages infrastructure through Terraform, developers deploy applications through GitHub Actions, and SRE engineers monitor the platform using Prometheus, Grafana, CloudWatch, and PagerDuty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Production architecture
&lt;/h3&gt;

&lt;p&gt;Conceptual production architecture. AWS networking and service placement are simplified for training.&lt;/p&gt;

&lt;p&gt;The system has these components:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Responsible team&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Amazon EKS&lt;/td&gt;
&lt;td&gt;Runs containerized services&lt;/td&gt;
&lt;td&gt;Platform / SRE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment API&lt;/td&gt;
&lt;td&gt;Receives and processes payment requests&lt;/td&gt;
&lt;td&gt;Backend application team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment workers&lt;/td&gt;
&lt;td&gt;Process asynchronous events&lt;/td&gt;
&lt;td&gt;Backend application team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon RDS PostgreSQL&lt;/td&gt;
&lt;td&gt;Stores transaction and payment records&lt;/td&gt;
&lt;td&gt;Database / DBA team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Security Groups&lt;/td&gt;
&lt;td&gt;Control permitted network connections&lt;/td&gt;
&lt;td&gt;Cloud platform / security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform&lt;/td&gt;
&lt;td&gt;Provisions and changes AWS infrastructure&lt;/td&gt;
&lt;td&gt;Cloud platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;Tests and deploys infrastructure and applications&lt;/td&gt;
&lt;td&gt;DevOps / release engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus and Grafana&lt;/td&gt;
&lt;td&gt;Collect and visualize service metrics&lt;/td&gt;
&lt;td&gt;SRE / observability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch&lt;/td&gt;
&lt;td&gt;AWS infrastructure logs and metrics&lt;/td&gt;
&lt;td&gt;Cloud platform / SRE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PagerDuty&lt;/td&gt;
&lt;td&gt;Routes urgent alerts to on-call responders&lt;/td&gt;
&lt;td&gt;SRE / incident management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jira Service Management&lt;/td&gt;
&lt;td&gt;Tracks incident tickets and investigation&lt;/td&gt;
&lt;td&gt;Service management&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Example workload sizes
&lt;/h3&gt;

&lt;p&gt;For this case study, the production environment has 12 Payment API Pods, 6 background workers, 3 Availability Zones, and one Multi-AZ PostgreSQL RDS deployment. These are illustrative values, not actual figures from any bank.&lt;/p&gt;

&lt;p&gt;The Payment API has a readiness endpoint at &lt;code&gt;/ready&lt;/code&gt;, which checks whether the HTTP process is responsive. It does not check whether the application can reach PostgreSQL. That design choice will become important.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Your production engineering team
&lt;/h2&gt;

&lt;p&gt;An enterprise incident is not normally handled by one engineer working alone. You may be the first person paged, but different teams own different systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Incident response team structure
&lt;/h2&gt;

&lt;p&gt;Incident Commander&lt;/p&gt;

&lt;p&gt;Coordinates response and decisions&lt;/p&gt;

&lt;p&gt;Primary SRE&lt;/p&gt;

&lt;p&gt;Triage, metrics, Kubernetes&lt;/p&gt;

&lt;p&gt;Platform Engineer&lt;/p&gt;

&lt;p&gt;Terraform, VPC, security groups&lt;/p&gt;

&lt;p&gt;Backend Engineer&lt;/p&gt;

&lt;p&gt;Payment API, application logs&lt;/p&gt;

&lt;p&gt;Database Engineer&lt;/p&gt;

&lt;p&gt;RDS, SQL, connection health&lt;/p&gt;

&lt;p&gt;Release Engineer&lt;/p&gt;

&lt;p&gt;CI/CD, change history&lt;/p&gt;

&lt;p&gt;Security Engineer&lt;/p&gt;

&lt;p&gt;Network access, policy review&lt;/p&gt;

&lt;p&gt;Customer support and business stakeholders receive coordinated status updates through the incident communication process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who is responsible for what?
&lt;/h3&gt;

&lt;p&gt;Primary on-call DevOps/SRE engineer — your role&lt;/p&gt;

&lt;p&gt;You acknowledge the alert, establish the initial technical picture, identify impacted components, collect evidence, coordinate with the incident team, and execute approved operational actions within your access and authority.&lt;/p&gt;

&lt;p&gt;Incident Commander&lt;/p&gt;

&lt;p&gt;Owns coordination, severity management, escalation, communications, and ensuring someone is assigned to each workstream. The incident commander does not necessarily perform the technical fix.&lt;/p&gt;

&lt;p&gt;Application engineer&lt;/p&gt;

&lt;p&gt;Investigates payment request failures, database client errors, connection pool behavior, retry logic, and application code.&lt;/p&gt;

&lt;p&gt;Cloud platform engineer&lt;/p&gt;

&lt;p&gt;Investigates AWS networking, Terraform state and plans, security groups, IAM, EKS networking, and infrastructure changes. This engineer normally owns the corrective Terraform pull request.&lt;/p&gt;

&lt;p&gt;Database engineer&lt;/p&gt;

&lt;p&gt;Checks database availability, active connections, PostgreSQL errors, query performance, locks, replication or failover state, and database-side access settings.&lt;/p&gt;

&lt;p&gt;Release engineer&lt;/p&gt;

&lt;p&gt;Finds the GitHub Actions deployment run, commit SHA, pull request, approvers, change window, and any simultaneous releases.&lt;/p&gt;

&lt;p&gt;Security engineer&lt;/p&gt;

&lt;p&gt;Reviews whether a proposed security group change is permitted and ensures recovery does not introduce unnecessary network exposure.&lt;/p&gt;

&lt;p&gt;Customer support and communications&lt;/p&gt;

&lt;p&gt;Collect customer reports and distribute approved incident updates. They should not receive raw database credentials or sensitive customer records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interview question
&lt;/h3&gt;

&lt;p&gt;“If you are the primary on-call engineer, are you personally responsible for fixing every component?”&lt;/p&gt;

&lt;p&gt;A strong answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I am responsible for responding to the incident, understanding the impact, and driving technical triage within my role. I would engage the correct service owners for specialized components such as RDS, networking, and application code. We work together under the incident response process to restore service safely.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Where the production ticket comes from
&lt;/h2&gt;

&lt;p&gt;In this scenario, Prometheus detects the elevated error rate and sends the alert to Alertmanager. Alertmanager routes it to PagerDuty. PagerDuty pages the primary on-call engineer. An incident ticket is then created in Jira Service Management through the company's configured integration or incident workflow.&lt;/p&gt;

&lt;p&gt;PagerDuty — Production Alert&lt;/p&gt;

&lt;p&gt;12:15 AM · Payment Platform · Primary On-Call&lt;/p&gt;

&lt;h2&gt;
  
  
  High Payment Failure Rate
&lt;/h2&gt;

&lt;p&gt;Service: &lt;code&gt;payment-api-prod&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Environment: &lt;code&gt;production&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Cluster: &lt;code&gt;northstar-prod-eks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Namespace: &lt;code&gt;payments-prod&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Trigger: HTTP 5xx rate exceeds the configured threshold for 5 minutes.&lt;/p&gt;

&lt;p&gt;Customer payment authorization is degraded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Jira incident ticket
&lt;/h3&gt;

&lt;p&gt;Jira Service Management · INC-2026-1047&lt;/p&gt;

&lt;p&gt;P1&lt;/p&gt;

&lt;p&gt;Payment authorization failures — customer impact&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Investigating&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Assigned group&lt;/td&gt;
&lt;td&gt;Production SRE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First detected&lt;/td&gt;
&lt;td&gt;12:15 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer symptoms&lt;/td&gt;
&lt;td&gt;Payment errors and timeouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Related change&lt;/td&gt;
&lt;td&gt;CHG-2026-318 — Terraform network update&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impacted service&lt;/td&gt;
&lt;td&gt;Payment API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Description&lt;/p&gt;

&lt;p&gt;Payment success rate has dropped from approximately 99.95% to 41%. Payment API 5xx errors have increased. Kubernetes reports all 12 API Pods as Ready. RDS instance status is Available. Investigate application dependencies, infrastructure changes, and customer impact.&lt;/p&gt;

&lt;p&gt;Initial assignment: Primary on-call SRE.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where else might you learn about the incident?
&lt;/h3&gt;

&lt;p&gt;You may see the same incident in the PagerDuty mobile app, Slack incident channel, Jira queue, Grafana dashboard, CloudWatch alarms, or customer support escalation. Different companies use different integrations.&lt;/p&gt;

&lt;p&gt;Student question: “What is the difference between an alert, an incident ticket, and a change ticket?”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An alert is a monitoring signal that requires attention.&lt;/li&gt;
&lt;li&gt;An incident ticket tracks the unexpected service disruption and response.&lt;/li&gt;
&lt;li&gt;A change ticket documents an intended production change, its approvals, timing, and rollback plan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. The incident timeline
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;11:20 PM&lt;/td&gt;
&lt;td&gt;GitHub Actions infrastructure pipeline starts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:28 PM&lt;/td&gt;
&lt;td&gt;Terraform plan is reviewed and approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:40 PM&lt;/td&gt;
&lt;td&gt;Terraform apply completes successfully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:45 PM&lt;/td&gt;
&lt;td&gt;Infrastructure pipeline reports success&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:00 AM&lt;/td&gt;
&lt;td&gt;Payment API error rate begins increasing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:10 AM&lt;/td&gt;
&lt;td&gt;Payment success rate drops sharply&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:15 AM&lt;/td&gt;
&lt;td&gt;PagerDuty pages the primary on-call engineer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:17 AM&lt;/td&gt;
&lt;td&gt;SRE acknowledges and begins triage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:22 AM&lt;/td&gt;
&lt;td&gt;Incident Commander engaged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:30 AM&lt;/td&gt;
&lt;td&gt;Database connectivity errors identified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:40 AM&lt;/td&gt;
&lt;td&gt;Recent infrastructure change becomes the leading suspect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12:50 AM&lt;/td&gt;
&lt;td&gt;Recovery change is prepared and reviewed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:05 AM&lt;/td&gt;
&lt;td&gt;Connectivity restored; application recovery monitored&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:20 AM&lt;/td&gt;
&lt;td&gt;Payment success and error metrics return to baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:35 AM&lt;/td&gt;
&lt;td&gt;Incident moves into observation and post-incident follow-up&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These timestamps are the planned case-study narrative, not measured outcomes from the student lab.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The mystery: why healthy Pods cannot process payments
&lt;/h2&gt;

&lt;p&gt;At first, you check Kubernetes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                           READY   STATUS    RESTARTS
payment-api-7d8f5b6c9-a1b2c    1/1     Running   0
payment-api-7d8f5b6c9-d3e4f    1/1     Running   0
payment-api-7d8f5b6c9-g5h6i    1/1     Running   0
...
12 payment-api Pods Ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you inspect the Deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment payment-api &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME          READY   UP-TO-DATE   AVAILABLE
payment-api   12/12   12           12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You inspect RDS in AWS and see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB instance: northstar-payments-prod
Status: Available
Engine: PostgreSQL
Port: 5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yet the payment API returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;503&lt;/span&gt; &lt;span class="ne"&gt;Service Unavailable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Application logs contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR payment authorization failed
ERROR could not establish database connection
ERROR connection timeout to postgres endpoint:5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the central lesson of the incident:&lt;/p&gt;

&lt;p&gt;Kubernetes Pod readiness, application dependency health, and successful business transactions are three different things.&lt;/p&gt;

&lt;p&gt;A database can be operational while a particular application cannot connect to it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Class 1 — Detect, assess, and investigate
&lt;/h1&gt;

&lt;p&gt;3 hours · Students act as the primary on-call SRE&lt;/p&gt;

&lt;h2&gt;
  
  
  Class 1 schedule
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Activity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0:00–0:25&lt;/td&gt;
&lt;td&gt;Read incident ticket, identify business impact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0:25–0:50&lt;/td&gt;
&lt;td&gt;Understand team structure and incident communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0:50–1:20&lt;/td&gt;
&lt;td&gt;Investigate Kubernetes health&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:20–1:50&lt;/td&gt;
&lt;td&gt;Investigate Grafana and HTTP errors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:50–2:20&lt;/td&gt;
&lt;td&gt;Check application logs and database connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:20–2:45&lt;/td&gt;
&lt;td&gt;Identify next investigation steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:45–3:00&lt;/td&gt;
&lt;td&gt;Mock interview and handover&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Task 1 — Your first five minutes
&lt;/h2&gt;

&lt;p&gt;You receive the PagerDuty alert. You are the primary on-call engineer.&lt;/p&gt;

&lt;p&gt;Your interviewer asks:&lt;/p&gt;

&lt;p&gt;“What would you do immediately?”&lt;/p&gt;

&lt;p&gt;A model response:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“First, I would acknowledge the PagerDuty alert. Then I would open our monitoring dashboards to validate the impact, including payment success rate, HTTP 5xx errors, latency, and Kubernetes availability. I would determine whether the issue affects all customers or a subset, identify the impacted services, and follow our incident escalation procedure. I would not immediately restart Pods because the evidence does not yet show that restarting them would help.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What you should ask the incident team
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Which payment operations are failing: authorization, capture, refund, or all of them?&lt;/li&gt;
&lt;li&gt;When did the errors begin?&lt;/li&gt;
&lt;li&gt;Are all customers affected or only certain regions or merchants?&lt;/li&gt;
&lt;li&gt;Did an application release, infrastructure change, or database maintenance occur?&lt;/li&gt;
&lt;li&gt;Are failures isolated to one service or shared by multiple services?&lt;/li&gt;
&lt;li&gt;Are transactions being rejected, timing out, or potentially duplicated?&lt;/li&gt;
&lt;li&gt;Is there a known-good recovery procedure?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Important: During a payment incident, do not blindly retry failed transactions. A timeout does not necessarily mean a payment was never processed. The application and payment teams must verify transaction status and idempotency before retrying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 2 — Kubernetes investigation
&lt;/h2&gt;

&lt;p&gt;Run the following commands in the designated training namespace. In the production case study, the namespace is &lt;code&gt;payments-prod&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Confirm cluster context before running commands&lt;/span&gt;
kubectl config current-context

&lt;span class="c"&gt;# Inspect deployments&lt;/span&gt;
kubectl get deployments &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Inspect Pods and their nodes&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;-o&lt;/span&gt; wide

&lt;span class="c"&gt;# Inspect Services&lt;/span&gt;
kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Inspect Service endpoints&lt;/span&gt;
kubectl get endpointslices &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Inspect nodes&lt;/span&gt;
kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide

&lt;span class="c"&gt;# Inspect the payment Deployment&lt;/span&gt;
kubectl describe deployment payment-api &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Inspect one payment Pod&lt;/span&gt;
kubectl describe pod POD_NAME &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Review application logs&lt;/span&gt;
kubectl logs POD_NAME &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What should you conclude?
&lt;/h3&gt;

&lt;p&gt;If all Pods are Ready, you have evidence that Kubernetes considers them eligible to serve traffic. You do not yet have evidence that the payment workflow is functioning correctly.&lt;/p&gt;

&lt;p&gt;Check the readiness probe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you discover:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/ready&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
  &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The endpoint checks whether the application process can respond, but it does not test PostgreSQL connectivity.&lt;/p&gt;

&lt;p&gt;Interview follow-up: “Should a readiness probe always connect to the database?”&lt;/p&gt;

&lt;p&gt;No. Dependency-aware readiness checks can be useful, but they require careful design. If every Pod fails readiness during a shared database outage, the Service may lose all endpoints, potentially worsening recovery. Teams often separate lightweight process readiness, dependency health, and end-to-end business transaction monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 3 — Grafana investigation
&lt;/h2&gt;

&lt;p&gt;Your instructor should show four monitoring panels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example incident dashboard
&lt;/h3&gt;

&lt;p&gt;Available API replicas&lt;/p&gt;

&lt;h1&gt;
  
  
  12 / 12
&lt;/h1&gt;

&lt;p&gt;Stable&lt;/p&gt;

&lt;p&gt;Payment success rate&lt;/p&gt;

&lt;h1&gt;
  
  
  41%
&lt;/h1&gt;

&lt;p&gt;Severely degraded&lt;/p&gt;

&lt;p&gt;HTTP 5xx error rate&lt;/p&gt;

&lt;h1&gt;
  
  
  37%
&lt;/h1&gt;

&lt;p&gt;Elevated&lt;/p&gt;

&lt;p&gt;Database connection failures&lt;/p&gt;

&lt;h1&gt;
  
  
  Increasing
&lt;/h1&gt;

&lt;p&gt;Application-side metric&lt;/p&gt;

&lt;h3&gt;
  
  
  PromQL examples
&lt;/h3&gt;

&lt;p&gt;These queries assume that the required Kubernetes and application metrics are actually collected. Metric names such as &lt;code&gt;http_requests_total&lt;/code&gt; and &lt;code&gt;payment_transactions_total&lt;/code&gt; are example application instrumentation; they do not appear automatically from kube-state-metrics.&lt;/p&gt;

&lt;p&gt;Available replicas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_status_replicas_available&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payments-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desired replicas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_spec_replicas&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payments-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTP 5xx percentage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http_requests_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="s2"&gt;"5.."&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nb"&gt;clamp_min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http_requests_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])),&lt;/span&gt;
  &lt;span class="mf"&gt;0.001&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Payment success percentage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_transactions_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="nb"&gt;clamp_min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_transactions_total&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])),&lt;/span&gt;
  &lt;span class="mf"&gt;0.001&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;95th percentile HTTP latency&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nb"&gt;histogram_quantile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;le&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http_request_duration_seconds_bucket&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;      &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"payment-api"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For HTTP status-code metrics, instrument the application or collect appropriate ingress/load-balancer metrics. Prometheus cannot derive HTTP 503 counts from Pod readiness alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interviewer asks
&lt;/h3&gt;

&lt;p&gt;“Grafana shows all 12 Pods healthy but the payment success rate is 41%. Where do you investigate next?”&lt;/p&gt;

&lt;p&gt;A strong response:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I would investigate the application request path and its dependencies. I would review payment API logs, trace failed requests, check database connection metrics, and test connectivity from the application network. I would also review recent infrastructure and application changes.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Task 4 — Application logs
&lt;/h2&gt;

&lt;p&gt;Example logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00:11:42 INFO  POST /api/payments/authorize
00:11:42 ERROR database connection timeout
00:11:42 ERROR SQLSTATE 08001
00:11:42 WARN  payment authorization unavailable
00:11:42 INFO  response_status=503 duration_ms=5002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain to the instructor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What does &lt;code&gt;SQLSTATE 08001&lt;/code&gt; suggest?&lt;/li&gt;
&lt;li&gt;Does this prove the database server has crashed?&lt;/li&gt;
&lt;li&gt;What is the difference between a connection timeout and an authentication failure?&lt;/li&gt;
&lt;li&gt;Why might the application return 503 while its Pod remains Ready?&lt;/li&gt;
&lt;li&gt;Which team should investigate the database, and which team should investigate the application?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A useful answer to question 2:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“No. A database connection failure can result from networking, security groups, routing, DNS, authentication, database capacity, or a database outage. I would test each layer before deciding which component is responsible.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Class 1 communication exercise
&lt;/h2&gt;

&lt;p&gt;Students should practice this update to the incident commander:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incident update — Payment API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have confirmed significant customer-facing payment failures. Payment success rate has dropped to approximately 41%, and HTTP 5xx errors are elevated.&lt;/p&gt;

&lt;p&gt;All 12 Payment API Pods remain Ready, and the RDS instance reports Available. However, application logs show PostgreSQL connection timeouts.&lt;/p&gt;

&lt;p&gt;We are investigating the application-to-database network path and reviewing recent infrastructure changes with the platform and database teams.&lt;/p&gt;

&lt;p&gt;The root cause is not yet confirmed. Our priority is restoring payment authorization safely and preventing duplicate transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class 1 homework
&lt;/h3&gt;

&lt;p&gt;Students should submit a short incident update, the commands they would use, their initial hypotheses, and an explanation of why healthy Pods do not guarantee healthy payment processing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Class 2 — Terraform, CI/CD, networking, and database
&lt;/h1&gt;

&lt;p&gt;3 hours · Deep technical investigation&lt;/p&gt;

&lt;h2&gt;
  
  
  Class 2 schedule
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Activity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0:00–0:25&lt;/td&gt;
&lt;td&gt;Review Class 1 evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0:25–0:55&lt;/td&gt;
&lt;td&gt;Trace the payment request to PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0:55–1:25&lt;/td&gt;
&lt;td&gt;Investigate database connectivity and metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:25–1:55&lt;/td&gt;
&lt;td&gt;Review GitHub Actions and Terraform change history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:55–2:25&lt;/td&gt;
&lt;td&gt;Compare security group rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:25–2:45&lt;/td&gt;
&lt;td&gt;Confirm the cause and propose recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:45–3:00&lt;/td&gt;
&lt;td&gt;Technical interview challenge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Task 1 — Understand the database connection
&lt;/h2&gt;

&lt;p&gt;The payment application uses PostgreSQL to store payment transactions.&lt;/p&gt;

&lt;p&gt;Example database tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;payment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;merchant_id&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount_cents&lt;/span&gt; &lt;span class="nb"&gt;BIGINT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;currency&lt;/span&gt; &lt;span class="nb"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;idempotency_key&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;payment_events&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;event_id&lt;/span&gt; &lt;span class="n"&gt;BIGSERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;payment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;event_type&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example payment statuses are &lt;code&gt;PENDING&lt;/code&gt;, &lt;code&gt;AUTHORIZED&lt;/code&gt;, &lt;code&gt;DECLINED&lt;/code&gt;, and &lt;code&gt;FAILED&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a real payment platform, financial transaction data needs additional controls, auditing, access restrictions, and carefully designed state transitions. This simplified schema is for learning connectivity and SQL troubleshooting, not a complete payment ledger.&lt;/p&gt;

&lt;h3&gt;
  
  
  Normal payment request flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Customer sends &lt;code&gt;POST /api/payments/authorize&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;ALB routes the request to the Payment API in EKS.&lt;/li&gt;
&lt;li&gt;Payment API validates the request and checks its idempotency key.&lt;/li&gt;
&lt;li&gt;Application opens or reuses a PostgreSQL connection.&lt;/li&gt;
&lt;li&gt;Application reads or writes payment state and coordinates the external authorization workflow.&lt;/li&gt;
&lt;li&gt;Application returns the appropriate response and emits metrics.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What happens if step 4 fails?&lt;/p&gt;

&lt;p&gt;The application may be unable to read or persist the payment state. It must not blindly repeat external authorization requests or assume that a timed-out transaction did not succeed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 2 — Test database connectivity
&lt;/h2&gt;

&lt;p&gt;The database engineer confirms that RDS is Available. Your next question is whether the Payment API network can reach the database endpoint on TCP port 5432.&lt;/p&gt;

&lt;p&gt;For the production case study, you would use approved access through the existing application Pod or an authorized diagnostic Pod in the same network context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Check the ServiceAccount and Pod configuration&lt;/span&gt;
kubectl get pod POD_NAME &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;-o&lt;/span&gt; yaml

&lt;span class="c"&gt;# Inspect relevant application logs&lt;/span&gt;
kubectl logs POD_NAME &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100

&lt;span class="c"&gt;# Check database DNS resolution&lt;/span&gt;
getent hosts DB_ENDPOINT

&lt;span class="c"&gt;# Check TCP connectivity&lt;/span&gt;
nc &lt;span class="nt"&gt;-vz&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; 5 DB_ENDPOINT 5432

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last two commands must run in an authorized environment with equivalent network access to the affected application, not simply on an unrelated EC2 management host. A successful connection from a bastion does not prove that an EKS Pod can connect.&lt;/p&gt;

&lt;p&gt;Expected investigation evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS resolution: successful

TCP connection:
connect to DB_ENDPOINT port 5432:
Connection timed out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This suggests a network-path problem but does not yet identify the exact AWS rule responsible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interviewer follow-ups
&lt;/h3&gt;

&lt;p&gt;“What if DNS fails?”&lt;/p&gt;

&lt;p&gt;Investigate CoreDNS, VPC DNS configuration, DNS records, resolver access, and the endpoint being used.&lt;/p&gt;

&lt;p&gt;“What if DNS works but TCP times out?”&lt;/p&gt;

&lt;p&gt;Investigate security groups, Network ACLs, routing, NetworkPolicies, database endpoint reachability, and possible network packet drops.&lt;/p&gt;

&lt;p&gt;“What if TCP succeeds but PostgreSQL authentication fails?”&lt;/p&gt;

&lt;p&gt;Investigate database credentials, IAM database authentication if configured, Secrets Manager, PostgreSQL roles, SSL requirements, and authentication settings.&lt;/p&gt;

&lt;p&gt;“What if TCP succeeds but SQL queries are slow?”&lt;/p&gt;

&lt;p&gt;Investigate query plans, locks, active sessions, connection pools, CPU, I/O, and database wait events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 3 — Inspect PostgreSQL health
&lt;/h2&gt;

&lt;p&gt;The database team runs approved diagnostic queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="c1"&gt;-- Verify database responds&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Count current connections&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;active_connections&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Inspect connection states&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check configured connection limit&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;max_connections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Review sessions waiting on resources&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;wait_event_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;wait_event&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;wait_event&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the database is responsive and the connection count is low, but Payment API Pods cannot connect, the team should investigate the network path.&lt;/p&gt;

&lt;p&gt;A low connection count alone does not prove a security group problem. It becomes useful evidence when combined with timeouts, recent changes, and network configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS RDS checks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws rds describe-db-instances &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--db-instance-identifier&lt;/span&gt; northstar-payments-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'DBInstances[0].{Status:DBInstanceStatus,Endpoint:Endpoint.Address,Port:Endpoint.Port,VpcSecurityGroups:VpcSecurityGroups}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check CloudWatch or RDS monitoring for database connections, CPU utilization, free memory, storage, and relevant logs. Enhanced Monitoring and Performance Insights/Database Insights may provide deeper diagnostics if configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 4 — Investigate the CI/CD pipeline
&lt;/h2&gt;

&lt;p&gt;The release engineer discovers a GitHub Actions workflow:&lt;/p&gt;

&lt;p&gt;GitHub Actions — Production Infrastructure&lt;/p&gt;

&lt;p&gt;Succeeded&lt;/p&gt;

&lt;p&gt;Workflow: terraform-production.yml · Completed 11:45 PM&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Checkout repository&lt;/li&gt;
&lt;li&gt; Terraform format and validate&lt;/li&gt;
&lt;li&gt; Terraform plan&lt;/li&gt;
&lt;li&gt; Production approval&lt;/li&gt;
&lt;li&gt; Terraform apply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interviewer: “If the Terraform pipeline succeeded, how could it have caused the incident?”&lt;/p&gt;

&lt;p&gt;Answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A successful Terraform apply means the requested infrastructure changes were applied. It does not prove that application connectivity or business functionality remained healthy. The pipeline may lack post-deployment integration tests or application-level validation.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Production workflow example
&lt;/h3&gt;

&lt;p&gt;Students should understand this pipeline structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production Terraform&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="c1"&gt;# Configure approved AWS OIDC credentials&lt;/span&gt;
      &lt;span class="c1"&gt;# Install a pinned, approved Terraform version&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform fmt -check&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform init -input=false&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform validate&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform plan -out=tfplan&lt;/span&gt;

  &lt;span class="c1"&gt;# Production apply should be a separate approved job.&lt;/span&gt;
  &lt;span class="c1"&gt;# Use a protected environment, artifact integrity&lt;/span&gt;
  &lt;span class="c1"&gt;# checks, and the reviewed saved plan.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a teaching skeleton, not a complete production-ready workflow. In a real pipeline, the saved plan must be securely transferred between jobs, access controlled, and applied only after approval.&lt;/p&gt;

&lt;h3&gt;
  
  
  Questions students must answer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What is the difference between &lt;code&gt;terraform plan&lt;/code&gt; and &lt;code&gt;terraform apply&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What does Terraform state store?&lt;/li&gt;
&lt;li&gt;Why use a remote backend and state locking?&lt;/li&gt;
&lt;li&gt;Why should GitHub Actions authenticate to AWS using OIDC rather than long-lived access keys?&lt;/li&gt;
&lt;li&gt;What does a protected GitHub environment accomplish?&lt;/li&gt;
&lt;li&gt;Why is manual approval useful but not sufficient?&lt;/li&gt;
&lt;li&gt;What post-apply checks would have detected the payment outage?&lt;/li&gt;
&lt;li&gt;Why can an infrastructure change fail without any new application image?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Task 5 — The Terraform change
&lt;/h2&gt;

&lt;p&gt;The platform engineer compares the previous and current security group configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before the change
&lt;/h3&gt;

&lt;p&gt;The RDS security group allows PostgreSQL access from the EKS application security group.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc_security_group_ingress_rule"&lt;/span&gt; &lt;span class="s2"&gt;"postgres_from_eks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;referenced_security_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;ip_protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After the change
&lt;/h3&gt;

&lt;p&gt;A Terraform refactor accidentally replaces the application security group reference with an unrelated security group.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc_security_group_ingress_rule"&lt;/span&gt; &lt;span class="s2"&gt;"postgres_from_eks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;referenced_security_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;management&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;ip_protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: The code is illustrative. Actual EKS Pod network traffic may use node security groups or Pod security groups depending on the VPC CNI and security-groups-for-Pods configuration. The effective source security group must be verified in the actual architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happened?
&lt;/h3&gt;

&lt;p&gt;The authorized source for PostgreSQL traffic was changed.&lt;/p&gt;

&lt;p&gt;The database remained healthy, and the EKS Pods remained Ready, but new database connections from the application network were no longer permitted by the intended ingress rule.&lt;/p&gt;

&lt;p&gt;Existing established connections may continue temporarily because AWS security groups are stateful and connection tracking can preserve some flows. As connections close, recycle, or time out, application failures may increase.&lt;/p&gt;

&lt;p&gt;This explains why the outage can appear after the Terraform apply rather than exactly when the change is made.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compare the infrastructure change
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

git diff PREVIOUS_COMMIT CURRENT_COMMIT &lt;span class="nt"&gt;--&lt;/span&gt; terraform/

terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AWS-side verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-security-groups &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-ids&lt;/span&gt; sg-EXAMPLE &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[*].IpPermissions'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not assume a security group ID from a screenshot or example. Identify the actual RDS security group and the effective source security group first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Root cause evidence chain
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Terraform changed the RDS ingress source security group.&lt;/li&gt;
&lt;li&gt;The infrastructure change occurred before the payment errors.&lt;/li&gt;
&lt;li&gt;Payment API logs show database connection timeouts.&lt;/li&gt;
&lt;li&gt;RDS remains operational and responsive from an authorized network.&lt;/li&gt;
&lt;li&gt;The application network cannot establish new TCP connections to port 5432.&lt;/li&gt;
&lt;li&gt;Restoring the approved application security group rule restores connectivity and payment processing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This combination of change history, network testing, application logs, and successful recovery provides much stronger causal evidence than timing alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class 2 interview challenge
&lt;/h3&gt;

&lt;p&gt;“How would you prove the Terraform change caused the payment failures rather than a PostgreSQL outage?”&lt;/p&gt;

&lt;p&gt;Expected answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I would compare the Terraform plan and AWS security group configuration with the last known-good state, verify that the database itself is responsive, and test connectivity from the affected application network. I would correlate the network failures with the infrastructure change and confirm that restoring the correct rule resolves the connectivity issue.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Class 3 — Recovery, prevention, and interview mastery
&lt;/h1&gt;

&lt;p&gt;3 hours · Students act as incident responders and interview candidates&lt;/p&gt;

&lt;h2&gt;
  
  
  Class 3 schedule
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Activity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0:00–0:30&lt;/td&gt;
&lt;td&gt;Decide on mitigation and evaluate rollback risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0:30–1:00&lt;/td&gt;
&lt;td&gt;Restore database connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:00–1:30&lt;/td&gt;
&lt;td&gt;Verify Kubernetes, database, and customer transactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1:30–2:00&lt;/td&gt;
&lt;td&gt;Write the incident report and preventive actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:00–2:40&lt;/td&gt;
&lt;td&gt;Advanced technical interview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:40–3:00&lt;/td&gt;
&lt;td&gt;Final individual interview assessment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Task 1 — How do you restore production?
&lt;/h2&gt;

&lt;p&gt;The platform engineer has identified the incorrect RDS security group ingress rule.&lt;/p&gt;

&lt;p&gt;The incident commander asks:&lt;/p&gt;

&lt;p&gt;“What is the safest and fastest way to restore service?”&lt;/p&gt;

&lt;p&gt;The team should evaluate two possible recovery approaches.&lt;/p&gt;

&lt;p&gt;Option A — Revert the incorrect Terraform change. Restore the previously approved application security group rule in code, review the plan, obtain the necessary approval, and apply the corrective configuration.&lt;/p&gt;

&lt;p&gt;Option B — Emergency network change. If the approved emergency procedure allows an immediate AWS-side correction, an authorized engineer can restore the exact known-good rule and subsequently reconcile Terraform code and state. This must be documented and reviewed to avoid configuration drift.&lt;/p&gt;

&lt;p&gt;Do not open PostgreSQL to &lt;code&gt;0.0.0.0/0&lt;/code&gt;, disable all security groups, or expose RDS publicly as a troubleshooting shortcut.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example corrected Terraform configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc_security_group_ingress_rule"&lt;/span&gt; &lt;span class="s2"&gt;"postgres_from_eks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;referenced_security_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;ip_protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;

  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PostgreSQL access from approved EKS application SG"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interviewer asks
&lt;/h3&gt;

&lt;p&gt;“Would you simply run &lt;code&gt;terraform apply&lt;/code&gt; again?”&lt;/p&gt;

&lt;p&gt;No. First inspect the planned changes. Applying the same incorrect configuration again would not solve the incident.&lt;/p&gt;

&lt;p&gt;“Would you run &lt;code&gt;terraform destroy&lt;/code&gt;?”&lt;/p&gt;

&lt;p&gt;No. Destroying production infrastructure would be highly dangerous and unrelated to this targeted connectivity issue.&lt;/p&gt;

&lt;p&gt;“Would you roll back the Kubernetes Deployment?”&lt;/p&gt;

&lt;p&gt;Not automatically. If the root cause is an RDS security group rule, reverting the application image may have no effect. The corrective action should target the confirmed cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 2 — Verify recovery at every layer
&lt;/h2&gt;

&lt;p&gt;After the approved rule is restored, verify the application network can connect to PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Verify application Pod health&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Verify Deployment availability&lt;/span&gt;
kubectl get deployment payment-api &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Verify Service endpoints&lt;/span&gt;
kubectl get endpointslices &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;span class="c"&gt;# Check recent application errors&lt;/span&gt;
kubectl logs deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100

&lt;span class="c"&gt;# Confirm application rollout state&lt;/span&gt;
kubectl rollout status &lt;span class="se"&gt;\&lt;/span&gt;
  deployment/payment-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-prod

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify database connectivity using an approved diagnostic path, confirm the application can perform its expected queries, and run a controlled synthetic payment test using a dedicated nonfinancial test transaction or payment-provider sandbox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recovery criteria
&lt;/h3&gt;

&lt;p&gt;Students must demonstrate all five checks&lt;/p&gt;

&lt;p&gt;Payment API can establish PostgreSQL connections&lt;/p&gt;

&lt;p&gt;Database queries succeed without exposing sensitive records&lt;/p&gt;

&lt;p&gt;Customer-facing 5xx rate returns to normal&lt;/p&gt;

&lt;p&gt;Payment success rate returns to expected baseline&lt;/p&gt;

&lt;p&gt;No unintended duplicate payments or unresolved transaction states&lt;/p&gt;

&lt;p&gt;0 of 5 recovery checks completed&lt;/p&gt;

&lt;p&gt;Remember: A green Grafana dashboard alone does not establish that customer transactions are correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task 3 — Write the post-incident report
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Postmortem — INC-2026-1047
&lt;/h2&gt;

&lt;p&gt;Incident summary&lt;/p&gt;

&lt;p&gt;Payment authorization was degraded following a production Terraform networking change.&lt;/p&gt;

&lt;p&gt;Customer impact&lt;/p&gt;

&lt;p&gt;The illustrative payment success rate declined from 99.95% to 41%, with elevated HTTP 5xx errors and latency.&lt;/p&gt;

&lt;p&gt;Technical root cause&lt;/p&gt;

&lt;p&gt;An infrastructure refactor changed the source security group allowed to reach RDS PostgreSQL on TCP port 5432. Application Pods remained Ready because their readiness checks did not verify database-dependent business functionality.&lt;/p&gt;

&lt;p&gt;Contributing factors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terraform validation confirmed configuration syntax but did not test application-to-database connectivity.&lt;/li&gt;
&lt;li&gt;The CI/CD pipeline lacked a post-apply payment workflow smoke test.&lt;/li&gt;
&lt;li&gt;The alerting design detected payment failures but did not immediately identify the affected network dependency.&lt;/li&gt;
&lt;li&gt;The readiness probe was insufficient as an indicator of end-to-end payment health.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mitigation&lt;/p&gt;

&lt;p&gt;The team restored the approved database ingress rule and verified application connectivity, transaction processing, and recovery metrics.&lt;/p&gt;

&lt;p&gt;Preventive actions&lt;/p&gt;

&lt;p&gt;Introduce security group policy checks, infrastructure change review, post-deployment connectivity testing, synthetic payment monitoring, and clearer incident runbooks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who owns the preventive actions?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;th&gt;Verification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Restore and review security group configuration&lt;/td&gt;
&lt;td&gt;Platform engineer&lt;/td&gt;
&lt;td&gt;Terraform plan and AWS configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add network policy tests to CI/CD&lt;/td&gt;
&lt;td&gt;Platform / security&lt;/td&gt;
&lt;td&gt;Automated policy checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add post-apply connectivity smoke test&lt;/td&gt;
&lt;td&gt;DevOps / SRE&lt;/td&gt;
&lt;td&gt;Successful synthetic check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Improve payment error metrics&lt;/td&gt;
&lt;td&gt;Backend team&lt;/td&gt;
&lt;td&gt;Grafana dashboard and alerts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Improve transaction reconciliation&lt;/td&gt;
&lt;td&gt;Backend / database&lt;/td&gt;
&lt;td&gt;Controlled recovery tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update incident runbook&lt;/td&gt;
&lt;td&gt;SRE&lt;/td&gt;
&lt;td&gt;Reviewed incident exercise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review production change approvals&lt;/td&gt;
&lt;td&gt;Release engineering&lt;/td&gt;
&lt;td&gt;Change audit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Practical hands-on lab — Build the failure safely
&lt;/h1&gt;

&lt;p&gt;Students, you will reproduce the application-to-database connectivity failure in your own training EKS cluster.&lt;/p&gt;

&lt;p&gt;You will not modify an actual bank, customer database, or production security group.&lt;/p&gt;

&lt;p&gt;The safest classroom version uses a PostgreSQL Pod inside a dedicated namespace and a Kubernetes NetworkPolicy to block connectivity. This reproduces the symptom and troubleshooting workflow without changing live AWS infrastructure.&lt;/p&gt;

&lt;p&gt;For the Terraform portion, you will separately review an example security group change and its plan. An optional isolated AWS RDS exercise can be added later when your instructor has prepared a dedicated account, budget, and recovery procedure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab architecture
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Step 1 — Create an isolated namespace
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2 — Deploy PostgreSQL
&lt;/h2&gt;

&lt;p&gt;This database is temporary and contains no real customer data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secret&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres-secret&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Opaque&lt;/span&gt;
&lt;span class="na"&gt;stringData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lab-only-change-me"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;labuser&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres-secret&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sh&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-c&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pg_isready -U labuser -d payments&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;50m&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;128Mi&lt;/span&gt;
            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;512Mi&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this as &lt;code&gt;postgres-lab.yaml&lt;/code&gt; and apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; postgres-lab.yaml

kubectl rollout status deployment/lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lab uses ephemeral PostgreSQL storage. Data is lost when the database Pod is replaced. That is acceptable for a disposable connectivity exercise but not for a production database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Verify normal connectivity
&lt;/h2&gt;

&lt;p&gt;Use a temporary PostgreSQL client Pod.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run payment-db-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres:16 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PGPASSWORD=lab-only-change-me"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;3600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait until it is Running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="nt"&gt;--for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready &lt;span class="se"&gt;\&lt;/span&gt;
  pod/payment-db-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;120s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run a database query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  payment-db-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  psql &lt;span class="nt"&gt;-h&lt;/span&gt; lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-U&lt;/span&gt; labuser &lt;span class="nt"&gt;-d&lt;/span&gt; payments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT 1;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ?column?
----------
        1
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This proves that the client can reach PostgreSQL before the incident is introduced.&lt;/p&gt;

&lt;p&gt;The example password is deliberately disposable. Never use real database credentials in shared class terminals or recorded commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Inject the incident
&lt;/h2&gt;

&lt;p&gt;Apply a NetworkPolicy that selects the PostgreSQL Pod and allows no incoming connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NetworkPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;block-postgres-ingress&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-incident-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;podSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab-postgres&lt;/span&gt;
  &lt;span class="na"&gt;policyTypes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
  &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save as &lt;code&gt;block-postgres.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; block-postgres.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prerequisite: The cluster must have a network policy implementation that enforces Kubernetes NetworkPolicy, such as a properly configured Amazon VPC CNI network policy agent or another compatible CNI. Otherwise, the policy may exist without actually blocking traffic.&lt;/p&gt;

&lt;p&gt;Test again with a timeout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  payment-db-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'PGCONNECT_TIMEOUT=5 psql -h lab-postgres -U labuser -d payments -c "SELECT 1;"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected on a correctly enforcing cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connection to server at "lab-postgres" failed:
Connection timed out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students should now investigate why PostgreSQL is Running and Ready but the client cannot connect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl get networkpolicy &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab

kubectl describe networkpolicy block-postgres-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Student challenge
&lt;/h3&gt;

&lt;p&gt;You are not told that the instructor introduced a NetworkPolicy.&lt;/p&gt;

&lt;p&gt;Your job is to identify the exact resource that changed and explain how it prevents database access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Restore service
&lt;/h2&gt;

&lt;p&gt;Once you have identified and documented the cause, remove the injected policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete networkpolicy block-postgres-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  payment-db-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  psql &lt;span class="nt"&gt;-h&lt;/span&gt; lab-postgres &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-U&lt;/span&gt; labuser &lt;span class="nt"&gt;-d&lt;/span&gt; payments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT 1;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected: &lt;code&gt;SELECT 1&lt;/code&gt; succeeds.&lt;/p&gt;

&lt;p&gt;Clean up the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod payment-db-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; payments-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the entire lab is complete, the instructor can delete the dedicated namespace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important difference between the lab and production
&lt;/h3&gt;

&lt;p&gt;The production case study involves an AWS security group changed by Terraform. The hands-on exercise uses Kubernetes NetworkPolicy to reproduce blocked database traffic safely.&lt;/p&gt;

&lt;p&gt;Both teach network connectivity troubleshooting, but they are different control planes. Students must be able to explain that distinction during an interview.&lt;/p&gt;

&lt;p&gt;Also, this initial lab tests connectivity directly; it does not yet deploy a complete payment API, transaction simulator, or the custom payment metrics used in the fictional dashboard. Those would be additional components if the class needs a fully instrumented end-to-end payment workflow.&lt;/p&gt;

&lt;h1&gt;
  
  
  Advanced interview question bank
&lt;/h1&gt;

&lt;p&gt;Practice the following questions without looking at the answers first.&lt;/p&gt;

&lt;p&gt;Incident response&lt;/p&gt;

&lt;p&gt;1 / 17&lt;/p&gt;

&lt;h2&gt;
  
  
  You receive a payment failure alert. What are your first five actions?
&lt;/h2&gt;

&lt;p&gt;Show model answerFollow-up&lt;/p&gt;

&lt;p&gt; PreviousNext &lt;/p&gt;

&lt;h1&gt;
  
  
  Final mock interview: Tell me about a critical production incident
&lt;/h1&gt;

&lt;p&gt;Students, your final task is to explain the entire incident in approximately three minutes. This is a model answer for discussing the case study. Adapt it to your actual experience rather than claiming to have personally resolved an incident you only practiced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Incident — Payment API Database Connectivity Failure
&lt;/h2&gt;

&lt;p&gt;One complex production incident scenario I worked through involved a customer-facing payment processing application running on AWS EKS with PostgreSQL on Amazon RDS.&lt;/p&gt;

&lt;p&gt;The environment used Terraform for infrastructure management, GitHub Actions for CI/CD, and Prometheus, Grafana, CloudWatch, and PagerDuty for monitoring and alerting.&lt;/p&gt;

&lt;p&gt;The incident began when the payment success rate dropped significantly, from approximately 99.95% to 41%. Customers were experiencing payment failures and HTTP 5xx errors.&lt;/p&gt;

&lt;p&gt;My first step would be to acknowledge the PagerDuty alert and investigate the customer impact through Grafana. I would check the error rate, latency, request volume, and Kubernetes availability.&lt;/p&gt;

&lt;p&gt;Interestingly, all 12 Payment API Pods were Running and Ready, and the RDS database itself reported Available.&lt;/p&gt;

&lt;p&gt;This indicated that the problem might be outside basic Kubernetes Pod health.&lt;/p&gt;

&lt;p&gt;I would inspect the application logs, where I would find PostgreSQL connection timeouts. I would then work with the database and cloud platform teams to investigate database health and the network path from EKS to RDS.&lt;/p&gt;

&lt;p&gt;I would check DNS resolution, TCP connectivity on port 5432, security group rules, and any relevant Kubernetes NetworkPolicies.&lt;/p&gt;

&lt;p&gt;At the same time, I would review recent production changes. The release engineering team would identify a successful Terraform infrastructure deployment shortly before the errors started.&lt;/p&gt;

&lt;p&gt;By comparing the Terraform change with the previous known-good configuration, we would identify that the RDS security group ingress rule had been changed to reference the wrong source security group.&lt;/p&gt;

&lt;p&gt;The database itself was operational, but the application could no longer reliably establish new database connections.&lt;/p&gt;

&lt;p&gt;I would coordinate with the incident commander and platform team to restore the previously approved security group rule using the authorized emergency change procedure.&lt;/p&gt;

&lt;p&gt;After the correction, I would verify connectivity from the application network, confirm successful database operations, and monitor payment success rate, HTTP errors, latency, and transaction reconciliation.&lt;/p&gt;

&lt;p&gt;I would not declare recovery based only on Kubernetes Pod status. I would verify that the customer-facing payment workflow was functioning correctly.&lt;/p&gt;

&lt;p&gt;Following recovery, I would participate in the postmortem and recommend stronger Terraform policy checks, post-deployment connectivity testing, synthetic payment monitoring, and improved incident runbooks.&lt;/p&gt;

&lt;p&gt;The main lesson from this incident is that healthy Kubernetes Pods and a healthy database do not necessarily mean the complete application is healthy. As a DevOps engineer, I need to investigate the full request path and work across infrastructure, application, database, and security teams to restore service safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final evaluation rubric
&lt;/h2&gt;

&lt;p&gt;Use this scorecard to assess each student during Class 3.&lt;/p&gt;

&lt;p&gt;Mock interview score&lt;/p&gt;

&lt;p&gt;Adjust scores as the student answers&lt;/p&gt;

&lt;h1&gt;
  
  
  0 / 100
&lt;/h1&gt;

&lt;p&gt;Needs more practice&lt;/p&gt;

&lt;p&gt;Incident impact and first response&lt;/p&gt;

&lt;p&gt;0 / 15&lt;/p&gt;

&lt;p&gt;Kubernetes investigation&lt;/p&gt;

&lt;p&gt;0 / 15&lt;/p&gt;

&lt;p&gt;Database and networking diagnosis&lt;/p&gt;

&lt;p&gt;0 / 20&lt;/p&gt;

&lt;p&gt;Terraform and CI/CD investigation&lt;/p&gt;

&lt;p&gt;0 / 20&lt;/p&gt;

&lt;p&gt;Mitigation and recovery verification&lt;/p&gt;

&lt;p&gt;0 / 15&lt;/p&gt;

&lt;p&gt;Communication and postmortem&lt;/p&gt;

&lt;p&gt;0 / 15&lt;/p&gt;

&lt;p&gt;Reset for next student&lt;/p&gt;

&lt;h2&gt;
  
  
  What interviewers are really evaluating
&lt;/h2&gt;

&lt;p&gt;This incident is especially useful for DevOps Engineer, Site Reliability Engineer, Platform Engineer, Cloud Infrastructure Engineer, and DevSecOps interviews because it tests several competencies together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes: Understanding that Pod readiness is not the same as business functionality.&lt;/li&gt;
&lt;li&gt;AWS: Knowing how VPC networking, security groups, EKS, and RDS interact.&lt;/li&gt;
&lt;li&gt;Terraform: Understanding change management, infrastructure drift, and safe recovery.&lt;/li&gt;
&lt;li&gt;CI/CD: Recognizing that a successful pipeline does not guarantee a successful production outcome.&lt;/li&gt;
&lt;li&gt;Database: Knowing how to distinguish connectivity, authentication, performance, and availability failures.&lt;/li&gt;
&lt;li&gt;Monitoring: Using technical and business metrics together.&lt;/li&gt;
&lt;li&gt;Incident management: Communicating, escalating, mitigating, verifying, and documenting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Students should be able to explain not just which command they would run, but what question that command answers.&lt;/p&gt;

&lt;p&gt;Your final assignment: Explain why the Payment API could have 12 healthy Kubernetes Pods, an Available PostgreSQL RDS instance, and a successful Terraform deployment while customer payments were failing—and describe the evidence needed to identify and fix the real cause.&lt;/p&gt;

&lt;p&gt;That is the central engineering challenge for these three classes.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>JumpToTech DevOps Bootcamp Kubernetes Production Support Lab — From Deployment to HTTP Request Troubleshooting</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Thu, 29 Oct 2026 15:48:47 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-devops-bootcamp-kubernetes-production-support-lab-from-deployment-to-http-request-4ech</link>
      <guid>https://dev.to/jumptotech/jumptotech-devops-bootcamp-kubernetes-production-support-lab-from-deployment-to-http-request-4ech</guid>
      <description>&lt;p&gt;&lt;strong&gt;Level:&lt;/strong&gt; Beginner to Intermediate\&lt;br&gt;
&lt;strong&gt;Role:&lt;/strong&gt; DevOps Engineer / Cloud Engineer / Site Reliability Engineer\&lt;br&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Restaurant Company\&lt;br&gt;
&lt;strong&gt;Environment:&lt;/strong&gt; Kubernetes (Amazon EKS, kind, or minikube)\&lt;br&gt;
&lt;strong&gt;Estimated time:&lt;/strong&gt; 3–4 hours\&lt;br&gt;
&lt;strong&gt;Assignment type:&lt;/strong&gt; Hands-on Lab + Simulated Production Incident + Interview Preparation&lt;/p&gt;


&lt;h1&gt;
  
  
  PART 1 — YOUR ROLE AS A DEVOPS ENGINEER
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Welcome to Restaurant Company
&lt;/h2&gt;

&lt;p&gt;Imagine you have recently joined Restaurant Company as a DevOps Engineer.&lt;/p&gt;

&lt;p&gt;Restaurant Company has a web application that customers use to view restaurant information and place orders.&lt;/p&gt;

&lt;p&gt;The application runs in Kubernetes.&lt;/p&gt;

&lt;p&gt;Your responsibility is to help ensure that the application is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available to customers.&lt;/li&gt;
&lt;li&gt;Running on healthy Kubernetes Pods.&lt;/li&gt;
&lt;li&gt;Accessible through the correct network routes.&lt;/li&gt;
&lt;li&gt;Deployed reliably through CI/CD pipelines.&lt;/li&gt;
&lt;li&gt;Monitored for failures.&lt;/li&gt;
&lt;li&gt;Recoverable when incidents occur.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are also responsible for communicating with developers, other DevOps engineers, SREs, engineering managers, and incident responders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your job is not simply to execute commands. Your job is to investigate problems, understand the impact, restore service safely, and communicate clearly.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1.1 Tools used by your company
&lt;/h2&gt;

&lt;p&gt;For this simulated environment, assume your company uses:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;Application source code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;CI/CD automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Container image packaging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon ECR&lt;/td&gt;
&lt;td&gt;Container image registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon EKS&lt;/td&gt;
&lt;td&gt;Managed Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kubectl&lt;/td&gt;
&lt;td&gt;Kubernetes administration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jira / ServiceNow&lt;/td&gt;
&lt;td&gt;Incident tickets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slack / Microsoft Teams&lt;/td&gt;
&lt;td&gt;Team communication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus&lt;/td&gt;
&lt;td&gt;Application and infrastructure metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;Monitoring dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon CloudWatch&lt;/td&gt;
&lt;td&gt;AWS monitoring and logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CoreDNS&lt;/td&gt;
&lt;td&gt;Internal Kubernetes DNS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS ALB&lt;/td&gt;
&lt;td&gt;External HTTP/HTTPS routing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Different companies may use different tools. The concepts remain similar.&lt;/p&gt;


&lt;h1&gt;
  
  
  PART 2 — UNDERSTAND THE APPLICATION ARCHITECTURE
&lt;/h1&gt;

&lt;p&gt;Before troubleshooting production issues, you must understand how the application reaches Kubernetes.&lt;/p&gt;
&lt;h2&gt;
  
  
  2.1 How an application is deployed
&lt;/h2&gt;

&lt;p&gt;A developer writes application code and pushes it to GitHub.&lt;/p&gt;

&lt;p&gt;A typical CI/CD workflow then performs the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer pushes code to a GitHub repository.&lt;/li&gt;
&lt;li&gt;GitHub Actions starts a CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;The pipeline checks out the source code.&lt;/li&gt;
&lt;li&gt;The pipeline installs dependencies and runs tests.&lt;/li&gt;
&lt;li&gt;Docker builds a container image.&lt;/li&gt;
&lt;li&gt;The image is pushed to Amazon ECR.&lt;/li&gt;
&lt;li&gt;The deployment workflow updates the Kubernetes Deployment to use the new image.&lt;/li&gt;
&lt;li&gt;The Kubernetes API Server accepts the updated desired state.&lt;/li&gt;
&lt;li&gt;The Deployment Controller manages the ReplicaSet.&lt;/li&gt;
&lt;li&gt;The ReplicaSet Controller maintains the required number of Pods.&lt;/li&gt;
&lt;li&gt;The Scheduler selects suitable Worker Nodes for new Pods.&lt;/li&gt;
&lt;li&gt;kubelet on each assigned Worker Node works with the container runtime to start the containers.&lt;/li&gt;
&lt;li&gt;The CNI implementation configures Pod networking.&lt;/li&gt;
&lt;li&gt;Readiness probes determine whether the application Pods are ready to receive traffic.&lt;/li&gt;
&lt;li&gt;Kubernetes Service endpoints are updated to reflect eligible backends.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; This is the typical production deployment architecture. In this lab, we will create Kubernetes resources manually using YAML and kubectl. We are not building a complete GitHub Actions/ECR pipeline today.&lt;/p&gt;
&lt;h2&gt;
  
  
  2.2 Kubernetes component responsibilities
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;API Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The API Server is the entry point for Kubernetes API requests. When you execute &lt;code&gt;kubectl apply&lt;/code&gt;, kubectl sends the requested configuration to the API Server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;etcd&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;etcd stores Kubernetes cluster state, including the desired state of Kubernetes resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Deployment Controller manages ReplicaSets and application rollouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReplicaSet Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ReplicaSet Controller ensures that the desired number of Pods exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Scheduler selects an appropriate Worker Node for a Pod that has not yet been assigned to a Node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kubelet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;kubelet is the agent running on a Kubernetes Node. It works with the container runtime to maintain assigned Pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container Runtime&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The container runtime, such as containerd, manages container image pulling and container execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linux Kernel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Linux Kernel provides the underlying operating system functionality, including processes, networking, namespaces, cgroups, and resource management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CNI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Container Network Interface implementation configures Pod networking. Depending on the CNI plugin, this includes interfaces, IP allocation, and routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CoreDNS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CoreDNS resolves Kubernetes Service DNS names into their corresponding Service IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EndpointSlices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EndpointSlices publish backend endpoint information associated with Kubernetes Services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kube-proxy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In clusters using kube-proxy, it watches Services and EndpointSlices and configures the Service networking dataplane. In iptables mode, Linux Netfilter processes packets according to the programmed rules.&lt;/p&gt;

&lt;p&gt;Other Kubernetes clusters may use different networking implementations, such as eBPF-based Service routing.&lt;/p&gt;


&lt;h1&gt;
  
  
  PART 3 — YOUR FIRST PRODUCTION TICKET
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Incident Ticket: INC-2026-1042
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Title:&lt;/strong&gt; Restaurant Backend Service Unavailable\&lt;br&gt;
&lt;strong&gt;Priority:&lt;/strong&gt; P2 — High (simulated)\&lt;br&gt;
&lt;strong&gt;Environment:&lt;/strong&gt; Kubernetes\&lt;br&gt;
&lt;strong&gt;Assigned Team:&lt;/strong&gt; DevOps / Platform Engineering\&lt;br&gt;
&lt;strong&gt;Status:&lt;/strong&gt; Open — Investigating&lt;/p&gt;
&lt;h3&gt;
  
  
  Incident description
&lt;/h3&gt;

&lt;p&gt;Customers are reporting that the Restaurant application cannot retrieve backend information.&lt;/p&gt;

&lt;p&gt;Monitoring indicates that application requests are failing.&lt;/p&gt;

&lt;p&gt;The Kubernetes Deployment appears healthy, but requests to the backend Service are unsuccessful.&lt;/p&gt;
&lt;h3&gt;
  
  
  Business impact
&lt;/h3&gt;

&lt;p&gt;Customers may be unable to view restaurant information or complete certain application workflows.&lt;/p&gt;

&lt;p&gt;Your task is to investigate the issue, identify the root cause, restore connectivity, and document the resolution.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.1 Where will you receive the ticket?
&lt;/h2&gt;

&lt;p&gt;In a real company, incidents may be reported through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jira or ServiceNow.&lt;/li&gt;
&lt;li&gt;PagerDuty or another on-call alerting system.&lt;/li&gt;
&lt;li&gt;Grafana or Prometheus alerts.&lt;/li&gt;
&lt;li&gt;CloudWatch alarms.&lt;/li&gt;
&lt;li&gt;Slack or Microsoft Teams.&lt;/li&gt;
&lt;li&gt;Customer support escalation.&lt;/li&gt;
&lt;li&gt;Developer reports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;A monitoring system detects failed HTTP requests and creates an alert.&lt;/p&gt;

&lt;p&gt;The alert reaches the on-call engineer.&lt;/p&gt;

&lt;p&gt;The engineer acknowledges the alert, reviews the impact, and opens or updates the incident ticket.&lt;/p&gt;

&lt;p&gt;The incident is then investigated according to the company's incident-management procedures.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.2 What should you do first?
&lt;/h2&gt;

&lt;p&gt;Before executing troubleshooting commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Acknowledge the ticket.&lt;/li&gt;
&lt;li&gt;Identify the affected application and environment.&lt;/li&gt;
&lt;li&gt;Determine the reported symptoms and business impact.&lt;/li&gt;
&lt;li&gt;Check whether there is an active incident bridge or incident commander.&lt;/li&gt;
&lt;li&gt;Review recent deployments and infrastructure changes.&lt;/li&gt;
&lt;li&gt;Start with safe, read-only diagnostic commands.&lt;/li&gt;
&lt;li&gt;Communicate your investigation status.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not immediately restart applications, delete Pods, or modify production configuration without understanding the situation and following company procedures.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.3 Your first Slack message
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hi team,&lt;/p&gt;

&lt;p&gt;I have acknowledged INC-2026-1042 regarding failed requests to the Restaurant backend service.&lt;/p&gt;

&lt;p&gt;I am reviewing the Kubernetes Deployment, Pod readiness, Service configuration, and backend endpoints to determine the cause.&lt;/p&gt;

&lt;p&gt;I will provide another update within 10 minutes.&lt;/p&gt;

&lt;p&gt;Please let me know if there were any recent application deployments or infrastructure changes.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;
&lt;h2&gt;
  
  
  3.4 What information should you collect?
&lt;/h2&gt;

&lt;p&gt;Before troubleshooting, identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application name.&lt;/li&gt;
&lt;li&gt;Namespace.&lt;/li&gt;
&lt;li&gt;Cluster.&lt;/li&gt;
&lt;li&gt;Environment.&lt;/li&gt;
&lt;li&gt;Time the issue started.&lt;/li&gt;
&lt;li&gt;User-facing symptoms.&lt;/li&gt;
&lt;li&gt;Error codes, if available.&lt;/li&gt;
&lt;li&gt;Recent deployments.&lt;/li&gt;
&lt;li&gt;Monitoring alerts.&lt;/li&gt;
&lt;li&gt;Relevant logs.&lt;/li&gt;
&lt;li&gt;Current incident owner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our lab:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application:&lt;/strong&gt; Restaurant Company\&lt;br&gt;
&lt;strong&gt;Namespace:&lt;/strong&gt; jumptotech-lab\&lt;br&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; restaurant\&lt;br&gt;
&lt;strong&gt;Service:&lt;/strong&gt; restaurant-service\&lt;br&gt;
&lt;strong&gt;Port:&lt;/strong&gt; 80\&lt;br&gt;
&lt;strong&gt;Replicas:&lt;/strong&gt; 2&lt;/p&gt;


&lt;h1&gt;
  
  
  PART 4 — BUILD YOUR KUBERNETES ENVIRONMENT FROM ZERO
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Step 1 — Verify Kubernetes access
&lt;/h2&gt;

&lt;p&gt;Open your terminal.&lt;/p&gt;

&lt;p&gt;If you are using Amazon EKS, make sure your AWS credentials, cluster access, and kubeconfig are configured.&lt;/p&gt;

&lt;p&gt;If you are using kind or minikube, ensure your local cluster is running.&lt;/p&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cluster-info
kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl config current-context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes API Server is reachable.&lt;/li&gt;
&lt;li&gt;At least one Node is Ready.&lt;/li&gt;
&lt;li&gt;Your current context points to the intended lab cluster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Never assume you are connected to the correct cluster. Always verify your Kubernetes context before making changes.&lt;/p&gt;

&lt;p&gt;If you receive a connection error, stop and troubleshoot cluster access before continuing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Create your project directory
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/jumptotech-k8s-network-lab
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/jumptotech-k8s-network-lab
&lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3 — Create a Namespace
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview question: Why do we use Kubernetes Namespaces?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Namespaces provide logical separation of namespaced Kubernetes resources within a cluster. Teams commonly use them to organize applications and environments, apply access controls, and manage resource quotas.&lt;/p&gt;

&lt;p&gt;Namespaces alone are not a complete security boundary.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 5 — CREATE THE RESTAURANT DEPLOYMENT
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 4 — Create deployment.yaml
&lt;/h2&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat &amp;gt; deployment.yaml &amp;lt;&amp;lt;'EOF'&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jumptotech-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.27&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;50m"&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;64Mi"&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;250m"&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;
        &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5 — Apply the Deployment
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check rollout status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployments &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab

kubectl get replicasets &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment exists.&lt;/li&gt;
&lt;li&gt;ReplicaSet exists.&lt;/li&gt;
&lt;li&gt;Two Restaurant Pods are Running and Ready.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the Pods are not Ready, do not continue blindly.&lt;/p&gt;

&lt;p&gt;Investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe deployment restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab

kubectl describe pods &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;restaurant

kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6 — Understand what happened
&lt;/h2&gt;

&lt;p&gt;When you executed &lt;code&gt;kubectl apply -f deployment.yaml&lt;/code&gt;, you submitted the desired application configuration to Kubernetes.&lt;/p&gt;

&lt;p&gt;The API Server processed the request.&lt;/p&gt;

&lt;p&gt;The Deployment Controller managed the ReplicaSet.&lt;/p&gt;

&lt;p&gt;The ReplicaSet Controller created the required Pods.&lt;/p&gt;

&lt;p&gt;The Scheduler selected Worker Nodes.&lt;/p&gt;

&lt;p&gt;kubelet worked with the container runtime to start the containers.&lt;/p&gt;

&lt;p&gt;The CNI implementation configured networking for the Pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Student questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is a Deployment?&lt;/li&gt;
&lt;li&gt;What is a ReplicaSet?&lt;/li&gt;
&lt;li&gt;What is a Pod?&lt;/li&gt;
&lt;li&gt;Who selects the Worker Node?&lt;/li&gt;
&lt;li&gt;Who starts the container?&lt;/li&gt;
&lt;li&gt;What is the role of the Linux Kernel?&lt;/li&gt;
&lt;li&gt;Why does the Pod need a network interface and IP address?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Be prepared to explain every answer without reading your notes.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 6 — CREATE THE KUBERNETES SERVICE
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 7 — Create service.yaml
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; service.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
apiVersion: v1
kind: Service
metadata:
  name: restaurant-service
  namespace: jumptotech-lab
spec:
  type: ClusterIP
  selector:
    app: restaurant
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab

kubectl describe svc restaurant-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check EndpointSlices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslices &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;restaurant-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 8 — Understand Service and Pod labels
&lt;/h2&gt;

&lt;p&gt;Your Service has this selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Pods have this label:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The matching labels allow the EndpointSlice Controller to publish the correct backend endpoints.&lt;/p&gt;

&lt;p&gt;The Service provides a stable virtual IP address, called a ClusterIP.&lt;/p&gt;

&lt;p&gt;Pods can be replaced and receive new IP addresses, while the Service can retain its ClusterIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interview question: Why do we need a Service if Pods already have IP addresses?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pod IP addresses may change when Pods are recreated. A Kubernetes Service provides a stable endpoint and Service discovery mechanism for reaching eligible backend Pods.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 7 — CREATE A DIAGNOSTIC CLIENT POD
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 9 — Create client.yaml
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; client.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
apiVersion: v1
kind: Pod
metadata:
  name: client
  namespace: jumptotech-lab
spec:
  containers:
  - name: netshoot
    image: nicolaka/netshoot:latest
    command: ["sleep", "36000"]
    resources:
      requests:
        cpu: "25m"
        memory: "32Mi"
      limits:
        cpu: "200m"
        memory: "128Mi"
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; client.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Ready &lt;span class="se"&gt;\&lt;/span&gt;
  pod/client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your terminal prompt should change to something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client:~#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; You are now inside the Client Pod, not on your EC2 management host.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 8 — INVESTIGATE POD NETWORKING
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 10 — Check the Pod hostname
&lt;/h2&gt;

&lt;p&gt;Inside Client Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 11 — Check network interfaces
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip addr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the &lt;code&gt;eth0&lt;/code&gt; interface and its IPv4 address.&lt;/p&gt;

&lt;p&gt;Record the IP address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 12 — Check routing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip route
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for the default route.&lt;/p&gt;

&lt;p&gt;In AWS VPC CNI, you may see a gateway such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default via 169.254.1.1 dev eth0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other Kubernetes network implementations may have different routing configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 13 — Check DNS configuration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identify the configured DNS server and search domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interview question: What is a Linux Network Namespace?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Network Namespace provides an isolated view of networking resources, including network interfaces, IP addresses, routing tables, and ports.&lt;/p&gt;

&lt;p&gt;Containers in the same Kubernetes Pod normally share one Network Namespace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interview question: What does CNI do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The CNI implementation configures networking for Pods. Depending on the plugin, this includes network interfaces, IP addresses, and routing.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 9 — TRACE AN HTTP REQUEST
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 14 — DNS resolution
&lt;/h2&gt;

&lt;p&gt;Still inside Client Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup restaurant-service.jumptotech-lab.svc.cluster.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;The DNS lookup returns the ClusterIP assigned to &lt;code&gt;restaurant-service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Record the IP address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happened?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Client Pod's resolver queried cluster DNS.&lt;/p&gt;

&lt;p&gt;CoreDNS resolved the Kubernetes Service name.&lt;/p&gt;

&lt;p&gt;The DNS response provided the Service IP address.&lt;/p&gt;

&lt;p&gt;CoreDNS does not forward the HTTP request itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 15 — Send HTTP request
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; http://restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected HTTP status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default NGINX welcome page should be returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 16 — Understand the complete internal request flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Client Pod initiates an HTTP request.&lt;/li&gt;
&lt;li&gt;DNS resolves &lt;code&gt;restaurant-service&lt;/code&gt; to its ClusterIP.&lt;/li&gt;
&lt;li&gt;The client establishes a TCP connection to the Service IP on port 80.&lt;/li&gt;
&lt;li&gt;The Kubernetes Service dataplane selects an eligible backend Pod.&lt;/li&gt;
&lt;li&gt;In iptables-based kube-proxy mode, Linux Netfilter applies Service forwarding and address translation rules.&lt;/li&gt;
&lt;li&gt;The packet reaches the selected Restaurant Pod.&lt;/li&gt;
&lt;li&gt;NGINX receives the HTTP request on port 80.&lt;/li&gt;
&lt;li&gt;NGINX returns the HTTP response.&lt;/li&gt;
&lt;li&gt;The response travels back to the Client Pod.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important distinction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;kube-proxy programs forwarding rules in its supported modes. In iptables mode, the Linux Kernel processes packets using those rules.&lt;/p&gt;

&lt;p&gt;The exact implementation depends on the cluster networking configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 17 — Compare direct Pod IP requests
&lt;/h2&gt;

&lt;p&gt;Exit the Client Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the current Restaurant Pod IP addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;restaurant &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record both Pod IPs.&lt;/p&gt;

&lt;p&gt;Enter Client Pod again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following, replacing the placeholders with the real IP addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://POD_1_IP:80
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://POD_2_IP:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, if a Pod IP is &lt;code&gt;172.31.46.36&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://172.31.46.36:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interview question: What is the difference between a Service request and a direct Pod IP request?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Service request uses a stable Service endpoint and the cluster's Service routing implementation to reach an eligible backend.&lt;/p&gt;

&lt;p&gt;A direct Pod IP request targets one specific Pod and bypasses Service load balancing.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 10 — REPRODUCE THE PRODUCTION INCIDENT
&lt;/h1&gt;

&lt;p&gt;Now we will simulate a real Kubernetes networking incident.&lt;/p&gt;

&lt;p&gt;We will intentionally create a Service with an incorrect selector.&lt;/p&gt;

&lt;p&gt;We will not modify the healthy Restaurant Service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 18 — Exit Client Pod
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 19 — Create a broken Service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; broken-service.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
apiVersion: v1
kind: Service
metadata:
  name: restaurant-broken
  namespace: jumptotech-lab
spec:
  type: ClusterIP
  selector:
    app: wrong-restaurant
  ports:
  - name: http
    port: 80
    targetPort: 80
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; broken-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 20 — Investigate the broken Service
&lt;/h2&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Describe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe svc restaurant-broken &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Pod labels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check EndpointSlices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslices &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;restaurant-broken &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Service selector uses &lt;code&gt;app: wrong-restaurant&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Restaurant Pods use &lt;code&gt;app: restaurant&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because these values do not match, the Service has no eligible backend endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 21 — Reproduce the failed HTTP request
&lt;/h2&gt;

&lt;p&gt;Test DNS from Client Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec &lt;/span&gt;client &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  nslookup restaurant-broken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The DNS name should resolve to the broken Service's ClusterIP.&lt;/p&gt;

&lt;p&gt;Now test HTTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec &lt;/span&gt;client &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://restaurant-broken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request should fail because the Service has no eligible backend endpoints.&lt;/p&gt;

&lt;p&gt;The exact failure may be connection refused, timeout, or another network-level error depending on the cluster dataplane.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not automatically describe this as HTTP 503.&lt;/strong&gt; A Service without endpoints does not necessarily return an HTTP response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 22 — Identify the root cause
&lt;/h2&gt;

&lt;p&gt;Compare:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service selector:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app: wrong-restaurant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pod label:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app: restaurant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root cause:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Kubernetes Service selector did not match the Restaurant Pod labels.&lt;/p&gt;

&lt;p&gt;As a result, no eligible backend endpoints were available for that Service.&lt;/p&gt;

&lt;p&gt;The application Pods were healthy, but traffic could not reach them through the broken Service.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 11 — COMMUNICATE YOUR FINDINGS
&lt;/h1&gt;

&lt;p&gt;Before applying the fix, write an investigation update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Slack message:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hi team,&lt;/p&gt;

&lt;p&gt;I identified a likely root cause for INC-2026-1042.&lt;/p&gt;

&lt;p&gt;The Restaurant application Pods are Running and Ready, but the affected Kubernetes Service has no eligible backend endpoints.&lt;/p&gt;

&lt;p&gt;The Service selector is configured with &lt;code&gt;app: wrong-restaurant&lt;/code&gt;, while the application Pods use &lt;code&gt;app: restaurant&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I reproduced the connectivity failure from a diagnostic Pod.&lt;/p&gt;

&lt;p&gt;I am preparing a selector correction and will verify the backend endpoints and HTTP response after the change.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 12 — FIX THE INCIDENT
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 23 — Correct the Service selector
&lt;/h2&gt;

&lt;p&gt;For our isolated lab, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch svc restaurant-broken &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"selector":{"app":"restaurant"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In real production, follow change authorization and GitOps procedures. If the Service is managed through Git, Helm, or Argo CD, update the source of truth to prevent the incorrect configuration from returning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 24 — Verify the fix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe svc restaurant-broken &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check EndpointSlices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslices &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;restaurant-broken &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm that backend Pod IPs appear.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec &lt;/span&gt;client &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://restaurant-broken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 25 — Verify the original healthy Service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec &lt;/span&gt;client &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a real production incident, one successful curl is not enough to establish full recovery.&lt;/p&gt;

&lt;p&gt;You should also verify monitoring metrics, error rates, readiness, backend health, and the actual user-facing path.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 13 — RESOLUTION COMMUNICATION
&lt;/h1&gt;

&lt;p&gt;After verifying recovery, write a resolution update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Slack message:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hi team,&lt;/p&gt;

&lt;p&gt;INC-2026-1042 has been resolved in our lab environment.&lt;/p&gt;

&lt;p&gt;Root cause: The Kubernetes Service selector did not match the application Pod labels, leaving the Service without eligible backend endpoints.&lt;/p&gt;

&lt;p&gt;Actions taken:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirmed the application Pods were Running and Ready.&lt;/li&gt;
&lt;li&gt;Reviewed Service configuration and Pod labels.&lt;/li&gt;
&lt;li&gt;Inspected EndpointSlices.&lt;/li&gt;
&lt;li&gt;Reproduced the failed HTTP request from a diagnostic Pod.&lt;/li&gt;
&lt;li&gt;Corrected the Service selector.&lt;/li&gt;
&lt;li&gt;Verified backend endpoints were populated.&lt;/li&gt;
&lt;li&gt;Confirmed HTTP 200 responses after the fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recommend adding automated validation for Service selectors and backend endpoint availability to help prevent similar configuration errors.&lt;/p&gt;

&lt;p&gt;I will document the investigation and resolution in the incident ticket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Only use this resolution message after completing and verifying the corresponding actions.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 14 — COMPLETE YOUR INCIDENT TICKET
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Incident Report
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Incident ID:&lt;/strong&gt; INC-2026-1042&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application:&lt;/strong&gt; Restaurant Company&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment:&lt;/strong&gt; Kubernetes Lab&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Backend Service connectivity failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Simulated inability to reach the backend application through the affected Service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Detection:&lt;/strong&gt; Simulated monitoring alert and failed HTTP connectivity test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Investigation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reviewed Kubernetes Deployment, Pod status, Service configuration, Pod labels, and EndpointSlices.&lt;/p&gt;

&lt;p&gt;Confirmed the application Pods were Running and Ready.&lt;/p&gt;

&lt;p&gt;Observed that the affected Service did not have eligible backend endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Service selector mismatch.&lt;/p&gt;

&lt;p&gt;The Service used &lt;code&gt;app: wrong-restaurant&lt;/code&gt;, while the Pods used &lt;code&gt;app: restaurant&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Updated the Service selector to match the Pod labels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verification:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Confirmed backend endpoints appeared and the Service returned HTTP 200 from the diagnostic Client Pod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preventive Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add deployment validation for Service selectors.&lt;/li&gt;
&lt;li&gt;Monitor Service backend availability.&lt;/li&gt;
&lt;li&gt;Review Kubernetes manifests before deployment.&lt;/li&gt;
&lt;li&gt;Use GitOps and peer-reviewed changes where applicable.&lt;/li&gt;
&lt;li&gt;Maintain clear incident runbooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Status:&lt;/strong&gt; Resolved — after successful verification.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 15 — BONUS LAB: KUBERNETES SELF-HEALING
&lt;/h1&gt;

&lt;p&gt;This lab demonstrates how Kubernetes maintains the desired number of Pods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 26 — Check existing Pods
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;restaurant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 27 — Delete one Pod
&lt;/h2&gt;

&lt;p&gt;Choose an actual Restaurant Pod name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod POD_NAME &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;POD_NAME&lt;/code&gt; with the real name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 28 — Watch Kubernetes create a replacement
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Ctrl+C when the new Pod becomes Ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 29 — Verify replicas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected: Two Ready replicas after recovery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interview question: What happens when a Pod is deleted?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ReplicaSet Controller detects that the number of existing Pods is below the desired replica count and creates a replacement Pod.&lt;/p&gt;

&lt;p&gt;The Scheduler assigns the new Pod to a suitable Node, and kubelet starts its containers.&lt;/p&gt;

&lt;p&gt;This is an example of Kubernetes reconciliation and self-healing.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 16 — BONUS LAB: ACCESS THE APPLICATION FROM A BROWSER
&lt;/h1&gt;

&lt;p&gt;From the machine where kubectl is configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  svc/restaurant-service &lt;span class="se"&gt;\&lt;/span&gt;
  8080:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Expected: NGINX welcome page.&lt;/p&gt;

&lt;p&gt;If kubectl is running on a remote EC2 instance, &lt;code&gt;localhost:8080&lt;/code&gt; refers to that EC2 instance, not your laptop. Use an approved SSH tunnel or another authorized access method if you need to view it locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Port-forwarding is a diagnostic tool. It does not demonstrate the production AWS ALB and Ingress request path.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 17 — UNDERSTAND THE EXTERNAL HTTP REQUEST FLOW
&lt;/h1&gt;

&lt;p&gt;A real customer usually does not access the application's internal Kubernetes Service name.&lt;/p&gt;

&lt;p&gt;Consider a production architecture using AWS ALB.&lt;/p&gt;

&lt;p&gt;A typical request flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Customer opens the Restaurant Company website.&lt;/li&gt;
&lt;li&gt;The browser resolves the public domain through DNS.&lt;/li&gt;
&lt;li&gt;The browser connects to the public application endpoint, commonly over HTTPS.&lt;/li&gt;
&lt;li&gt;AWS ALB receives the request.&lt;/li&gt;
&lt;li&gt;ALB evaluates listener and routing rules.&lt;/li&gt;
&lt;li&gt;The request is forwarded to a configured target group.&lt;/li&gt;
&lt;li&gt;The target group sends the request to a healthy backend target.&lt;/li&gt;
&lt;li&gt;The application processes the request.&lt;/li&gt;
&lt;li&gt;The HTTP response returns to the browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With AWS Load Balancer Controller, ALB can target Pod IPs directly in IP target mode or NodePorts in instance target mode.&lt;/p&gt;

&lt;p&gt;For a separate internal backend call, a frontend server Pod may resolve a Kubernetes Service name using CoreDNS and send traffic through the internal Service dataplane.&lt;/p&gt;

&lt;p&gt;A browser-hosted React application may instead call a public backend API through ALB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You must know which architecture your application actually uses.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Important HTTP status codes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;What DevOps investigates&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Successful response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;Created&lt;/td&gt;
&lt;td&gt;Resource creation succeeded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301 / 302&lt;/td&gt;
&lt;td&gt;Redirect&lt;/td&gt;
&lt;td&gt;Redirect configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;Bad Request&lt;/td&gt;
&lt;td&gt;Invalid request or API validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;td&gt;Unauthorized&lt;/td&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403&lt;/td&gt;
&lt;td&gt;Forbidden&lt;/td&gt;
&lt;td&gt;Authorization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Not Found&lt;/td&gt;
&lt;td&gt;Missing route or resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;Internal Server Error&lt;/td&gt;
&lt;td&gt;Application/backend failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;td&gt;Bad Gateway&lt;/td&gt;
&lt;td&gt;Gateway or upstream response failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;td&gt;Service Unavailable&lt;/td&gt;
&lt;td&gt;Backend availability or overload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;504&lt;/td&gt;
&lt;td&gt;Gateway Timeout&lt;/td&gt;
&lt;td&gt;Upstream timeout&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; A 404 does not necessarily mean the entire application is unavailable. A 400 does not automatically mean the application is down. HTTP status codes must be interpreted in context.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 18 — HOW TO TROUBLESHOOT DIFFERENT ERRORS
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Scenario A — Pod is Pending
&lt;/h2&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod POD_NAME &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Insufficient CPU or memory.&lt;/li&gt;
&lt;li&gt;Scheduling constraints.&lt;/li&gt;
&lt;li&gt;Node availability.&lt;/li&gt;
&lt;li&gt;Taints and tolerations.&lt;/li&gt;
&lt;li&gt;Persistent volume requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scenario B — ImagePullBackOff
&lt;/h2&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod POD_NAME &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Incorrect image name.&lt;/li&gt;
&lt;li&gt;Missing image tag.&lt;/li&gt;
&lt;li&gt;Registry access.&lt;/li&gt;
&lt;li&gt;Image pull permissions.&lt;/li&gt;
&lt;li&gt;Registry connectivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scenario C — CrashLoopBackOff
&lt;/h2&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs POD_NAME &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="nt"&gt;--previous&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also inspect Pod events and container exit codes.&lt;/p&gt;

&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application startup failure.&lt;/li&gt;
&lt;li&gt;Incorrect configuration.&lt;/li&gt;
&lt;li&gt;Missing dependencies.&lt;/li&gt;
&lt;li&gt;Resource limits.&lt;/li&gt;
&lt;li&gt;Probe failures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scenario D — Service DNS resolution fails
&lt;/h2&gt;

&lt;p&gt;Check from a diagnostic Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service existence.&lt;/li&gt;
&lt;li&gt;Namespace and DNS name.&lt;/li&gt;
&lt;li&gt;CoreDNS health.&lt;/li&gt;
&lt;li&gt;Pod DNS configuration.&lt;/li&gt;
&lt;li&gt;DNS connectivity and network policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scenario E — DNS works but HTTP fails
&lt;/h2&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslices &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; jumptotech-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service selector.&lt;/li&gt;
&lt;li&gt;Pod readiness.&lt;/li&gt;
&lt;li&gt;Target port.&lt;/li&gt;
&lt;li&gt;Application listener.&lt;/li&gt;
&lt;li&gt;Network policies.&lt;/li&gt;
&lt;li&gt;Service dataplane behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scenario F — External users receive 503
&lt;/h2&gt;

&lt;p&gt;Investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS ALB target health.&lt;/li&gt;
&lt;li&gt;Ingress configuration.&lt;/li&gt;
&lt;li&gt;Target groups.&lt;/li&gt;
&lt;li&gt;Service and endpoint availability.&lt;/li&gt;
&lt;li&gt;Pod readiness.&lt;/li&gt;
&lt;li&gt;Application health checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The investigation depends on which component generated the 503.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 19 — HOW TO ANSWER IN A DEVOPS INTERVIEW
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Interview Question 1: Tell me about yourself
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am building hands-on experience in DevOps and cloud infrastructure, focusing on Linux, AWS, Docker, Kubernetes, Terraform, and CI/CD automation.&lt;/p&gt;

&lt;p&gt;Through my Restaurant Company project, I have practiced deploying containerized applications to Kubernetes, configuring Deployments and Services, troubleshooting Pod networking, and investigating application connectivity issues.&lt;/p&gt;

&lt;p&gt;I have also worked on simulated production incidents, where I followed a structured process to identify problems, verify fixes, and communicate technical findings.&lt;/p&gt;

&lt;p&gt;I am especially interested in cloud infrastructure automation, Kubernetes operations, and production reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 2: Explain how an application gets deployed to Kubernetes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a typical CI/CD workflow, developers push their code to GitHub, which triggers an automated pipeline.&lt;/p&gt;

&lt;p&gt;The pipeline builds and tests the application, creates a Docker image, and pushes it to a container registry such as Amazon ECR.&lt;/p&gt;

&lt;p&gt;The deployment process updates the Kubernetes Deployment with the new image version.&lt;/p&gt;

&lt;p&gt;The Kubernetes API Server accepts the desired configuration, and the Deployment Controller manages the rollout through ReplicaSets.&lt;/p&gt;

&lt;p&gt;The Scheduler assigns new Pods to suitable Worker Nodes, and kubelet works with the container runtime to start the containers.&lt;/p&gt;

&lt;p&gt;The CNI implementation configures Pod networking, and readiness probes help determine when the application is ready to receive traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 3: Explain how an HTTP request reaches a Kubernetes application
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For an external request, the client first resolves the public domain through DNS and connects to the application's public endpoint.&lt;/p&gt;

&lt;p&gt;In an AWS environment, the request may reach an Application Load Balancer.&lt;/p&gt;

&lt;p&gt;The ALB evaluates its listener rules and forwards traffic to a healthy backend target.&lt;/p&gt;

&lt;p&gt;For internal communication between Kubernetes applications, a client Pod can use the backend Service DNS name.&lt;/p&gt;

&lt;p&gt;CoreDNS resolves the Service name to its ClusterIP.&lt;/p&gt;

&lt;p&gt;The Kubernetes Service dataplane then forwards the connection to an eligible backend Pod.&lt;/p&gt;

&lt;p&gt;The application processes the HTTP request and sends the response back to the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 4: Tell me about a Kubernetes incident you resolved
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During my DevOps training, I investigated a simulated production incident involving a Restaurant Company application running in Kubernetes.&lt;/p&gt;

&lt;p&gt;The application Pods were healthy, but HTTP requests through a Kubernetes Service were failing.&lt;/p&gt;

&lt;p&gt;I started by reviewing Pod readiness, the Service configuration, Pod labels, and EndpointSlices.&lt;/p&gt;

&lt;p&gt;I reproduced the connectivity failure from a diagnostic Client Pod.&lt;/p&gt;

&lt;p&gt;DNS resolution was successful, which helped me separate DNS issues from Service routing problems.&lt;/p&gt;

&lt;p&gt;I found that the Service selector did not match the application Pod labels, leaving the Service without eligible backend endpoints.&lt;/p&gt;

&lt;p&gt;I corrected the selector, verified that the expected endpoints appeared, and confirmed the application returned HTTP 200.&lt;/p&gt;

&lt;p&gt;I also practiced communicating the incident status, documenting the root cause, and recommending preventive checks.&lt;/p&gt;

&lt;p&gt;This exercise helped me understand how Kubernetes networking works and how to approach connectivity issues systematically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 5: How do you troubleshoot a Kubernetes application that is unavailable?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I first confirm the scope and impact of the issue.&lt;/p&gt;

&lt;p&gt;I check monitoring alerts and determine whether the problem affects all users or only specific requests.&lt;/p&gt;

&lt;p&gt;Then I inspect the Kubernetes Deployment, Pod readiness, events, and application logs.&lt;/p&gt;

&lt;p&gt;If the Pods are healthy, I investigate Service configuration, EndpointSlices, DNS resolution, and network connectivity.&lt;/p&gt;

&lt;p&gt;For externally exposed applications, I also check Ingress configuration, load balancer target health, and relevant AWS networking components.&lt;/p&gt;

&lt;p&gt;Once I identify the likely root cause, I coordinate the appropriate mitigation, verify recovery, monitor for recurrence, and document the incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 6: What is the difference between CoreDNS, CNI, and kube-proxy?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CoreDNS provides DNS resolution for Kubernetes Service names.&lt;/p&gt;

&lt;p&gt;CNI is the interface through which the networking implementation configures Pod connectivity, including IP addressing and interfaces.&lt;/p&gt;

&lt;p&gt;kube-proxy, when used, implements Kubernetes Service networking by programming forwarding rules based on Service and EndpointSlice information.&lt;/p&gt;

&lt;p&gt;These components have different responsibilities, but they work together to support communication between Kubernetes applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Question 7: How do you communicate during a production incident?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I acknowledge the incident and confirm the business impact.&lt;/p&gt;

&lt;p&gt;I provide regular updates to the incident channel, including what has been verified, what I am investigating, and when the next update is expected.&lt;/p&gt;

&lt;p&gt;I avoid presenting assumptions as confirmed root causes.&lt;/p&gt;

&lt;p&gt;If the incident requires escalation or a potentially disruptive change, I coordinate with the incident lead and relevant teams.&lt;/p&gt;

&lt;p&gt;After service recovery, I document the root cause, resolution, verification results, and preventive actions.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 20 — YOUR FINAL HOMEWORK
&lt;/h1&gt;

&lt;p&gt;Submit the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Screenshot showing Kubernetes Nodes in Ready status.&lt;/li&gt;
&lt;li&gt;Screenshot showing your Restaurant Deployment and two Ready Pods.&lt;/li&gt;
&lt;li&gt;Screenshot showing your Kubernetes Service and ClusterIP.&lt;/li&gt;
&lt;li&gt;Screenshot showing the EndpointSlices.&lt;/li&gt;
&lt;li&gt;Screenshot showing successful CoreDNS resolution.&lt;/li&gt;
&lt;li&gt;Screenshot showing HTTP 200 from the healthy Service.&lt;/li&gt;
&lt;li&gt;Screenshot showing the broken Service selector.&lt;/li&gt;
&lt;li&gt;Screenshot showing missing backend endpoints.&lt;/li&gt;
&lt;li&gt;Screenshot showing the failed HTTP request.&lt;/li&gt;
&lt;li&gt;Screenshot showing the corrected selector.&lt;/li&gt;
&lt;li&gt;Screenshot showing HTTP 200 after the fix.&lt;/li&gt;
&lt;li&gt;Your first Slack incident acknowledgment.&lt;/li&gt;
&lt;li&gt;Your investigation update.&lt;/li&gt;
&lt;li&gt;Your resolution update.&lt;/li&gt;
&lt;li&gt;Your completed incident report.&lt;/li&gt;
&lt;li&gt;A written or recorded interview explanation of the incident.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final practical assessment
&lt;/h2&gt;

&lt;p&gt;Your instructor may ask you to share your screen and demonstrate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to find a Deployment.&lt;/li&gt;
&lt;li&gt;How to check Pod health.&lt;/li&gt;
&lt;li&gt;How to find the Pod IP.&lt;/li&gt;
&lt;li&gt;How to inspect a Service.&lt;/li&gt;
&lt;li&gt;How to inspect EndpointSlices.&lt;/li&gt;
&lt;li&gt;How to check DNS resolution.&lt;/li&gt;
&lt;li&gt;How to test HTTP connectivity.&lt;/li&gt;
&lt;li&gt;How to identify a selector mismatch.&lt;/li&gt;
&lt;li&gt;How to correct the configuration.&lt;/li&gt;
&lt;li&gt;How to verify recovery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should explain what every command does and why you are using it.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 21 — CLEANUP
&lt;/h1&gt;

&lt;p&gt;After your instructor confirms that the assignment is complete, remove the lab resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete namespace jumptotech-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This removes the resources created in that Namespace.&lt;/p&gt;

&lt;p&gt;Do not run this command until you have saved your screenshots and completed the assignment.&lt;/p&gt;




&lt;h1&gt;
  
  
  FINAL MESSAGE TO STUDENTS
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Your goal is not to memorize Kubernetes commands. Your goal is to understand the full lifecycle of an application and how to troubleshoot it when something goes wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A strong DevOps Engineer should be able to explain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How application code moves from GitHub to Kubernetes.&lt;/li&gt;
&lt;li&gt;How Kubernetes schedules and runs containers.&lt;/li&gt;
&lt;li&gt;How Pods receive network connectivity.&lt;/li&gt;
&lt;li&gt;How Services and EndpointSlices support application communication.&lt;/li&gt;
&lt;li&gt;How DNS resolution differs from HTTP routing.&lt;/li&gt;
&lt;li&gt;How an HTTP request reaches an application.&lt;/li&gt;
&lt;li&gt;How to investigate a production incident safely.&lt;/li&gt;
&lt;li&gt;How to communicate findings and progress.&lt;/li&gt;
&lt;li&gt;How to verify that a problem is resolved.&lt;/li&gt;
&lt;li&gt;How to explain the work clearly in a technical interview.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember the incident response structure:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact → Investigation → Evidence → Root Cause → Mitigation → Verification → Communication → Prevention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Practice explaining your project in your own words.&lt;/p&gt;

&lt;p&gt;Be clear about which activities you performed in a lab and which tools or processes belong to the example production architecture. Never present a training exercise as actual employment experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JumpToTech DevOps Bootcamp — Learn It. Build It. Troubleshoot It. Explain It.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can copy this entire handbook directly into your student group or development platform. It includes the complete lab, the simulated ticket, step-by-step commands, workplace communication, incident reporting, and interview preparation.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>JumpToTech DevOps/SRE Bootcamp Production Incident Response Lab — Banking Application on AWS EKS</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Wed, 28 Oct 2026 21:17:39 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-devopssre-bootcampproduction-incident-response-lab-banking-application-on-aws-eks-26l6</link>
      <guid>https://dev.to/jumptotech/jumptotech-devopssre-bootcampproduction-incident-response-lab-banking-application-on-aws-eks-26l6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Kubernetes Incident Response — Banking Application on AWS EKS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most critical incidents I handled involved a customer-facing banking application running on AWS EKS.&lt;/p&gt;

&lt;p&gt;Our production environment had approximately &lt;strong&gt;60 frontend replicas distributed across three Availability Zones&lt;/strong&gt;, with an AWS Application Load Balancer handling incoming traffic. We used Prometheus and Grafana for monitoring and alerting.&lt;/p&gt;

&lt;p&gt;During a production release, we started receiving alerts that the banking application's HTTP 5xx error rate had increased significantly. The error rate reached approximately &lt;strong&gt;18%&lt;/strong&gt;, and customers were experiencing intermittent failures when accessing their accounts.&lt;/p&gt;

&lt;p&gt;I was the primary SRE responsible for investigating the incident and coordinating the technical recovery.&lt;/p&gt;

&lt;p&gt;My first step was to assess the impact. I checked Grafana dashboards for error rates, request latency, and available replicas. I noticed that available frontend replicas had dropped from &lt;strong&gt;60 to 38&lt;/strong&gt;, which explained why the remaining Pods were struggling to handle traffic.&lt;/p&gt;

&lt;p&gt;I then checked the EKS cluster using &lt;code&gt;kubectl get nodes&lt;/code&gt;, &lt;code&gt;kubectl get pods&lt;/code&gt;, and &lt;code&gt;kubectl get deployments&lt;/code&gt;. All worker nodes were healthy, so I ruled out a cluster-wide infrastructure failure.&lt;/p&gt;

&lt;p&gt;When I inspected the affected Pods using &lt;code&gt;kubectl describe pod&lt;/code&gt;, I found repeated readiness-probe failures. The new containers were Running, but they were not becoming Ready.&lt;/p&gt;

&lt;p&gt;I checked the Kubernetes events and application logs and found that the readiness probes were returning &lt;strong&gt;HTTP 404&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After comparing the new deployment configuration with the previous release, I identified the root cause: the readiness probe had been changed from &lt;code&gt;/&lt;/code&gt; to &lt;code&gt;/healthz&lt;/code&gt;, but the application did not expose the new endpoint.&lt;/p&gt;

&lt;p&gt;I also found that the deployment configuration allowed too many healthy Pods to become unavailable during the rollout, which contributed to the loss of serving capacity.&lt;/p&gt;

&lt;p&gt;At that point, my priority was restoring service rather than troubleshooting the defective release further.&lt;/p&gt;

&lt;p&gt;I rolled back the deployment using &lt;code&gt;kubectl rollout undo deployment/banking-frontend&lt;/code&gt; and monitored the recovery using &lt;code&gt;kubectl rollout status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As the previous application version came back online, available replicas increased from &lt;strong&gt;38 to 60&lt;/strong&gt;, and the HTTP 5xx error rate returned to its normal baseline.&lt;/p&gt;

&lt;p&gt;I verified recovery by checking Kubernetes Service endpoints, application health checks, load balancer metrics, and Grafana dashboards.&lt;/p&gt;

&lt;p&gt;The application was restored within approximately &lt;strong&gt;12 minutes&lt;/strong&gt; of incident detection.&lt;/p&gt;

&lt;p&gt;After the incident, I completed a root cause analysis and recommended three improvements: automated readiness-probe validation in CI/CD, safer RollingUpdate settings with &lt;code&gt;maxUnavailable: 0&lt;/code&gt;, and canary deployments to detect faulty releases before they affect the entire application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The outcome was that I restored full application availability, reduced the immediate customer impact, and helped establish deployment safeguards to prevent the same failure from recurring.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This incident reinforced the importance of understanding Kubernetes readiness probes, deployment strategies, monitoring, and rapid rollback procedures in a high-availability banking environment.&lt;/p&gt;

&lt;p&gt;Numbers in this example&lt;br&gt;
Metric  Value&lt;br&gt;
Frontend replicas   60&lt;br&gt;
Availability Zones  3&lt;br&gt;
Available replicas during incident  38&lt;br&gt;
Unavailable replicas    22&lt;br&gt;
Peak HTTP 5xx error rate    18%&lt;br&gt;
Readiness-probe error   HTTP 404&lt;br&gt;
Recovery time   12 minutes&lt;br&gt;
Replicas after recovery 60&lt;br&gt;
Recovery method Kubernetes rollback&lt;/p&gt;

&lt;p&gt;These numbers form a consistent hypothetical production incident, not a historical incident verified at JPMorgan Chase. In a real interview, students should use the metrics from their own incident evidence rather than present these figures as their personal employment history.&lt;/p&gt;

&lt;p&gt;What makes this a senior-level answer: It demonstrates that the engineer assessed customer impact, distinguished application failure from infrastructure failure, investigated Kubernetes events and logs, identified the configuration defect, performed a controlled rollback, verified recovery, and implemented preventive measures.&lt;br&gt;
Student Lab Guide · Day 2&lt;/p&gt;

&lt;p&gt;Scenario: Banking Application Outage After a Failed Production Deployment\&lt;br&gt;
Environment: AWS EKS, Kubernetes, Prometheus, Grafana, NGINX\&lt;br&gt;
Role: DevOps / Site Reliability Engineer\&lt;br&gt;
Difficulty: Intermediate\&lt;br&gt;
Estimated duration: 3 hours\&lt;br&gt;
Incident severity: Simulated SEV-2 / P2&lt;/p&gt;
&lt;h3&gt;
  
  
  Important note for students
&lt;/h3&gt;

&lt;p&gt;This lab uses a fictional banking incident inspired by the types of production problems that can occur in large financial institutions such as JPMorgan Chase. It is not a documented incident at Chase, and you must not claim that you worked at Chase or resolved this incident in its actual production environment.&lt;/p&gt;

&lt;p&gt;You will, however, perform a real hands-on investigation in your own Kubernetes cluster. You can discuss that experience confidently in interviews as an independently resolved production-style lab incident.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Your role and responsibilities
&lt;/h2&gt;

&lt;p&gt;You are a DevOps/SRE Engineer supporting a banking application running on Amazon EKS.&lt;/p&gt;

&lt;p&gt;The application allows customers to access banking services. Your team is responsible for keeping the infrastructure reliable, deploying application releases, monitoring service health, and restoring service when an incident occurs.&lt;/p&gt;

&lt;p&gt;During this lab, you are responsible for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Monitoring: Detect when application availability decreases.&lt;/li&gt;
&lt;li&gt;Incident response: Assess the impact and prioritize recovery.&lt;/li&gt;
&lt;li&gt;Troubleshooting: Investigate Deployments, ReplicaSets, Pods, Services, probes, events, and logs.&lt;/li&gt;
&lt;li&gt;Mitigation: Restore the last known healthy application version.&lt;/li&gt;
&lt;li&gt;Verification: Confirm application availability and healthy Kubernetes status.&lt;/li&gt;
&lt;li&gt;Communication: Provide clear updates to the incident commander and application team.&lt;/li&gt;
&lt;li&gt;Root cause analysis: Explain why the failure occurred and how to prevent recurrence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your objective is not simply to restart a Pod. Your objective is to restore customer-facing service safely, understand the failure, and reduce the chance of recurrence.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. The incident you will investigate
&lt;/h2&gt;

&lt;p&gt;INC-2026-001&lt;/p&gt;

&lt;p&gt;Simulated SEV-2&lt;/p&gt;
&lt;h2&gt;
  
  
  Banking frontend unavailable after a Kubernetes deployment
&lt;/h2&gt;

&lt;p&gt;Business impact: Customers may be unable to access the banking frontend during the failed rollout.&lt;/p&gt;

&lt;p&gt;Technical symptoms: Deployment unavailable, Pods not Ready, application health checks failing.&lt;/p&gt;

&lt;p&gt;Expected root cause: A newly released application version fails its readiness checks.&lt;/p&gt;

&lt;p&gt;Recovery strategy: Roll back to the previous known-good Deployment revision.&lt;/p&gt;
&lt;h3&gt;
  
  
  What happened?
&lt;/h3&gt;

&lt;p&gt;The development team released a new version of the banking frontend.&lt;/p&gt;

&lt;p&gt;The new container starts, but a configuration defect causes its HTTP readiness endpoint to fail. Kubernetes therefore cannot mark the new Pods as Ready.&lt;/p&gt;

&lt;p&gt;As the rollout progresses, the old working Pods are replaced. Eventually, the application has no Ready endpoints, and customers cannot access the service.&lt;/p&gt;

&lt;p&gt;Prometheus detects the decrease in available replicas. Grafana displays the outage and can trigger an alert.&lt;/p&gt;

&lt;p&gt;You are the engineer responsible for diagnosing the failure and restoring the previous working release.&lt;/p&gt;
&lt;h3&gt;
  
  
  What success looks like
&lt;/h3&gt;

&lt;p&gt;At the end of the incident:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Deployment is restored to its previous healthy revision.&lt;/li&gt;
&lt;li&gt;Two frontend replicas are Ready.&lt;/li&gt;
&lt;li&gt;The Kubernetes Service has healthy endpoints.&lt;/li&gt;
&lt;li&gt;The application returns &lt;code&gt;HTTP 200&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Monitoring shows recovery.&lt;/li&gt;
&lt;li&gt;You have recorded the root cause, commands, evidence, and preventive actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not invent recovery times, financial losses, customer counts, or performance improvements. Measure your actual lab results and use those numbers in your interview explanation.&lt;/p&gt;
&lt;h1&gt;
  
  
  3. Understand the production architecture
&lt;/h1&gt;

&lt;p&gt;Banking customers&lt;/p&gt;

&lt;p&gt;Customer requests&lt;/p&gt;

&lt;p&gt;Application access layer&lt;/p&gt;

&lt;p&gt;Production would typically use HTTPS and an ALB or Ingress&lt;/p&gt;

&lt;p&gt;Kubernetes Service&lt;/p&gt;

&lt;p&gt;banking-service · ClusterIP · Port 80&lt;/p&gt;

&lt;p&gt;Frontend Pod 1&lt;/p&gt;

&lt;p&gt;NGINX · Port 80&lt;/p&gt;

&lt;p&gt;Frontend Pod 2&lt;/p&gt;

&lt;p&gt;NGINX · Port 80&lt;/p&gt;

&lt;p&gt;Prometheus collects Kubernetes health metrics. Grafana visualizes them and evaluates alert rules.&lt;/p&gt;

&lt;p&gt;In this lab, the frontend is represented by an NGINX container. It is not a complete banking system with authentication, payment processing, or a database. The incident concerns the frontend availability layer.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Lab prerequisites
&lt;/h2&gt;

&lt;p&gt;From the previous lesson, you should already have:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Expected state&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EKS cluster&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worker nodes&lt;/td&gt;
&lt;td&gt;Ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;&lt;code&gt;banking-incident-lab&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;&lt;code&gt;banking-frontend&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replicas&lt;/td&gt;
&lt;td&gt;2/2 Ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;banking-service&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus&lt;/td&gt;
&lt;td&gt;Running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;Running&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use the same cluster and namespace as yesterday. Do not delete or reinstall the monitoring stack.&lt;/p&gt;
&lt;h1&gt;
  
  
  Part A — Establish the healthy production baseline
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Step 1. Verify your AWS and Kubernetes environment
&lt;/h2&gt;

&lt;p&gt;Run these commands on the machine where your &lt;code&gt;kubectl&lt;/code&gt; is configured.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config current-context

kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring

kubectl get deployment &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide

kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected Deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME               READY   UP-TO-DATE   AVAILABLE
banking-frontend   2/2     2            2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Student task: Explain why &lt;code&gt;READY 2/2&lt;/code&gt; matters and how Kubernetes determines whether a Pod is ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Inspect the readiness probe
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness: http-get http://:80/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The readiness probe is configured to request &lt;code&gt;/&lt;/code&gt; on port &lt;code&gt;80&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The kubelet runs the probe. Successful HTTP responses (status codes 200–399) allow the container to become Ready.&lt;/p&gt;

&lt;p&gt;A failed readiness probe does not necessarily restart the container. Instead, the Pod becomes Not Ready and is excluded from normal Service traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3. Verify the Service endpoints
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslice &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;banking-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints banking-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see two Pod addresses associated with the Service.&lt;/p&gt;

&lt;p&gt;The EndpointSlice output is the preferred way to inspect endpoint readiness in modern Kubernetes. The legacy Endpoints command is included because it is still common in interviews and older runbooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4. Verify the application responds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run baseline-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl:8.11.1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"HTTP %{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-time&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
  http://banking-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;HTTP 200
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A temporary warning about attaching to the diagnostic Pod is acceptable if the curl command still returns HTTP 200.&lt;/p&gt;

&lt;p&gt;Evidence to save: Terminal output showing two Ready replicas and a successful HTTP response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5. Save the healthy Deployment configuration
&lt;/h2&gt;

&lt;p&gt;This is an essential production habit: preserve the current state before making changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/banking-incident-lab/evidence

kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/banking-incident-lab/evidence/deployment-before.yaml

kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not manually edit the saved baseline file during the incident.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part B — Configure Prometheus and Grafana
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 6. Open Grafana
&lt;/h2&gt;

&lt;p&gt;Use the Grafana instance you configured in the previous lesson.&lt;/p&gt;

&lt;p&gt;If Grafana is not accessible, start the port-forward on the management machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring &lt;span class="se"&gt;\&lt;/span&gt;
  svc/monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  3000:80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--address&lt;/span&gt; 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you access Grafana through an EC2 management machine, use your existing SSH tunnel to reach its localhost port securely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7. Create a production monitoring dashboard
&lt;/h2&gt;

&lt;p&gt;In Grafana, go to Dashboards → New → New dashboard → Add visualization and select your Prometheus data source.&lt;/p&gt;

&lt;p&gt;Create these four panels.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Panel&lt;/th&gt;
&lt;th&gt;Visualization&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Available replicas&lt;/td&gt;
&lt;td&gt;Stat&lt;/td&gt;
&lt;td&gt;Number of available frontend replicas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desired replicas&lt;/td&gt;
&lt;td&gt;Stat&lt;/td&gt;
&lt;td&gt;Number Kubernetes should maintain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unavailable replicas&lt;/td&gt;
&lt;td&gt;Stat&lt;/td&gt;
&lt;td&gt;Detect loss of Deployment availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container restarts&lt;/td&gt;
&lt;td&gt;Time series&lt;/td&gt;
&lt;td&gt;Track application restarts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Panel 1 — Available replicas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_status_replicas_available&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Healthy value: &lt;code&gt;2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Panel 2 — Desired replicas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_spec_replicas&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Healthy value: &lt;code&gt;2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Panel 3 — Unavailable replicas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_spec_replicas&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;
&lt;span class="n"&gt;kube_deployment_status_replicas_available&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Healthy value: &lt;code&gt;0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Panel 4 — Container restarts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;kube_pod_container_status_restarts_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="na"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;=~&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend-.*"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Healthy initial value: normally &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Save the dashboard as:&lt;/p&gt;

&lt;p&gt;JumpToTech — Banking Production Incident Monitoring&lt;/p&gt;

&lt;p&gt;If a query returns No Data, verify the Prometheus data source, kube-state-metrics, namespace, and Deployment labels before proceeding. Do not treat missing metrics as a healthy result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8. Create an incident alert
&lt;/h2&gt;

&lt;p&gt;Navigate to Alerting → Alert rules → New alert rule.&lt;/p&gt;

&lt;p&gt;Configure:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alert name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BankingFrontendUnavailable&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data source&lt;/td&gt;
&lt;td&gt;Prometheus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluation interval&lt;/td&gt;
&lt;td&gt;1 minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pending period&lt;/td&gt;
&lt;td&gt;1 minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Condition&lt;/td&gt;
&lt;td&gt;Last value greater than 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Severity label&lt;/td&gt;
&lt;td&gt;&lt;code&gt;warning&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Folder&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Banking Production Lab&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notification&lt;/td&gt;
&lt;td&gt;Your configured email contact point&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use this PromQL expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;kube_deployment_spec_replicas&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;
&lt;span class="n"&gt;kube_deployment_status_replicas_available&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-incident-lab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  &lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"banking-frontend"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the alert condition to Last IS ABOVE 0. Depending on your Grafana version, this may require a Reduce expression and a Threshold expression.&lt;/p&gt;

&lt;p&gt;Use these annotations:&lt;/p&gt;

&lt;p&gt;Summary: Banking frontend has unavailable replicas.&lt;/p&gt;

&lt;p&gt;Description: The banking-frontend Deployment has fewer available replicas than desired. Investigate Pod readiness, Deployment rollout status, Kubernetes events, and Service endpoints.&lt;/p&gt;

&lt;p&gt;For the lab, use &lt;code&gt;No Data = No Data&lt;/code&gt; and &lt;code&gt;Error = Error&lt;/code&gt; so that missing metrics or evaluation failures are not silently treated as healthy. These states should be monitored separately in a real production alerting design.&lt;/p&gt;

&lt;p&gt;Before proceeding, verify the alert is saved and that the email contact point is selected by the notification policy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part C — Simulate the production incident
&lt;/h1&gt;

&lt;p&gt;Controlled incident simulation&lt;/p&gt;

&lt;p&gt;The next commands deliberately make the banking frontend unavailable. Execute them only in your dedicated training namespace, never in a real production banking environment.&lt;/p&gt;

&lt;p&gt;Verify that &lt;code&gt;kubectl config current-context&lt;/code&gt; points to your training cluster before continuing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 9. Understand the failure before creating it
&lt;/h2&gt;

&lt;p&gt;Our healthy NGINX container responds to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /
HTTP 200 OK
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will introduce a bad readiness probe that requests a nonexistent endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /healthz
HTTP 404 Not Found
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NGINX will still be running, but the kubelet will mark the container Not Ready.&lt;/p&gt;

&lt;p&gt;To make the full outage reproducible, we will temporarily use the Deployment's &lt;code&gt;Recreate&lt;/code&gt; strategy. This intentionally removes the old Pods before starting replacements. This is not a recommended production rollout strategy for a high-availability banking frontend.&lt;/p&gt;

&lt;p&gt;This combination demonstrates two failures: a bad health-check configuration and a rollout strategy that allows total service interruption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10. Record the incident start time
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +&lt;span class="s2"&gt;"Incident started: %Y-%m-%dT%H:%M:%SZ"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record the output in your incident worksheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 11. Configure the controlled rollout strategy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;merge &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"strategy":{"type":"Recreate","rollingUpdate":null}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes the rollout strategy without changing the application template.&lt;/p&gt;

&lt;p&gt;Confirm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.strategy.type}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recreate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 12. Introduce the faulty readiness probe
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;strategic &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"template":{"spec":{"containers":[{"name":"frontend","readinessProbe":{"httpGet":{"path":"/healthz","port":80},"initialDelaySeconds":5,"periodSeconds":5}}]}}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new Deployment revision with a bad readiness endpoint.&lt;/p&gt;

&lt;p&gt;Wait approximately 30–60 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 13. Observe the production failure
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab

kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab

kubectl rollout status deployment/banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected symptoms may resemble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                READY   STATUS
banking-frontend-xxxxxxxxxx-aaaaa   0/1     Running
banking-frontend-xxxxxxxxxx-bbbbb   0/1     Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME               READY   UP-TO-DATE   AVAILABLE
banking-frontend   0/2     2            0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rollout status command should time out because the new Pods never become available.&lt;/p&gt;

&lt;p&gt;Important: A Pod can have &lt;code&gt;STATUS Running&lt;/code&gt; while showing &lt;code&gt;READY 0/1&lt;/code&gt;. These fields describe different aspects of Pod health.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 14. Confirm customer-facing impact
&lt;/h2&gt;

&lt;p&gt;Inspect the endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslice &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;banking-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ready&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now test the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run incident-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl:8.11.1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
  http://banking-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected: the request fails or times out because the Service has no Ready backend endpoints.&lt;/p&gt;

&lt;p&gt;The exact network error can vary with the cluster networking implementation.&lt;/p&gt;

&lt;p&gt;Record the actual error. Do not assume every failed Service request returns HTTP 503.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part D — Investigate like a production SRE
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 15. Establish the scope
&lt;/h2&gt;

&lt;p&gt;First determine whether the problem affects only the banking application or the whole Kubernetes cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; monitoring

kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are Worker Nodes Ready?&lt;/li&gt;
&lt;li&gt;Are Prometheus and Grafana healthy?&lt;/li&gt;
&lt;li&gt;Are the banking Pods Running?&lt;/li&gt;
&lt;li&gt;Are the banking Pods Ready?&lt;/li&gt;
&lt;li&gt;Is the issue isolated to the frontend?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not immediately restart every Pod. That can destroy useful evidence without fixing the underlying configuration problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 16. Examine Kubernetes events
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for an event resembling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning  Unhealthy  Readiness probe failed:
HTTP probe failed with statuscode: 404
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a strong clue that the application is running but failing its health check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 17. Describe the affected Pods
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pods &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;banking-frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the &lt;code&gt;Readiness&lt;/code&gt; field and the &lt;code&gt;Events&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;You should observe that the probe is requesting &lt;code&gt;/healthz&lt;/code&gt; instead of &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 18. Examine application logs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for NGINX requests to &lt;code&gt;/healthz&lt;/code&gt; returning HTTP 404.&lt;/p&gt;

&lt;p&gt;This is the evidence that connects the Kubernetes probe failures to the application endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 19. Compare the deployment revisions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the live readiness configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.template.spec.containers[0].readinessProbe.httpGet.path}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare it with the baseline configuration saved before the incident, where the path was &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Root cause analysis
&lt;/h3&gt;

&lt;p&gt;Primary configuration defect&lt;/p&gt;

&lt;p&gt;The new Deployment revision used &lt;code&gt;/healthz&lt;/code&gt; as its readiness endpoint, but the NGINX application did not serve that path.&lt;/p&gt;

&lt;p&gt;Failure mechanism&lt;/p&gt;

&lt;p&gt;Kubelet received HTTP 404, marked the new Pods Not Ready, and the Service had no Ready endpoints.&lt;/p&gt;

&lt;p&gt;Outage-enabling rollout configuration&lt;/p&gt;

&lt;p&gt;The intentionally selected &lt;code&gt;Recreate&lt;/code&gt; strategy removed the healthy old Pods before the replacement Pods passed readiness checks.&lt;/p&gt;

&lt;p&gt;Business impact in the simulation&lt;/p&gt;

&lt;p&gt;The banking frontend became unavailable to clients using its Kubernetes Service.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part E — Recover production service
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 20. Perform a Kubernetes rollback
&lt;/h2&gt;

&lt;p&gt;We have identified the defective Deployment revision. Rather than manually editing the new release during the outage, restore the previous working version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout undo deployment/banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the recovery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deployment "banking-frontend" successfully rolled out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Deployment rollback restores the previous Pod template. It does not automatically restore the Deployment's rollout strategy, so we must correct that separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 21. Restore the safer RollingUpdate strategy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;merge &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"}}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With two replicas, this configuration allows a surge Pod while rounding the permitted unavailable count down to zero during normal rolling updates.&lt;/p&gt;

&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.strategy.type}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RollingUpdate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 22. Verify recovery
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab

kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab

kubectl get endpointslice &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;banking-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Deployment should return to &lt;code&gt;2/2&lt;/code&gt; available.&lt;/p&gt;

&lt;p&gt;Verify the readiness endpoint was restored:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment banking-frontend &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.template.spec.containers[0].readinessProbe.httpGet.path}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, test the Service again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run recovery-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; banking-incident-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl:8.11.1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"HTTP %{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-time&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
  http://banking-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;HTTP 200
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 23. Record the recovery time
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +&lt;span class="s2"&gt;"Service restored: %Y-%m-%dT%H:%M:%SZ"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculate the elapsed time between the incident start and recovery.&lt;/p&gt;

&lt;p&gt;This is your measured lab recovery duration. It is not automatically the same as production MTTR, which is typically calculated across multiple incidents.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part F — Verify monitoring and notification
&lt;/h1&gt;

&lt;p&gt;Return to the JumpToTech — Banking Production Incident Monitoring dashboard.&lt;/p&gt;

&lt;p&gt;The expected pattern is:&lt;/p&gt;

&lt;p&gt;Illustrative availability timeline&lt;/p&gt;

&lt;p&gt;Example only. Replace these values with observations from your Grafana dashboard.&lt;/p&gt;

&lt;p&gt;Desired replicasAvailable replicas&lt;/p&gt;

&lt;p&gt;00.511.52HealthyFailureInvestigationRollbackRecovered&lt;/p&gt;

&lt;p&gt;Check whether the alert transitioned through its expected states:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Normal → Pending → Firing → Resolved&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Because alert evaluations run periodically, a short outage may not last long enough to enter &lt;code&gt;Firing&lt;/code&gt;. If no alert fired, record that observation rather than claiming that an email was sent.&lt;/p&gt;

&lt;p&gt;If an email was delivered, preserve the timestamp and alert name as evidence.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part G — Your incident report
&lt;/h1&gt;

&lt;p&gt;Every student must complete this worksheet using their own terminal outputs and observations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Incident report — INC-2026-001
&lt;/h2&gt;

&lt;p&gt;Complete after the hands-on exercise. Copy the report into your lab submission.&lt;/p&gt;

&lt;p&gt;Engineer name&lt;/p&gt;

&lt;p&gt;Incident start time (UTC)&lt;/p&gt;

&lt;p&gt;How was the incident detected?&lt;/p&gt;

&lt;p&gt;Observed application impact&lt;/p&gt;

&lt;p&gt;Key commands and evidence&lt;/p&gt;

&lt;p&gt;Root cause&lt;/p&gt;

&lt;p&gt;Mitigation and recovery actions&lt;/p&gt;

&lt;p&gt;Service restoration time (UTC)&lt;/p&gt;

&lt;p&gt;Measured recovery duration&lt;/p&gt;

&lt;p&gt;Preventive actions&lt;/p&gt;

&lt;p&gt; Copy completed incident report&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevention recommendations
&lt;/h2&gt;

&lt;p&gt;A strong SRE does more than restore service. They identify engineering improvements.&lt;/p&gt;

&lt;p&gt;For this incident, recommend:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add automated readiness-endpoint checks to the CI/CD pipeline before deployment.&lt;/li&gt;
&lt;li&gt;Use RollingUpdate with an appropriate availability budget for customer-facing applications.&lt;/li&gt;
&lt;li&gt;Test application health checks in staging before promoting to production.&lt;/li&gt;
&lt;li&gt;Monitor desired versus available replicas and alert on sustained unavailability.&lt;/li&gt;
&lt;li&gt;Introduce canary deployments or progressive delivery for high-risk releases.&lt;/li&gt;
&lt;li&gt;Maintain a documented rollback runbook and test it regularly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Part H — Interview preparation
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The question interviewers may ask
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Tell me about a production incident you independently investigated and resolved. What was the impact, root cause, and outcome?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sample answer in English
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Production-Style Incident Response — AWS EKS Banking Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During a hands-on production incident simulation, I was responsible for investigating and restoring a banking frontend application deployed on AWS EKS.&lt;/p&gt;

&lt;p&gt;The application was running with two replicas behind a Kubernetes ClusterIP Service. We used Prometheus and Grafana to monitor Deployment availability, Pod readiness, and container restarts.&lt;/p&gt;

&lt;p&gt;During a deployment, the frontend became unavailable. My initial investigation showed that the desired replica count was two, but zero replicas were available.&lt;/p&gt;

&lt;p&gt;I checked the Deployment rollout status, inspected the Pods, reviewed Kubernetes events, and examined the application logs.&lt;/p&gt;

&lt;p&gt;The containers were running, but their readiness probes were failing with HTTP 404 errors.&lt;/p&gt;

&lt;p&gt;I traced the issue to an incorrect readiness probe path introduced in the new Deployment revision. The application was configured to check &lt;code&gt;/healthz&lt;/code&gt;, but NGINX was only serving the root endpoint. The rollout also used a Recreate strategy, which removed the healthy Pods before the replacement Pods were ready.&lt;/p&gt;

&lt;p&gt;After identifying the root cause, I rolled back the Deployment to the previous working revision and restored the RollingUpdate strategy.&lt;/p&gt;

&lt;p&gt;I verified that both replicas returned to Ready, the Service had healthy endpoints, and the application responded with HTTP 200.&lt;/p&gt;

&lt;p&gt;The key lesson was that a running container does not necessarily mean the application is ready to serve traffic.&lt;/p&gt;

&lt;p&gt;To prevent recurrence, I recommended automated health-check validation in CI/CD, safer rollout strategies, and Prometheus/Grafana alerting for unavailable replicas.&lt;/p&gt;

&lt;p&gt;This exercise gave me practical experience in Kubernetes incident investigation, root cause analysis, rollback, service recovery, and production reliability practices.&lt;/p&gt;

&lt;p&gt;This is an interview practice script for a lab incident. Personalize it with your actual evidence and recovery time. Do not present the simulation as an incident you handled while employed by a bank.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow-up interview questions you must master
&lt;/h2&gt;

&lt;p&gt;12 technical interview questions&lt;/p&gt;

&lt;p&gt;Tap to reveal answers&lt;/p&gt;

&lt;p&gt;1.Why were the Pods Running but not Ready?&lt;/p&gt;

&lt;p&gt;2.What is the difference between readiness and liveness probes?&lt;/p&gt;

&lt;p&gt;3.Why didn't Kubernetes automatically fix the incident?&lt;/p&gt;

&lt;p&gt;4.What did the Service do when both Pods were Not Ready?&lt;/p&gt;

&lt;p&gt;5.Why did the deployment cause a full outage?&lt;/p&gt;

&lt;p&gt;6.Would the default RollingUpdate strategy behave the same way?&lt;/p&gt;

&lt;p&gt;7.Why use kubectl rollout undo?&lt;/p&gt;

&lt;p&gt;8.Did the rollback restore every Deployment setting?&lt;/p&gt;

&lt;p&gt;9.How did Prometheus detect the problem?&lt;/p&gt;

&lt;p&gt;10.What is the difference between mitigation and root cause analysis?&lt;/p&gt;

&lt;p&gt;11.What would you communicate to stakeholders?&lt;/p&gt;

&lt;p&gt;12.What is the most important prevention?&lt;/p&gt;

&lt;h1&gt;
  
  
  Part I — Student submission checklist
&lt;/h1&gt;

&lt;p&gt;Evidence and deliverables&lt;/p&gt;

&lt;p&gt;0/12 completed&lt;/p&gt;

&lt;p&gt;Deployment healthy before incident: 2/2&lt;/p&gt;

&lt;p&gt;Baseline application test: HTTP 200&lt;/p&gt;

&lt;p&gt;Grafana dashboard with banking metrics&lt;/p&gt;

&lt;p&gt;Screenshot showing failed readiness probes&lt;/p&gt;

&lt;p&gt;Kubernetes events showing HTTP 404&lt;/p&gt;

&lt;p&gt;Application logs showing failed /healthz requests&lt;/p&gt;

&lt;p&gt;Deployment rollout history&lt;/p&gt;

&lt;p&gt;Successful rollback output&lt;/p&gt;

&lt;p&gt;Deployment recovered: 2/2&lt;/p&gt;

&lt;p&gt;Application recovered: HTTP 200&lt;/p&gt;

&lt;p&gt;Incident report with measured recovery time&lt;/p&gt;

&lt;p&gt;Interview explanation practiced aloud&lt;/p&gt;

&lt;h2&gt;
  
  
  Final learning outcome
&lt;/h2&gt;

&lt;p&gt;By completing this lab, you should be able to explain the entire incident lifecycle:&lt;/p&gt;

&lt;p&gt;1&lt;/p&gt;

&lt;p&gt;Detect&lt;/p&gt;

&lt;p&gt;2&lt;/p&gt;

&lt;p&gt;Investigate&lt;/p&gt;

&lt;p&gt;3&lt;/p&gt;

&lt;p&gt;Mitigate&lt;/p&gt;

&lt;p&gt;4&lt;/p&gt;

&lt;p&gt;Verify&lt;/p&gt;

&lt;p&gt;5&lt;/p&gt;

&lt;p&gt;Prevent&lt;/p&gt;

&lt;p&gt;Your goal is not to memorize a fictional story. Your goal is to reproduce the failure, understand every command, independently restore the application, and explain your own results clearly in an interview.&lt;/p&gt;

&lt;p&gt;This is the difference between knowing Kubernetes commands and demonstrating practical DevOps/SRE incident-response skills.&lt;/p&gt;

&lt;p&gt;JumpToTech DevOps/SRE Bootcamp — Production Incident Response Lab, Day 2&lt;/p&gt;

</description>
      <category>sre</category>
      <category>aws</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>Marta Dzekevich — Cloud &amp; Platform Engineering Manager Interview Preparation</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Wed, 28 Oct 2026 03:48:56 +0000</pubDate>
      <link>https://dev.to/jumptotech/marta-dzekevich-cloud-platform-engineering-manager-interview-preparation-1p4f</link>
      <guid>https://dev.to/jumptotech/marta-dzekevich-cloud-platform-engineering-manager-interview-preparation-1p4f</guid>
      <description>&lt;h2&gt;
  
  
  1. Tell me about yourself
&lt;/h2&gt;

&lt;p&gt;Sure, absolutely.&lt;/p&gt;

&lt;p&gt;My name is Marta, and I'm a Senior DevOps Engineer with over eight years of experience in cloud infrastructure, automation, Kubernetes, CI/CD, and production support.&lt;/p&gt;

&lt;p&gt;Currently, I'm working at Wells Fargo, where I focus on building and maintaining reliable AWS infrastructure, improving deployment automation, and supporting containerized applications.&lt;/p&gt;

&lt;p&gt;A big part of my work involves Terraform, Amazon EKS, Docker, GitHub Actions, Jenkins, and AWS services such as EC2, VPC, IAM, ALB, and CloudWatch.&lt;/p&gt;

&lt;p&gt;One of my key accomplishments was improving our CI/CD pipelines and reducing deployment time from approximately 45 minutes to 8 minutes through automation.&lt;/p&gt;

&lt;p&gt;I also worked on improving our release and rollback processes, reducing rollback time from around 20 minutes to 2 minutes using blue-green deployment strategies.&lt;/p&gt;

&lt;p&gt;Another area I've focused on is cloud cost optimization. By analyzing AWS resource utilization and right-sizing infrastructure, I helped reduce our monthly development AWS spending by approximately 35%.&lt;/p&gt;

&lt;p&gt;Before Wells Fargo, I worked at Home Depot, where I supported cloud-hosted business applications, networking, DNS, SSL/TLS, application integrations, and production operations.&lt;/p&gt;

&lt;p&gt;Over the years, I've developed a strong understanding of how cloud infrastructure, automation, networking, and application reliability work together.&lt;/p&gt;

&lt;p&gt;What interests me about this opportunity is the chance to contribute at a broader platform level, improve engineering standards, support cloud strategy, and help teams build reliable, secure, and cost-efficient infrastructure.&lt;/p&gt;

&lt;p&gt;I believe my hands-on engineering background and experience solving infrastructure problems would allow me to contribute effectively to this role.&lt;/p&gt;

&lt;p&gt;Speaking time: approximately 90 seconds to 2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What are your day-to-day responsibilities?
&lt;/h2&gt;

&lt;p&gt;My day-to-day responsibilities involve cloud infrastructure management, automation, CI/CD pipeline improvements, Kubernetes operations, and production support.&lt;/p&gt;

&lt;p&gt;I typically start by reviewing AWS CloudWatch dashboards and alerts to make sure our infrastructure and applications are healthy.&lt;/p&gt;

&lt;p&gt;I check for any failed deployments, high CPU or memory utilization, application availability issues, and infrastructure alerts.&lt;/p&gt;

&lt;p&gt;Then I review our priorities with the team and identify any blockers or production issues that need immediate attention.&lt;/p&gt;

&lt;p&gt;A significant part of my work involves Terraform. I maintain reusable Terraform modules to provision and manage AWS infrastructure across multiple environments.&lt;/p&gt;

&lt;p&gt;For example, if a development team needs a new application environment, I can use our Terraform modules to provision VPC networking, EC2 resources, security groups, IAM roles, and load balancers.&lt;/p&gt;

&lt;p&gt;I also work with Jenkins and GitHub Actions to maintain automated build, testing, security scanning, and deployment workflows.&lt;/p&gt;

&lt;p&gt;On the Kubernetes side, I support Amazon EKS workloads, investigate failed deployments, check pod health, and review resource requests, limits, and autoscaling configurations.&lt;/p&gt;

&lt;p&gt;Another responsibility is cloud cost optimization. I review AWS Cost Explorer and CloudWatch utilization data to identify underutilized resources and opportunities for right-sizing.&lt;/p&gt;

&lt;p&gt;I also collaborate with development teams, security engineers, and other infrastructure teams to troubleshoot issues and improve operational reliability.&lt;/p&gt;

&lt;p&gt;My main goal is to make our infrastructure more reliable, secure, automated, and cost-efficient while reducing manual work for engineering teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Production incident #1 — Deployment failure and rollback
&lt;/h2&gt;

&lt;p&gt;CI/CD · NGINX · Blue-green deployment · Recovery&lt;/p&gt;

&lt;p&gt;Marta's resume confirms blue-green deployment automation and a reduction in rollback time from 20 minutes to 2 minutes. The specific failure described below is an illustrative incident to adapt.&lt;/p&gt;

&lt;p&gt;Sure. One example I can share involves a deployment issue where a new application release was causing errors after being deployed.&lt;/p&gt;

&lt;p&gt;We noticed the issue through application health checks and started investigating the deployment.&lt;/p&gt;

&lt;p&gt;My first priority was to understand the impact and restore the previous stable version as quickly as possible.&lt;/p&gt;

&lt;p&gt;We were using a blue-green deployment strategy, where the current stable version and the new application version were deployed separately.&lt;/p&gt;

&lt;p&gt;I checked the application health, reviewed the deployment logs, and confirmed that the new version wasn't responding correctly.&lt;/p&gt;

&lt;p&gt;Instead of spending too much time troubleshooting while users were affected, we switched traffic back to the previous stable version.&lt;/p&gt;

&lt;p&gt;We used our automated NGINX and Bash-based traffic-switching process to perform the rollback.&lt;/p&gt;

&lt;p&gt;Once the previous version was serving traffic again, we verified application availability and reviewed the failed release with the development team.&lt;/p&gt;

&lt;p&gt;After the incident, we improved our deployment validation and health-check procedures to reduce the risk of similar failures.&lt;/p&gt;

&lt;p&gt;One of the major improvements from our release automation work was reducing rollback time from approximately 20 minutes to 2 minutes.&lt;/p&gt;

&lt;p&gt;This experience reinforced the importance of having a reliable rollback strategy and prioritizing service restoration during production incidents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical follow-up questions
&lt;/h3&gt;

&lt;p&gt;Q: What is blue-green deployment?&lt;/p&gt;

&lt;p&gt;Blue-green deployment uses two separate application environments. One serves production traffic while the other hosts the new version. Once the new version passes validation, traffic switches to it. If problems occur, traffic can be redirected to the previous version.&lt;/p&gt;

&lt;p&gt;Q: How did you switch traffic?&lt;/p&gt;

&lt;p&gt;In this example, an automated Bash script updated the NGINX upstream configuration and reloaded NGINX after validating the configuration.&lt;/p&gt;

&lt;p&gt;Q: What commands would you use?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx
curl &lt;span class="nt"&gt;-I&lt;/span&gt; https://application.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q: What would you do if the new version had already changed the database schema?&lt;/p&gt;

&lt;p&gt;I would verify database backward compatibility before switching traffic. An application rollback is not automatically a safe database rollback, so schema migrations need a separate recovery plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Production incident #2 — AWS infrastructure connectivity issue
&lt;/h2&gt;

&lt;p&gt;AWS VPC · Security groups · ALB · Networking&lt;/p&gt;

&lt;p&gt;This is a sample incident built around Marta's documented AWS networking and connectivity troubleshooting experience.&lt;/p&gt;

&lt;p&gt;Another incident involved an application connectivity problem in our AWS environment.&lt;/p&gt;

&lt;p&gt;The application was deployed, but users were experiencing connection failures, and the application wasn't responding as expected.&lt;/p&gt;

&lt;p&gt;I started by checking the application health and reviewing the AWS load balancer configuration.&lt;/p&gt;

&lt;p&gt;I noticed that the Application Load Balancer was reporting unhealthy targets.&lt;/p&gt;

&lt;p&gt;My next step was to investigate the target group health checks, EC2 instance status, and security group configurations.&lt;/p&gt;

&lt;p&gt;After reviewing the networking configuration, we identified a security group rule that was preventing the load balancer from reaching the application on the required port.&lt;/p&gt;

&lt;p&gt;I worked with the team to update the security group configuration through Terraform, following our normal review and approval process.&lt;/p&gt;

&lt;p&gt;After applying the change, we verified that the ALB health checks were passing and the application became accessible again.&lt;/p&gt;

&lt;p&gt;We continued monitoring the application to confirm that connectivity was stable.&lt;/p&gt;

&lt;p&gt;As a preventive measure, we reviewed our Terraform modules and added additional validation to reduce the possibility of similar networking configuration issues.&lt;/p&gt;

&lt;p&gt;The key lesson was that even a small infrastructure configuration change can have a major impact on application availability, which is why automated validation and infrastructure code reviews are so important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical follow-up questions
&lt;/h3&gt;

&lt;p&gt;Q: How do you investigate an ALB reporting unhealthy targets?&lt;/p&gt;

&lt;p&gt;I check target group health status and reason codes, listener rules, health-check path and port, application readiness, security groups, network ACLs, and route tables.&lt;/p&gt;

&lt;p&gt;Q: What AWS commands might you use?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws elbv2 describe-target-health &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--target-group-arn&lt;/span&gt; &amp;lt;target-group-arn&amp;gt;

aws ec2 describe-security-groups &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-ids&lt;/span&gt; &amp;lt;security-group-id&amp;gt;

aws ec2 describe-instances &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; &amp;lt;instance-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q: Why manage security groups through Terraform?&lt;/p&gt;

&lt;p&gt;Because it keeps infrastructure configuration version-controlled, reviewable, and consistent across environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Explain your company structure and engineering team
&lt;/h2&gt;

&lt;p&gt;Marta's resume does not specify Wells Fargo's actual reporting structure or team size. This is a reasonable sample description, not a verified organizational chart.&lt;/p&gt;

&lt;p&gt;At Wells Fargo, I work as part of the cloud infrastructure and DevOps engineering function.&lt;/p&gt;

&lt;p&gt;Our responsibility is to support AWS infrastructure, application deployment automation, and production reliability.&lt;/p&gt;

&lt;p&gt;We collaborate closely with application developers, QA engineers, security teams, networking engineers, and other infrastructure teams.&lt;/p&gt;

&lt;p&gt;The DevOps engineers focus on infrastructure provisioning, CI/CD automation, Kubernetes workloads, monitoring, and production troubleshooting.&lt;/p&gt;

&lt;p&gt;Development teams are responsible for application functionality and code changes, while we provide the infrastructure and automated deployment processes that support those applications.&lt;/p&gt;

&lt;p&gt;Security engineers help establish access controls, vulnerability management, and security requirements.&lt;/p&gt;

&lt;p&gt;Networking engineers support connectivity, routing, DNS, and network security.&lt;/p&gt;

&lt;p&gt;When we work on major infrastructure changes or production issues, we coordinate with the relevant teams to make sure the changes are implemented safely.&lt;/p&gt;

&lt;p&gt;Although my primary role has been hands-on engineering, I also contribute to engineering standardization through reusable Terraform modules, automated workflows, documentation, and technical collaboration.&lt;/p&gt;

&lt;p&gt;Cloud Infrastructure / Engineering Leadership&lt;/p&gt;

&lt;p&gt;DevOps / Platform Engineering Team&lt;/p&gt;

&lt;p&gt;Marta — Senior DevOps Engineer&lt;/p&gt;

&lt;p&gt;AWS · Terraform · Kubernetes · CI/CD · Reliability&lt;/p&gt;

&lt;p&gt;Application / QA&lt;/p&gt;

&lt;p&gt;Security / Networking&lt;/p&gt;

&lt;p&gt;Operations / Support&lt;/p&gt;

&lt;p&gt;Illustrative collaboration structure; actual reporting lines should be confirmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What meetings do you attend?
&lt;/h2&gt;

&lt;p&gt;We typically work in an Agile-style environment, so I participate in regular engineering and operational meetings.&lt;/p&gt;

&lt;p&gt;We have daily stand-ups to review our progress, discuss current priorities, and identify blockers.&lt;/p&gt;

&lt;p&gt;During sprint planning, we review upcoming infrastructure work, automation improvements, and technical tasks.&lt;/p&gt;

&lt;p&gt;We also have technical discussions and design reviews when we're introducing new AWS infrastructure, modifying Terraform modules, or improving deployment workflows.&lt;/p&gt;

&lt;p&gt;For production releases, we coordinate deployment schedules, change approvals, risk assessments, and rollback plans.&lt;/p&gt;

&lt;p&gt;If a significant production issue occurs, we conduct an incident review to understand what happened, identify the root cause, and discuss preventive actions.&lt;/p&gt;

&lt;p&gt;I also participate in cross-team meetings with developers, security engineers, and infrastructure teams when changes affect multiple systems.&lt;/p&gt;

&lt;p&gt;These meetings help us maintain visibility, manage dependencies, and ensure infrastructure changes support the broader engineering goals.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Meeting&lt;/th&gt;
&lt;th&gt;Example frequency&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily stand-up&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Priorities and blockers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sprint planning&lt;/td&gt;
&lt;td&gt;Every 2 weeks&lt;/td&gt;
&lt;td&gt;Work allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backlog refinement&lt;/td&gt;
&lt;td&gt;Weekly&lt;/td&gt;
&lt;td&gt;Technical requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture review&lt;/td&gt;
&lt;td&gt;As needed&lt;/td&gt;
&lt;td&gt;Cloud design decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change / release review&lt;/td&gt;
&lt;td&gt;Before major releases&lt;/td&gt;
&lt;td&gt;Deployment safety&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident review&lt;/td&gt;
&lt;td&gt;After significant incidents&lt;/td&gt;
&lt;td&gt;RCA and prevention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engineering 1:1&lt;/td&gt;
&lt;td&gt;Weekly or biweekly&lt;/td&gt;
&lt;td&gt;Development and priorities&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. Tell me about your cloud cost optimization experience
&lt;/h2&gt;

&lt;p&gt;This is one of Marta's strongest documented accomplishments and is particularly relevant to the management position.&lt;/p&gt;

&lt;p&gt;Cloud cost optimization has been an important part of my work at Wells Fargo.&lt;/p&gt;

&lt;p&gt;We wanted to reduce unnecessary AWS spending, particularly in our development environments, without affecting application performance or reliability.&lt;/p&gt;

&lt;p&gt;I started by reviewing AWS Cost Explorer reports to identify our major cost drivers.&lt;/p&gt;

&lt;p&gt;Then I used CloudWatch metrics to analyze resource utilization, including CPU and memory trends where available.&lt;/p&gt;

&lt;p&gt;We identified opportunities to right-size EC2 instances and optimize storage resources based on actual usage.&lt;/p&gt;

&lt;p&gt;I also reviewed infrastructure configurations to make sure our development environments were provisioned consistently.&lt;/p&gt;

&lt;p&gt;We implemented the approved changes and monitored the environments afterward to verify that application performance remained stable.&lt;/p&gt;

&lt;p&gt;As a result of this optimization effort, we reduced monthly development AWS spending by approximately 35%.&lt;/p&gt;

&lt;p&gt;For me, cloud cost optimization is not just about reducing expenses. It's about finding the right balance between performance, availability, security, and cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Tell me about your Terraform experience
&lt;/h2&gt;

&lt;p&gt;Terraform is one of the main tools I use for infrastructure automation.&lt;/p&gt;

&lt;p&gt;At Wells Fargo, I've worked with reusable Terraform modules to provision AWS resources across more than eight environments.&lt;/p&gt;

&lt;p&gt;These modules cover infrastructure components such as VPCs, subnets, EC2 instances, IAM roles, security groups, load balancers, and Auto Scaling.&lt;/p&gt;

&lt;p&gt;We use remote Terraform state in Amazon S3 and state locking to help prevent conflicting infrastructure changes.&lt;/p&gt;

&lt;p&gt;Our infrastructure code is version-controlled, and changes go through a review process before being applied.&lt;/p&gt;

&lt;p&gt;One of the biggest advantages of using reusable modules is consistency. Instead of manually configuring infrastructure for every environment, we can standardize the resources and customize them using variables.&lt;/p&gt;

&lt;p&gt;This reduces configuration drift, makes troubleshooting easier, and helps us provision infrastructure more efficiently.&lt;/p&gt;

&lt;p&gt;I've also worked with Terraform and Ansible together to automate AWS infrastructure provisioning and server configuration.&lt;/p&gt;

&lt;p&gt;I believe Infrastructure as Code is essential for managing cloud environments reliably at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. How do you demonstrate leadership without being a people manager?
&lt;/h2&gt;

&lt;p&gt;This is likely one of the most important questions for this particular job.&lt;/p&gt;

&lt;p&gt;My background has primarily been in senior hands-on engineering rather than formal people management.&lt;/p&gt;

&lt;p&gt;However, I've contributed to technical leadership by helping standardize infrastructure provisioning, improve deployment processes, and establish repeatable engineering practices.&lt;/p&gt;

&lt;p&gt;For example, at Wells Fargo, I worked on reusable Terraform modules across multiple AWS environments, which helped make infrastructure provisioning more consistent.&lt;/p&gt;

&lt;p&gt;I also contributed to improving CI/CD automation and release reliability.&lt;/p&gt;

&lt;p&gt;I believe strong technical leadership involves understanding problems, evaluating trade-offs, communicating clearly, and helping teams adopt solutions that are reliable and maintainable.&lt;/p&gt;

&lt;p&gt;I also understand that a formal engineering management role involves additional responsibilities, including people development, prioritization, resource planning, and stakeholder management.&lt;/p&gt;

&lt;p&gt;Those are areas I'm interested in developing further while bringing a strong technical foundation to the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Why are you interested in Herc Rentals?
&lt;/h2&gt;

&lt;p&gt;I'm interested in this opportunity because it combines cloud infrastructure engineering with broader platform ownership and leadership responsibilities.&lt;/p&gt;

&lt;p&gt;My experience has been focused on building reliable AWS environments, automating infrastructure with Terraform, supporting Kubernetes workloads, and improving CI/CD and operational processes.&lt;/p&gt;

&lt;p&gt;What interests me about this position is the opportunity to apply that experience at a broader organizational level, helping establish engineering standards, improve cloud governance, and support a long-term cloud platform strategy.&lt;/p&gt;

&lt;p&gt;I also appreciate the focus on reliability, security, and cost optimization, because those are areas where I've delivered measurable improvements.&lt;/p&gt;

&lt;p&gt;For example, I've helped reduce deployment time from 45 minutes to 8 minutes, improve rollback time from 20 minutes to 2 minutes, and reduce development AWS spending by 35%.&lt;/p&gt;

&lt;p&gt;I see this as an opportunity to contribute my technical experience while continuing to grow in engineering leadership and platform strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Advanced questions to prepare for
&lt;/h2&gt;

&lt;p&gt;1. How would you design a multi-cloud platform strategy?&lt;/p&gt;

&lt;p&gt;Start with business requirements, workload suitability, security, compliance, cost, and recovery objectives. Define consistent identity, networking, monitoring, tagging, IaC, and governance standards across AWS, Azure, and OCI. Avoid moving workloads between clouds without a clear business justification.&lt;/p&gt;

&lt;p&gt;2. How would you manage a cloud engineering team?&lt;/p&gt;

&lt;p&gt;3. How do you manage cloud governance?&lt;/p&gt;

&lt;p&gt;4. How would you design disaster recovery?&lt;/p&gt;

&lt;p&gt;5. How do you prevent Terraform configuration drift?&lt;/p&gt;

&lt;p&gt;6. What is your experience with Azure and OCI?&lt;/p&gt;

&lt;p&gt;7. How would you handle disagreement between engineers?&lt;/p&gt;

&lt;p&gt;8. How would you measure platform engineering success?&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Practice mock interview
&lt;/h2&gt;

</description>
    </item>
    <item>
      <title>DevOps Engineer (AWS) — Interview Preparation for Elena Abditalipova</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Wed, 28 Oct 2026 03:44:52 +0000</pubDate>
      <link>https://dev.to/jumptotech/devops-engineer-aws-interview-preparation-for-elena-abditalipova-2apl</link>
      <guid>https://dev.to/jumptotech/devops-engineer-aws-interview-preparation-for-elena-abditalipova-2apl</guid>
      <description>&lt;p&gt;HICKS PROFESSIONAL GROUP · CATERPILLAR OPPORTUNITY · CHICAGO / IRVING&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Tell me about yourself
&lt;/h2&gt;

&lt;p&gt;Sure, absolutely.&lt;/p&gt;

&lt;p&gt;My name is Elena, and I'm a DevOps Engineer with over five years of experience working with AWS cloud infrastructure, Kubernetes, Terraform, CI/CD automation, and production support.&lt;/p&gt;

&lt;p&gt;Currently, I'm working at Northern Trust, where my main responsibility is managing and improving our AWS infrastructure and Kubernetes environments.&lt;/p&gt;

&lt;p&gt;We use Amazon EKS to run containerized applications, Terraform to provision infrastructure, GitHub Actions and Jenkins for CI/CD automation, and Argo CD for GitOps-based deployments.&lt;/p&gt;

&lt;p&gt;A big part of my work involves building reusable Terraform modules, improving deployment pipelines, monitoring production environments, and troubleshooting infrastructure and application issues.&lt;/p&gt;

&lt;p&gt;For monitoring, I work with Prometheus, Grafana, Datadog, and AWS CloudWatch. We use these tools to monitor application health, resource utilization, and infrastructure performance.&lt;/p&gt;

&lt;p&gt;Before Northern Trust, I worked at CDW, where I focused on infrastructure automation, containerization, and CI/CD pipelines. Earlier, at Apex Systems, I supported cloud migration projects and automated AWS infrastructure using Terraform and Bash.&lt;/p&gt;

&lt;p&gt;I also have experience using AI tools like GitHub Copilot, OpenAI, and Claude to improve infrastructure automation, troubleshooting, and technical documentation.&lt;/p&gt;

&lt;p&gt;What I enjoy most about DevOps is solving complex production problems, reducing manual work through automation, and building reliable infrastructure that development teams can use efficiently.&lt;/p&gt;

&lt;p&gt;I'm particularly interested in this opportunity because it closely aligns with my experience in AWS, EKS, Terraform, GitHub Actions, and Kubernetes automation.&lt;/p&gt;

&lt;p&gt;Target speaking time: 90 seconds to 2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What are your day-to-day responsibilities?
&lt;/h2&gt;

&lt;p&gt;My daily responsibilities are a combination of infrastructure automation, Kubernetes operations, CI/CD improvements, monitoring, and production support.&lt;/p&gt;

&lt;p&gt;I usually start my day by reviewing our monitoring dashboards in Grafana, Datadog, and CloudWatch to make sure our production applications and Kubernetes clusters are healthy.&lt;/p&gt;

&lt;p&gt;I check for any critical alerts, failed deployments, pod restarts, high CPU or memory utilization, and infrastructure issues.&lt;/p&gt;

&lt;p&gt;After that, we have our daily stand-up meeting, where we discuss what we completed yesterday, what we're working on today, and whether we have any blockers.&lt;/p&gt;

&lt;p&gt;Throughout the day, I work on Jira tickets, which might involve updating Terraform modules, improving GitHub Actions workflows, deploying applications through Argo CD, or troubleshooting Kubernetes issues.&lt;/p&gt;

&lt;p&gt;For example, if a development team needs a new AWS resource, I update the appropriate Terraform module, open a pull request, and go through our code review and approval process before applying the changes.&lt;/p&gt;

&lt;p&gt;I also maintain our CI/CD pipelines. When developers push code, GitHub Actions automatically runs tests, builds Docker images, performs security scans, and pushes approved images to Amazon ECR. Argo CD then helps synchronize our Kubernetes deployments with the desired configuration in Git.&lt;/p&gt;

&lt;p&gt;Another important part of my job is production support. If an application becomes unavailable or a deployment fails, I investigate the issue using kubectl, application logs, Kubernetes events, and monitoring dashboards.&lt;/p&gt;

&lt;p&gt;I also collaborate closely with developers, QA engineers, security teams, and other infrastructure engineers to make sure our releases are secure and reliable.&lt;/p&gt;

&lt;p&gt;My overall goal is to keep our infrastructure stable, automate repetitive tasks, and help development teams deliver applications faster and more safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Tell me about a production incident you resolved — Kubernetes application outage
&lt;/h2&gt;

&lt;p&gt;Scenario 1 · EKS · CrashLoopBackOff · Application availability&lt;/p&gt;

&lt;p&gt;This is a realistic incident example consistent with Elena's listed EKS and troubleshooting skills, but the specific incident is not verified by the resume.&lt;/p&gt;

&lt;p&gt;Sure. One incident I can describe involves an application running in our production Amazon EKS environment.&lt;/p&gt;

&lt;p&gt;After a new deployment, we started receiving alerts from Datadog and Prometheus indicating that some application pods were unhealthy and the application error rate was increasing.&lt;/p&gt;

&lt;p&gt;My first step was to assess the impact and check the health of the Kubernetes workloads.&lt;/p&gt;

&lt;p&gt;I used kubectl get pods to review the pod status and noticed that several pods were entering CrashLoopBackOff.&lt;/p&gt;

&lt;p&gt;Then I used kubectl describe pod and kubectl logs --previous to investigate why the containers were restarting.&lt;/p&gt;

&lt;p&gt;The logs showed that the application was failing during startup because it couldn't load a required environment variable.&lt;/p&gt;

&lt;p&gt;I compared the new deployment configuration with the previous working version and found that a required configuration value had been omitted from the new release.&lt;/p&gt;

&lt;p&gt;Since this was affecting production, our first priority was restoring service.&lt;/p&gt;

&lt;p&gt;We rolled back to the previous stable deployment using Argo CD and verified that the application pods became healthy again.&lt;/p&gt;

&lt;p&gt;After service was restored, I worked with the development team to correct the missing configuration and validate it in our lower environment.&lt;/p&gt;

&lt;p&gt;We also improved our deployment validation process by adding configuration checks to the GitHub Actions pipeline.&lt;/p&gt;

&lt;p&gt;The result was that we restored application availability and reduced the risk of the same issue happening again.&lt;/p&gt;

&lt;p&gt;The biggest lesson from this incident was the importance of automated configuration validation and having a reliable rollback strategy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical follow-up questions
&lt;/h3&gt;

&lt;p&gt;Q: How did you identify CrashLoopBackOff?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl describe pod &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl logs &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--previous&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q: Why did the pod restart?&lt;/p&gt;

&lt;p&gt;The application process exited during startup because a required configuration value was missing. Kubernetes restarted the container according to the pod's restart policy, and repeated failures caused the backoff delay.&lt;/p&gt;

&lt;p&gt;Q: How did you roll back?&lt;/p&gt;

&lt;p&gt;For an Argo CD-managed application, we restored the last known-good configuration in Git and synchronized the application. A direct &lt;code&gt;kubectl rollout undo&lt;/code&gt; may also be used as an emergency mitigation, but the GitOps desired state must be corrected to prevent Argo CD from restoring the faulty version.&lt;/p&gt;

&lt;p&gt;Q: How did you prevent recurrence?&lt;/p&gt;

&lt;p&gt;We added required configuration checks in CI, tested the release in a lower environment, and improved deployment monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Tell me about another production incident — High CPU and EKS performance degradation
&lt;/h2&gt;

&lt;p&gt;Scenario 2 · AWS EKS · HPA · Resource limits · Performance&lt;/p&gt;

&lt;p&gt;Another incident involved performance degradation in our Kubernetes environment during a period of increased application traffic.&lt;/p&gt;

&lt;p&gt;We received alerts from Prometheus and Grafana showing high CPU utilization and increased application response times.&lt;/p&gt;

&lt;p&gt;I started by checking the cluster and workload health using kubectl top nodes and kubectl top pods.&lt;/p&gt;

&lt;p&gt;I noticed that several application pods were consuming significantly more CPU than usual, and some workloads were approaching their configured CPU limits.&lt;/p&gt;

&lt;p&gt;I checked the Horizontal Pod Autoscaler configuration and noticed that the application wasn't scaling as expected.&lt;/p&gt;

&lt;p&gt;After investigating the HPA configuration and resource metrics, we identified an issue with the CPU resource requests used by the workload, which affected the autoscaling behavior.&lt;/p&gt;

&lt;p&gt;I worked with the team to update the resource requests and limits, verify that the metrics pipeline was functioning correctly, and adjust the HPA configuration.&lt;/p&gt;

&lt;p&gt;We also reviewed node capacity to make sure the cluster had enough resources to schedule additional replicas.&lt;/p&gt;

&lt;p&gt;After applying the changes, the HPA started scaling the application appropriately as traffic increased.&lt;/p&gt;

&lt;p&gt;We monitored the deployment through Grafana and CloudWatch and confirmed that CPU utilization stabilized and application response times improved.&lt;/p&gt;

&lt;p&gt;As a preventive measure, we added more specific alerts for HPA scaling conditions, resource saturation, and application latency.&lt;/p&gt;

&lt;p&gt;This incident reinforced the importance of properly configuring Kubernetes resource requests, autoscaling policies, and cluster capacity together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical follow-up questions
&lt;/h3&gt;

&lt;p&gt;Q: What commands did you use?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top nodes
kubectl top pods &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl describe hpa &amp;lt;hpa-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl describe deployment &amp;lt;deployment-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q: How does HPA calculate CPU utilization?&lt;/p&gt;

&lt;p&gt;For CPU utilization-based scaling, HPA compares actual CPU usage against the CPU requests configured for containers. If resource requests are missing or unsuitable, scaling can behave incorrectly.&lt;/p&gt;

&lt;p&gt;Q: What if HPA increases replicas but pods remain Pending?&lt;/p&gt;

&lt;p&gt;I would check node capacity, scheduler events, node taints, resource requests, and whether Cluster Autoscaler or Karpenter is configured to provision additional capacity.&lt;/p&gt;

&lt;p&gt;Q: What's the difference between HPA and Karpenter?&lt;/p&gt;

&lt;p&gt;HPA scales the number of application pod replicas. Karpenter provisions and manages worker-node capacity so the cluster can accommodate unschedulable workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Explain your company structure and DevOps team
&lt;/h2&gt;

&lt;p&gt;The resume confirms Northern Trust as Elena's current employer but does not specify her reporting structure or team size. The following is a sample enterprise team description to adapt to her actual situation.&lt;/p&gt;

&lt;p&gt;At Northern Trust, I work within the cloud infrastructure and DevOps engineering organization.&lt;/p&gt;

&lt;p&gt;Our team is responsible for supporting AWS infrastructure, Kubernetes platforms, CI/CD automation, and application deployment processes.&lt;/p&gt;

&lt;p&gt;We work closely with several application development teams, as well as QA, security, networking, and infrastructure teams.&lt;/p&gt;

&lt;p&gt;In a typical team structure, we have a DevOps engineering manager, senior DevOps engineers, DevOps engineers, and platform or cloud engineers.&lt;/p&gt;

&lt;p&gt;Our DevOps team is responsible for infrastructure provisioning, Kubernetes operations, deployment automation, monitoring, and production reliability.&lt;/p&gt;

&lt;p&gt;Developers focus on application code and business functionality, while our team provides the infrastructure and automation needed to build, test, and deploy their applications.&lt;/p&gt;

&lt;p&gt;We also collaborate with security engineers on IAM permissions, secrets management, vulnerability scanning, and infrastructure security.&lt;/p&gt;

&lt;p&gt;When production incidents occur, we coordinate with the application owners and relevant infrastructure teams to identify the root cause, restore service, and implement preventive improvements.&lt;/p&gt;

&lt;p&gt;We use Jira to track tasks and GitHub for source control, pull requests, and infrastructure code reviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example organizational structure
&lt;/h3&gt;

&lt;p&gt;Engineering / Cloud Infrastructure Leadership&lt;/p&gt;

&lt;p&gt;DevOps / Platform Engineering Manager&lt;/p&gt;

&lt;p&gt;DevOps / SRE Team&lt;/p&gt;

&lt;p&gt;Senior Engineers · DevOps Engineers · Platform Engineers&lt;/p&gt;

&lt;p&gt;Elena — DevOps Engineer&lt;/p&gt;

&lt;p&gt;Development / QA&lt;/p&gt;

&lt;p&gt;Security / Networking&lt;/p&gt;

&lt;p&gt;Cloud / Operations&lt;/p&gt;

&lt;p&gt;Illustrative team structure, not a verified Northern Trust organization chart.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What meetings do you attend?
&lt;/h2&gt;

&lt;p&gt;We follow an Agile-style workflow, so I participate in several regular meetings.&lt;/p&gt;

&lt;p&gt;Every morning, we have a daily stand-up, usually around 15 minutes, where we discuss what we worked on yesterday, our priorities for today, and any blockers.&lt;/p&gt;

&lt;p&gt;We also have sprint planning meetings, where we review upcoming Jira tickets, estimate the effort required, and decide which infrastructure or automation tasks we can complete during the sprint.&lt;/p&gt;

&lt;p&gt;During backlog refinement, we review technical requirements and clarify dependencies before starting new work.&lt;/p&gt;

&lt;p&gt;I also participate in technical design discussions, especially when we're planning Terraform infrastructure changes, Kubernetes upgrades, or CI/CD improvements.&lt;/p&gt;

&lt;p&gt;Before major production deployments, we may have release readiness or change review meetings to discuss risks, rollback plans, and deployment procedures.&lt;/p&gt;

&lt;p&gt;If we experience a significant production incident, we hold a post-incident review to discuss the root cause, business impact, and preventive actions.&lt;/p&gt;

&lt;p&gt;Finally, I have regular one-on-one meetings with my manager to discuss priorities, performance, and professional development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example meeting schedule
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Meeting&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily stand-up&lt;/td&gt;
&lt;td&gt;Daily, 15 min&lt;/td&gt;
&lt;td&gt;Progress and blockers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sprint planning&lt;/td&gt;
&lt;td&gt;Every 2 weeks&lt;/td&gt;
&lt;td&gt;Assign sprint work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backlog refinement&lt;/td&gt;
&lt;td&gt;Weekly&lt;/td&gt;
&lt;td&gt;Review Jira tickets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Technical design&lt;/td&gt;
&lt;td&gt;As needed&lt;/td&gt;
&lt;td&gt;Architecture and changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Release / change review&lt;/td&gt;
&lt;td&gt;Before major releases&lt;/td&gt;
&lt;td&gt;Risk and approval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident review&lt;/td&gt;
&lt;td&gt;After significant incidents&lt;/td&gt;
&lt;td&gt;Root cause and prevention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manager 1:1&lt;/td&gt;
&lt;td&gt;Weekly or biweekly&lt;/td&gt;
&lt;td&gt;Priorities and feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. Describe your GitHub Actions pipeline
&lt;/h2&gt;

&lt;p&gt;This question is especially important because the job description requires extensive GitHub Actions experience.&lt;/p&gt;

&lt;p&gt;In my current role, I work with GitHub Actions to automate our application build, testing, security scanning, and deployment processes.&lt;/p&gt;

&lt;p&gt;Our typical pipeline starts when a developer opens a pull request or pushes changes to the repository.&lt;/p&gt;

&lt;p&gt;First, we run code quality checks, unit tests, and dependency scanning.&lt;/p&gt;

&lt;p&gt;Once the code is approved and merged, the pipeline builds a Docker image using a multi-stage Dockerfile.&lt;/p&gt;

&lt;p&gt;We then run container security scanning using tools such as Trivy and publish the approved image to Amazon ECR.&lt;/p&gt;

&lt;p&gt;For AWS authentication, I prefer using GitHub Actions OIDC with IAM roles instead of storing long-lived AWS access keys.&lt;/p&gt;

&lt;p&gt;After the image is published, the deployment process updates the appropriate Kubernetes configuration in Git, and Argo CD synchronizes the changes to our EKS environment.&lt;/p&gt;

&lt;p&gt;We also use environment-specific configurations and approval controls for production deployments.&lt;/p&gt;

&lt;p&gt;One of the main benefits of this approach is that it gives us consistent, repeatable deployments with better security and traceability.&lt;/p&gt;

&lt;p&gt;I'm also comfortable working with reusable workflows to avoid duplicating the same CI/CD logic across multiple repositories.&lt;/p&gt;

&lt;p&gt;Typical deployment flow&lt;/p&gt;

&lt;p&gt;GitHub Pull Request / Merge&lt;/p&gt;

&lt;p&gt;Unit Tests&lt;/p&gt;

&lt;p&gt;Code Quality&lt;/p&gt;

&lt;p&gt;Security Scan&lt;/p&gt;

&lt;p&gt;Docker Build → Amazon ECR&lt;/p&gt;

&lt;p&gt;Update GitOps Repository&lt;/p&gt;

&lt;p&gt;Argo CD → Amazon EKS&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Why are you interested in this position?
&lt;/h2&gt;

&lt;p&gt;I'm interested in this position because the technical requirements align very closely with the work I've been doing.&lt;/p&gt;

&lt;p&gt;My strongest areas are AWS infrastructure, Kubernetes, Terraform, GitHub Actions, and automation.&lt;/p&gt;

&lt;p&gt;What particularly interests me is the opportunity to work on enterprise-scale EKS environments, improve CI/CD workflows, and contribute to infrastructure standardization.&lt;/p&gt;

&lt;p&gt;I also like that the position focuses on reliability, security, and cost optimization rather than just deploying applications.&lt;/p&gt;

&lt;p&gt;I'm looking for an opportunity where I can take more ownership of infrastructure automation, solve challenging production problems, and continue growing as a DevOps and platform engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Additional questions Elena should prepare for
&lt;/h2&gt;

&lt;p&gt;The recruiter specifically emphasizes several advanced topics that are not clearly demonstrated in the resume, especially Karpenter, Actions Runner Controller, OIDC, IRSA, and zero-downtime EKS upgrades.&lt;/p&gt;

&lt;p&gt;1. How do you implement GitHub Actions OIDC authentication with AWS?&lt;/p&gt;

&lt;p&gt;Configure the GitHub OIDC identity provider in IAM, create an IAM role with a restricted trust policy for the repository and environment, and use aws-actions/configure-aws-credentials to assume that role. This avoids storing long-lived AWS access keys.&lt;/p&gt;

&lt;p&gt;2. How would you upgrade a production EKS cluster with minimal downtime?&lt;/p&gt;

&lt;p&gt;3. What is IRSA?&lt;/p&gt;

&lt;p&gt;4. How do you troubleshoot a Kubernetes pod stuck in Pending?&lt;/p&gt;

&lt;p&gt;5. How do you handle Terraform state?&lt;/p&gt;

&lt;p&gt;6. What is Actions Runner Controller?&lt;/p&gt;

&lt;p&gt;7. What is the difference between Argo CD and GitHub Actions?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JumpToTech DevOps + AI Bootcamp Hands-On Lab: Kubernetes Monitoring, Grafana Persistence, Gmail SMTP, and Production Alerts</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Mon, 26 Oct 2026 23:24:09 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-devops-ai-bootcamp-hands-on-lab-kubernetes-monitoring-grafana-persistence-gmail-2598</link>
      <guid>https://dev.to/jumptotech/jumptotech-devops-ai-bootcamp-hands-on-lab-kubernetes-monitoring-grafana-persistence-gmail-2598</guid>
      <description>&lt;p&gt;&lt;strong&gt;Environment:&lt;/strong&gt; AWS EKS&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Namespace:&lt;/strong&gt; &lt;code&gt;dev&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; Kubernetes, Helm, Prometheus, Grafana, AWS EBS CSI Driver, Gmail SMTP&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Estimated duration:&lt;/strong&gt; 2–3 hours&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Intermediate&lt;/p&gt;
&lt;h3&gt;
  
  
  Learning objectives
&lt;/h3&gt;

&lt;p&gt;By the end of this lab, students will be able to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy Prometheus and Grafana into Kubernetes.&lt;/li&gt;
&lt;li&gt;Configure persistent storage for Grafana using AWS EBS.&lt;/li&gt;
&lt;li&gt;Understand the difference between &lt;code&gt;emptyDir&lt;/code&gt; and PersistentVolumeClaims.&lt;/li&gt;
&lt;li&gt;Configure Gmail SMTP securely using Kubernetes Secrets.&lt;/li&gt;
&lt;li&gt;Create Grafana email contact points and notification policies.&lt;/li&gt;
&lt;li&gt;Create an &lt;code&gt;ImagePullBackOff&lt;/code&gt; alert using PromQL.&lt;/li&gt;
&lt;li&gt;Simulate a Kubernetes incident and receive an email notification.&lt;/li&gt;
&lt;li&gt;Verify Grafana data survives a Pod restart.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Important architecture decision
&lt;/h3&gt;

&lt;p&gt;Students must use their own development EKS cluster or an instructor-approved isolated lab environment.&lt;/p&gt;

&lt;p&gt;Do not modify the existing production monitoring release.&lt;/p&gt;

&lt;p&gt;The namespace &lt;code&gt;dev&lt;/code&gt; isolates Kubernetes objects, but it does not provide complete security or resource isolation. Students must use their own credentials and must not share passwords.&lt;/p&gt;


&lt;h1&gt;
  
  
  Part 1 — Verify the Kubernetes environment
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Step 1: Verify AWS identity
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws sts get-caller-identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This confirms which AWS account and IAM identity the CLI is using.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Connect to EKS
&lt;/h3&gt;

&lt;p&gt;Replace the cluster name and region with your assigned development cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EKS_CLUSTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR-DEV-CLUSTER"&lt;/span&gt;

aws eks update-kubeconfig &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AWS_REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EKS_CLUSTER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config current-context
kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl cluster-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected result:&lt;/strong&gt; At least one worker node is &lt;code&gt;Ready&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the dev namespace
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dry-run&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;client &lt;span class="nt"&gt;-o&lt;/span&gt; yaml | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -

kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All application and monitoring resources in this lab will be deployed into &lt;code&gt;dev&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 2 — Verify AWS EBS storage
&lt;/h1&gt;

&lt;p&gt;AWS EBS provides persistent block storage for Kubernetes workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Check the EBS CSI driver
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks describe-addon &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cluster-name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EKS_CLUSTER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--addon-name&lt;/span&gt; aws-ebs-csi-driver &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AWS_REGION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'addon.{status:status,version:addonVersion,issues:health.issues}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ACTIVE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system | &lt;span class="nb"&gt;grep &lt;/span&gt;ebs-csi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the add-on is missing, stop and ask the instructor to install it with the correct IAM permissions. Do not create an EBS CSI IAM role or install the add-on independently in a shared cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Check StorageClasses
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get storageclass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for a class provisioned by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ebs.csi.aws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this lab, we will create a dedicated &lt;code&gt;gp3&lt;/code&gt; StorageClass if it does not already exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dev-gp3-storageclass.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: dev-gp3
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; dev-gp3-storageclass.yaml
kubectl get storageclass dev-gp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gp3&lt;/code&gt; is the AWS EBS volume type.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;encrypted: true&lt;/code&gt; enables EBS encryption.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Delete&lt;/code&gt; allows Kubernetes to delete the EBS volume when the PVC is deleted, subject to the provisioner and cloud cleanup succeeding.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WaitForFirstConsumer&lt;/code&gt; helps schedule the Pod and EBS volume in the same availability zone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StorageClasses are cluster-scoped, so this step requires instructor approval in shared environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 3 — Install Prometheus and Grafana in dev
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Step 1: Install Helm
&lt;/h3&gt;

&lt;p&gt;Check first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Helm is not installed, use the approved installation method for your operating system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Add the Helm repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add prometheus-community &lt;span class="se"&gt;\&lt;/span&gt;
  https://prometheus-community.github.io/helm-charts

helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create a working directory
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/jumptotech-monitoring-lab
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/jumptotech-monitoring-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Create monitoring values
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; monitoring-values.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
alertmanager:
  enabled: false

grafana:
  persistence:
    enabled: true
    type: pvc
    storageClassName: dev-gp3
    accessModes:
      - ReadWriteOnce
    size: 5Gi

  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 300m
      memory: 512Mi

prometheus:
  prometheusSpec:
    retention: 6h
    resources:
      requests:
        cpu: 200m
        memory: 512Mi
      limits:
        cpu: 500m
        memory: 1Gi
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are enabling persistent storage from the beginning, so students do not need to migrate an existing Grafana database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Install the monitoring stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; dev-monitoring &lt;span class="se"&gt;\&lt;/span&gt;
  prometheus-community/kube-prometheus-stack &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 92.7.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; monitoring-values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--wait&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt; 15m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm list &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get deployments &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grafana Pod running&lt;/li&gt;
&lt;li&gt;Prometheus Pod running&lt;/li&gt;
&lt;li&gt;Grafana PVC bound to EBS&lt;/li&gt;
&lt;li&gt;Helm release deployed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the installation fails, inspect Pod events and resource capacity before retrying.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 4 — Verify Grafana persistent storage
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Step 1: Find the Grafana Deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected Deployment name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev-monitoring-grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Inspect the storage volume
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.template.spec.volumes}'&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for a &lt;code&gt;persistentVolumeClaim&lt;/code&gt; storage volume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Verify the PVC
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dev
kubectl describe pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Grafana claim should be &lt;code&gt;Bound&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discussion question:&lt;/strong&gt; What would happen to Grafana dashboards if the application used &lt;code&gt;emptyDir&lt;/code&gt; instead of a PVC?&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 5 — Access Grafana
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Step 1: Retrieve the Grafana admin password
&lt;/h3&gt;

&lt;p&gt;Do not paste the password into chat or a shared document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get secret dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.data.admin-password}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Start port-forwarding
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  svc/dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  3000:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Kubernetes is managed from a remote EC2 machine, use an SSH tunnel to forward port 3000 to your own computer. Do not expose Grafana publicly just to complete this lab.&lt;/p&gt;

&lt;p&gt;Login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username: admin
Password: password retrieved from Kubernetes Secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Verify Grafana health
&lt;/h3&gt;

&lt;p&gt;From a second terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; http://localhost:3000/api/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ok"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additional fields may be returned.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 6 — Configure Gmail SMTP
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Step 1: Create a Google app password
&lt;/h3&gt;

&lt;p&gt;Students must use their own Gmail account.&lt;/p&gt;

&lt;p&gt;Open:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://myaccount.google.com/apppasswords" rel="noopener noreferrer"&gt;https://myaccount.google.com/apppasswords&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google 2-Step Verification enabled&lt;/li&gt;
&lt;li&gt;A new app password created for the Grafana lab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never use a normal Gmail login password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a Kubernetes Secret
&lt;/h3&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Enter Gmail address: "&lt;/span&gt; GMAIL_ADDRESS

&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Enter Gmail app password: "&lt;/span&gt; GMAIL_APP_PASSWORD
&lt;span class="nb"&gt;echo

&lt;/span&gt;kubectl create secret generic grafana-smtp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GMAIL_ADDRESS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GMAIL_APP_PASSWORD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;unset &lt;/span&gt;GMAIL_APP_PASSWORD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify without revealing credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get secret grafana-smtp &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grafana-smtp   Opaque   2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create SMTP Helm values
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; grafana-smtp-values.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
grafana:
  env:
    GF_SMTP_ENABLED: "true"
    GF_SMTP_HOST: "smtp.gmail.com:587"
    GF_SMTP_STARTTLS_POLICY: "MandatoryStartTLS"
    GF_SMTP_FROM_NAME: "JumpToTech Dev Alerts"
  envValueFrom:
    GF_SMTP_USER:
      secretKeyRef:
        name: grafana-smtp
        key: username
    GF_SMTP_PASSWORD:
      secretKeyRef:
        name: grafana-smtp
        key: password
    GF_SMTP_FROM_ADDRESS:
      secretKeyRef:
        name: grafana-smtp
        key: username
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses the same Gmail address for authentication and the email sender.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Preview the Helm deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm template dev-monitoring &lt;span class="se"&gt;\&lt;/span&gt;
  prometheus-community/kube-prometheus-stack &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 92.7.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; monitoring-values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; grafana-smtp-values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; monitoring-preview.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the Grafana SMTP environment variables and Secret references in the rendered Deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Upgrade Helm
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade dev-monitoring &lt;span class="se"&gt;\&lt;/span&gt;
  prometheus-community/kube-prometheus-stack &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 92.7.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; monitoring-values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; grafana-smtp-values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--wait&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt; 15m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;grafana

kubectl get deployment dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{range .spec.template.spec.containers[?(@.name=="grafana")].env[*]}{.name}{"\n"}{end}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep &lt;/span&gt;GF_SMTP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students should see seven SMTP environment variable names.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 7 — Configure email notifications in Grafana
&lt;/h1&gt;

&lt;p&gt;Open Grafana in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a contact point
&lt;/h3&gt;

&lt;p&gt;Navigate to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alerting → Notification configuration → Contact points&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;New contact point&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;Student-Dev-Email&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Integration: &lt;code&gt;Email&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Address: your own Gmail address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Send a test notification
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Test → Send test notification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Test notification sent successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Gmail inbox and Spam.&lt;/p&gt;

&lt;p&gt;The test may arrive with a subject containing &lt;code&gt;FIRING&lt;/code&gt;. This is a simulated alert and does not necessarily indicate a real incident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure the notification policy
&lt;/h3&gt;

&lt;p&gt;Navigate to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alerting → Notification configuration → Notification policies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For an isolated student Grafana installation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Default policy menu.&lt;/li&gt;
&lt;li&gt;Select Edit.&lt;/li&gt;
&lt;li&gt;Change the default contact point to &lt;code&gt;Student-Dev-Email&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep grouping and timing settings unchanged.&lt;/li&gt;
&lt;li&gt;Click Update policy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delivered to Student-Dev-Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not change a shared organization's default notification policy.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 8 — Create a real ImagePullBackOff incident
&lt;/h1&gt;

&lt;p&gt;We will deliberately deploy an application with a nonexistent container image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use only the dev namespace.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the broken Deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; broken-app.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: broken-restaurant
  namespace: dev
  labels:
    app: broken-restaurant
spec:
  replicas: 1
  selector:
    matchLabels:
      app: broken-restaurant
  template:
    metadata:
      labels:
        app: broken-restaurant
    spec:
      containers:
        - name: restaurant
          image: nginx:jumptotech-image-does-not-exist-2026
          imagePullPolicy: Always
          ports:
            - containerPort: 80
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; broken-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Observe the failure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl describe deployment broken-restaurant &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Pod should eventually show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ImagePullBackOff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Verify the Prometheus metric
&lt;/h3&gt;

&lt;p&gt;In Grafana, open &lt;strong&gt;Explore&lt;/strong&gt;, select the Prometheus data source, and enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kube_pod_container_status_waiting_reason{
  namespace="dev",
  reason="ImagePullBackOff"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the query in Instant mode.&lt;/p&gt;

&lt;p&gt;Expected: a matching series with value &lt;code&gt;1&lt;/code&gt; while the image-pull failure is present.&lt;/p&gt;

&lt;p&gt;If no series appears, verify that kube-state-metrics is running and that Prometheus is scraping it before continuing.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 9 — Create the ImagePullBackOff alert
&lt;/h1&gt;

&lt;p&gt;Navigate to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alerting → Alert rules → New alert rule&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Alert name
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEV - Kubernetes ImagePullBackOff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Prometheus query A
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kube_pod_container_status_waiting_reason{
  namespace="dev",
  reason="ImagePullBackOff"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use an Instant query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Alert condition
&lt;/h3&gt;

&lt;p&gt;Configure Grafana expressions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query A: Prometheus metric&lt;/li&gt;
&lt;li&gt;Expression B: Reduce, Last of A&lt;/li&gt;
&lt;li&gt;Expression C: Threshold, B is above 0.5&lt;/li&gt;
&lt;li&gt;Set C as the alert condition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This evaluates each matching container series and fires when its value is &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Evaluation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Evaluation interval: 1 minute&lt;/li&gt;
&lt;li&gt;Pending period: 2 minutes&lt;/li&gt;
&lt;li&gt;Keep firing for: 0 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use a dedicated folder and evaluation group, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Folder: JumpToTech-Dev
Evaluation group: dev-kubernetes-alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Notification routing
&lt;/h3&gt;

&lt;p&gt;Use the Grafana notification policy configured earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Default policy → Student-Dev-Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Alert message
&lt;/h3&gt;

&lt;p&gt;Summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ImagePullBackOff detected in dev namespace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kubernetes cannot pull a container image.
Check the Pod image, image registry, credentials, and Kubernetes events.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Save the alert
&lt;/h3&gt;

&lt;p&gt;Wait for the alert to evaluate.&lt;/p&gt;

&lt;p&gt;Expected progression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Normal → Pending → Firing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The email notification may arrive later because Grafana's notification policy also has grouping and delivery delays.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 10 — Fix the incident
&lt;/h1&gt;

&lt;p&gt;Once the alert is firing, students must troubleshoot and resolve the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Inspect the Pod
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl describe deployment broken-restaurant &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Fix the container image
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;set &lt;/span&gt;image deployment/broken-restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;restaurant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx:1.27 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Verify recovery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/broken-restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Running
1/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Verify alert recovery
&lt;/h3&gt;

&lt;p&gt;Return to Grafana.&lt;/p&gt;

&lt;p&gt;The alert should transition back toward &lt;code&gt;Normal&lt;/code&gt; after Prometheus and Grafana observe that the image-pull problem has cleared.&lt;/p&gt;

&lt;p&gt;Students should also check whether a resolved email notification arrives.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 11 — Test Grafana persistence
&lt;/h1&gt;

&lt;p&gt;Students must prove that Grafana can retain data after Pod replacement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a test dashboard
&lt;/h3&gt;

&lt;p&gt;In Grafana:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new dashboard.&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;JumpToTech Dev Persistence Test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a simple Prometheus panel.&lt;/li&gt;
&lt;li&gt;Save the dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Restart Grafana
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout restart deployment/dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl rollout status deployment/dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Verify the PVC
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dev
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; app.kubernetes.io/name&lt;span class="o"&gt;=&lt;/span&gt;grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Check Grafana
&lt;/h3&gt;

&lt;p&gt;Log back into Grafana and verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The test dashboard still exists.&lt;/li&gt;
&lt;li&gt;The email contact point still exists.&lt;/li&gt;
&lt;li&gt;The alert rule still exists.&lt;/li&gt;
&lt;li&gt;The notification policy is unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Expected result:&lt;/strong&gt; The Grafana database and its saved objects survive the Pod restart.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 12 — Troubleshooting
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;What to investigate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Grafana PVC Pending&lt;/td&gt;
&lt;td&gt;EBS CSI driver, IAM permissions, scheduling, storage class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana Pod Pending&lt;/td&gt;
&lt;td&gt;Node capacity, volume zone, Pod events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana HTTP 401&lt;/td&gt;
&lt;td&gt;Authentication or API permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gmail 535 error&lt;/td&gt;
&lt;td&gt;Incorrect or revoked Gmail app password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP timeout&lt;/td&gt;
&lt;td&gt;Outbound connectivity, port 587, security controls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No email received&lt;/td&gt;
&lt;td&gt;Contact point, policy routing, SMTP logs, Gmail Spam&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No Prometheus metric&lt;/td&gt;
&lt;td&gt;kube-state-metrics, scrape targets, namespace labels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alert stays Normal&lt;/td&gt;
&lt;td&gt;Query results, threshold, evaluation group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard disappears&lt;/td&gt;
&lt;td&gt;PVC mount, storage configuration, database errors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Useful troubleshooting commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dev

kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

kubectl logs &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  deployment/dev-monitoring-grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100

helm status dev-monitoring &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never paste credentials or decoded Kubernetes Secret values into reports.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 13 — Cleanup and cost control
&lt;/h1&gt;

&lt;p&gt;After the instructor approves cleanup, delete the deliberately broken application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete deployment broken-restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ignore-not-found&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this is a disposable, dedicated student cluster, the instructor may authorize removal of the monitoring release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm uninstall dev-monitoring &lt;span class="nt"&gt;-n&lt;/span&gt; dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Helm uninstall does not guarantee deletion of all PVCs or cloud volumes.&lt;/p&gt;

&lt;p&gt;Before deleting any PVC, identify its exact PV and EBS volume, verify that it belongs to this lab, and confirm the data is no longer needed.&lt;/p&gt;

&lt;p&gt;Do not delete shared namespaces, StorageClasses, EBS CSI drivers, or production volumes.&lt;/p&gt;

&lt;p&gt;AWS EBS volumes and EKS resources may incur charges while they exist.&lt;/p&gt;




&lt;h1&gt;
  
  
  Homework submission requirements
&lt;/h1&gt;

&lt;p&gt;Students must submit a report containing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS EKS cluster and node verification.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dev&lt;/code&gt; namespace creation.&lt;/li&gt;
&lt;li&gt;Helm monitoring installation output.&lt;/li&gt;
&lt;li&gt;Grafana PVC showing &lt;code&gt;Bound&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Grafana HTTP health result.&lt;/li&gt;
&lt;li&gt;SMTP environment variable names (no passwords).&lt;/li&gt;
&lt;li&gt;Grafana email contact point screenshot.&lt;/li&gt;
&lt;li&gt;Successful test notification screenshot.&lt;/li&gt;
&lt;li&gt;Broken Kubernetes Pod showing &lt;code&gt;ImagePullBackOff&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Prometheus query result.&lt;/li&gt;
&lt;li&gt;Grafana alert showing &lt;code&gt;Firing&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Gmail alert notification screenshot.&lt;/li&gt;
&lt;li&gt;Deployment recovery showing &lt;code&gt;Running&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Grafana dashboard persistence verification.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Student reflection questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt; Why do we use a PVC for Grafana instead of &lt;code&gt;emptyDir&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 2:&lt;/strong&gt; Why is a Kubernetes Secret better than putting an SMTP password directly into Helm values?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 3:&lt;/strong&gt; What is the difference between &lt;code&gt;ImagePullBackOff&lt;/code&gt; and &lt;code&gt;CrashLoopBackOff&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 4:&lt;/strong&gt; What does Prometheus do, and what does Grafana do?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 5:&lt;/strong&gt; Why do we configure both an alert rule and a notification policy?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 6:&lt;/strong&gt; Why can an alert be &lt;code&gt;Firing&lt;/code&gt; before an email arrives?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 7:&lt;/strong&gt; Why should monitoring alerts include namespace, Pod, and container labels?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 8:&lt;/strong&gt; What are the limitations of storing Grafana's SQLite database on a single EBS volume?&lt;/p&gt;

&lt;h3&gt;
  
  
  Final expected architecture
&lt;/h3&gt;

&lt;p&gt;Kubernetes application → kube-state-metrics → Prometheus → Grafana alert evaluation → Grafana notification policy → Gmail SMTP → Student email.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completion criteria:&lt;/strong&gt; The student must demonstrate a real Kubernetes image-pull failure, receive an alert, fix the Deployment, and verify recovery while Grafana's configuration persists across a Pod restart.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>JumpToTech DevOps School ## HOMEWORK — Production Incident Response: Kubernetes HTTP 503</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Mon, 26 Oct 2026 16:46:07 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-devops-school-homework-production-incident-response-kubernetes-http-503-238p</link>
      <guid>https://dev.to/jumptotech/jumptotech-devops-school-homework-production-incident-response-kubernetes-http-503-238p</guid>
      <description>&lt;p&gt;&lt;strong&gt;Course:&lt;/strong&gt; DevOps + AI Engineering&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Topic:&lt;/strong&gt; Kubernetes Troubleshooting, Service Networking, EndpointSlices, Incident Response&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Beginner to Intermediate&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Estimated time:&lt;/strong&gt; 60–90 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Role:&lt;/strong&gt; DevOps Engineer / Site Reliability Engineer&lt;/p&gt;


&lt;h1&gt;
  
  
  1. Production Incident Ticket
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Ticket ID:&lt;/strong&gt; INC-503-001&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Priority:&lt;/strong&gt; P2 — High&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Status:&lt;/strong&gt; OPEN&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Environment:&lt;/strong&gt; Production Simulation&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Application:&lt;/strong&gt; Restaurant Company&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Namespace:&lt;/strong&gt; &lt;code&gt;production-lab&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Service:&lt;/strong&gt; &lt;code&gt;restaurant-service&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reported by:&lt;/strong&gt; Customer Support&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Assigned to:&lt;/strong&gt; DevOps / SRE Team&lt;/p&gt;
&lt;h3&gt;
  
  
  Customer Complaint
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Our customers are unable to access the Restaurant Company application. The website is not responding correctly. Please investigate and restore service as soon as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Business Impact:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customers may be unable to access the restaurant menu, browse products, or place orders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Responsibility:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are the on-call DevOps Engineer. Your job is to investigate the incident, identify the root cause, restore application connectivity, verify the recovery, and document your findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; This lab simulates an application outage. An actual HTTP 503 response is not guaranteed by the Kubernetes Service failure alone. Different network components may return a connection error, timeout, or HTTP 503.&lt;/p&gt;


&lt;h1&gt;
  
  
  2. Learning Objectives
&lt;/h1&gt;

&lt;p&gt;By the end of this homework, you should be able to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand how Kubernetes Pods, Deployments, Services, labels, selectors, and EndpointSlices work together.&lt;/li&gt;
&lt;li&gt;Explain the difference between a healthy Pod and an accessible application.&lt;/li&gt;
&lt;li&gt;Investigate a production incident using &lt;code&gt;kubectl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Identify a Service selector mismatch.&lt;/li&gt;
&lt;li&gt;Understand why a Service can have zero endpoints while Pods are running.&lt;/li&gt;
&lt;li&gt;Restore connectivity without unnecessarily restarting healthy Pods.&lt;/li&gt;
&lt;li&gt;Verify application recovery.&lt;/li&gt;
&lt;li&gt;Prepare a professional incident report.&lt;/li&gt;
&lt;/ol&gt;


&lt;h1&gt;
  
  
  3. Architecture Overview
&lt;/h1&gt;

&lt;p&gt;Our application uses the following architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Customer / Client
                      |
                      v
              HTTP Request
                      |
                      v
           restaurant-service
              ClusterIP :80
                      |
              Service Routing
                      |
             +--------+--------+
             |                 |
             v                 v
        Restaurant Pod 1  Restaurant Pod 2
           NGINX :80        NGINX :80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kubernetes components involved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment:&lt;/strong&gt; Maintains the desired number of application replicas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pods:&lt;/strong&gt; Run the NGINX application containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service:&lt;/strong&gt; Provides a stable virtual IP and port for accessing selected backend Pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Labels:&lt;/strong&gt; Identify Kubernetes resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service Selector:&lt;/strong&gt; Determines which Pods belong to a Service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EndpointSlice Controller:&lt;/strong&gt; Maintains EndpointSlice resources that describe matching backend endpoints and their readiness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kube-proxy:&lt;/strong&gt; In clusters using kube-proxy, watches Services and EndpointSlices and configures the node's network forwarding rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CoreDNS:&lt;/strong&gt; Resolves Kubernetes Service names into IP addresses. It does not select the backend Pod or forward HTTP requests.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Phase 1 — Prepare Your Environment
&lt;/h1&gt;

&lt;p&gt;Before beginning, verify that &lt;code&gt;kubectl&lt;/code&gt; is connected to your authorized Kubernetes cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cluster-info

kubectl get nodes

kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an isolated namespace for the homework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace production-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it already exists, reuse it only if it is your own dedicated training namespace. Do not modify another student's environment.&lt;/p&gt;

&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespace production-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt; What is a Kubernetes Namespace? Why do companies separate development, staging, and production resources?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 2:&lt;/strong&gt; When a real production incident occurs, do DevOps engineers normally create a new production namespace, or investigate the existing one?&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Phase 2 — Deploy a Healthy Application
&lt;/h1&gt;

&lt;p&gt;Create a file named:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;restaurant-lab.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.27&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
              &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
            &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-service&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production-lab&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; restaurant-lab.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for the Deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/restaurant &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the Pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the EndpointSlices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslices &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-l&lt;/span&gt; kubernetes.io/service-name&lt;span class="o"&gt;=&lt;/span&gt;restaurant-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Expected Healthy State
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Two NGINX Pods are running and ready.&lt;/li&gt;
&lt;li&gt;The Service has a ClusterIP.&lt;/li&gt;
&lt;li&gt;The Service has matching backend endpoints.&lt;/li&gt;
&lt;li&gt;Requests to the application succeed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verify HTTP Access
&lt;/h3&gt;

&lt;p&gt;Use an internal Kubernetes client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run restaurant-http-test &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'HTTP Status: %{http_code}\n'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  http://restaurant-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Status: 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optional Browser Access
&lt;/h3&gt;

&lt;p&gt;If your instructor has configured an EC2 browser demonstration, you may use the instructor-provided EC2 address and port.&lt;/p&gt;

&lt;p&gt;Remember that &lt;code&gt;kubectl port-forward&lt;/code&gt; is a debugging tunnel. It is not the same as normal Service ClusterIP routing and should not be used as proof that Service endpoints are healthy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshot Required:&lt;/strong&gt; Healthy Pods, Service, EndpointSlices, and HTTP 200 verification.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Phase 3 — Production Incident Begins
&lt;/h1&gt;

&lt;p&gt;Your instructor or lab partner will introduce a controlled failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Students must not read the instructor-only fault-injection command until they have completed their investigation.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Incident Notification
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Slack — #production-incidents&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ALERT: Restaurant Company application connectivity failure.&lt;/p&gt;

&lt;p&gt;Customer Support has reported that customers cannot access the restaurant application.&lt;/p&gt;

&lt;p&gt;The Kubernetes cluster is reachable, but application connectivity is failing.&lt;/p&gt;

&lt;p&gt;Investigate immediately and provide a root-cause analysis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Your Mission
&lt;/h3&gt;

&lt;p&gt;You have been assigned this ticket.&lt;/p&gt;

&lt;p&gt;Do not immediately delete Pods, restart the Deployment, or recreate the Namespace.&lt;/p&gt;

&lt;p&gt;Begin by collecting evidence.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Phase 4 — Troubleshooting Investigation
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Task A — Check the Pods
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production-lab &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
kub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>networking</category>
      <category>sre</category>
    </item>
    <item>
      <title>WEEKEND HOMEWORK — DEVOPS FOUNDATION + KUBERNETES</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Sat, 10 Oct 2026 00:21:07 +0000</pubDate>
      <link>https://dev.to/jumptotech/weekend-homework-devops-foundation-kubernetes-5bpj</link>
      <guid>https://dev.to/jumptotech/weekend-homework-devops-foundation-kubernetes-5bpj</guid>
      <description>&lt;p&gt;This homework is &lt;strong&gt;not about memorizing definitions&lt;/strong&gt;. Your task is to prove that you understand &lt;strong&gt;where everything lives, what each component does, and how everything connects together&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your assignment
&lt;/h3&gt;

&lt;p&gt;Create a &lt;strong&gt;10–15 minute screen recording with your voice&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You may draw the architecture on paper, whiteboard, PowerPoint, Excalidraw, or on your computer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not read definitions from Google, ChatGPT, or your notes during the recording. Explain everything in your own words as if you are answering an interview question.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  TASK 1 — Build a Computer
&lt;/h2&gt;

&lt;p&gt;Draw a computer/server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COMPUTER / SERVER
┌──────────────────────────────┐
│ CPU                          │
│ RAM                          │
│ Storage / SSD                │
│ Network                      │
│ Operating System             │
└──────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CPU&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is CPU?&lt;/li&gt;
&lt;li&gt;What does CPU do?&lt;/li&gt;
&lt;li&gt;What is a CPU core?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;100m&lt;/code&gt;, &lt;code&gt;500m&lt;/code&gt;, &lt;code&gt;1000m&lt;/code&gt; mean in Kubernetes?&lt;/li&gt;
&lt;li&gt;Does CPU store files?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RAM&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is RAM?&lt;/li&gt;
&lt;li&gt;Why does an application need RAM?&lt;/li&gt;
&lt;li&gt;RAM vs Storage?&lt;/li&gt;
&lt;li&gt;What can happen when an application runs out of memory?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;OOMKilled&lt;/code&gt; mean?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is SSD/storage?&lt;/li&gt;
&lt;li&gt;What normally remains after a reboot?&lt;/li&gt;
&lt;li&gt;RAM vs persistent storage?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TASK 2 — Explain Operating System
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is an Operating System?&lt;/li&gt;
&lt;li&gt;Why does a computer need an OS?&lt;/li&gt;
&lt;li&gt;What is Linux?&lt;/li&gt;
&lt;li&gt;What does the OS manage?&lt;/li&gt;
&lt;li&gt;What is the Kernel?&lt;/li&gt;
&lt;li&gt;Application vs Process vs Service.&lt;/li&gt;
&lt;li&gt;Why do servers commonly run Linux?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You must be able to explain this relationship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hardware / Virtual Hardware
        ↓
CPU + RAM + Storage + Network
        ↓
Operating System
        ↓
Applications / Processes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 3 — Computer vs Server vs EC2
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a computer?&lt;/li&gt;
&lt;li&gt;What is a server?&lt;/li&gt;
&lt;li&gt;Is a server also a computer?&lt;/li&gt;
&lt;li&gt;What makes a computer act as a server?&lt;/li&gt;
&lt;li&gt;What is AWS EC2?&lt;/li&gt;
&lt;li&gt;Is EC2 an Operating System?&lt;/li&gt;
&lt;li&gt;Where does Linux run when we create an Ubuntu EC2 instance?&lt;/li&gt;
&lt;li&gt;Where are CPU and RAM in this architecture?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS
 ↓
EC2 Instance
 ↓
CPU + RAM + Storage + Network
 ↓
Linux OS
 ↓
Applications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 4 — Networking
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is an IP address?&lt;/li&gt;
&lt;li&gt;What is a Private IP?&lt;/li&gt;
&lt;li&gt;What is a Public IP?&lt;/li&gt;
&lt;li&gt;Private IP vs Public IP.&lt;/li&gt;
&lt;li&gt;What is a Port?&lt;/li&gt;
&lt;li&gt;What are ports &lt;code&gt;22&lt;/code&gt;, &lt;code&gt;80&lt;/code&gt;, and &lt;code&gt;443&lt;/code&gt; commonly used for?&lt;/li&gt;
&lt;li&gt;What is an AWS Security Group?&lt;/li&gt;
&lt;li&gt;Why can an application be running but still not open in your browser?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explain this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Laptop
     ↓
Internet
     ↓
Public endpoint / Public IP
     ↓
Security Group
     ↓
Port
     ↓
Server
     ↓
Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 5 — Image vs Container
&lt;/h2&gt;

&lt;p&gt;This section is very important.&lt;/p&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a Docker Image?&lt;/li&gt;
&lt;li&gt;What is a Container?&lt;/li&gt;
&lt;li&gt;Image vs Container.&lt;/li&gt;
&lt;li&gt;Is an Image a running application?&lt;/li&gt;
&lt;li&gt;Can we create multiple Containers from the same Image?&lt;/li&gt;
&lt;li&gt;What is a Container Runtime?&lt;/li&gt;
&lt;li&gt;What is Docker/containerd doing?&lt;/li&gt;
&lt;li&gt;Where does an Image come from?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Container Registry
ECR / Docker Hub
        ↓
      Image
        ↓
Container Runtime
        ↓
     Container
        ↓
   Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Nginx as your example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx:1.27 Image
       ↓
Container Runtime
       ↓
Nginx Container
       ↓
Nginx Process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; say that the Image itself is running.&lt;/p&gt;




&lt;h2&gt;
  
  
  TASK 6 — Connect This to Kubernetes
&lt;/h2&gt;

&lt;p&gt;Now extend your architecture.&lt;/p&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Kubernetes?&lt;/li&gt;
&lt;li&gt;What is EKS?&lt;/li&gt;
&lt;li&gt;What is a Cluster?&lt;/li&gt;
&lt;li&gt;What is a Control Plane?&lt;/li&gt;
&lt;li&gt;What is a Worker Node?&lt;/li&gt;
&lt;li&gt;What is a Pod?&lt;/li&gt;
&lt;li&gt;Container vs Pod.&lt;/li&gt;
&lt;li&gt;Worker Node vs Pod.&lt;/li&gt;
&lt;li&gt;Where does the Container run?&lt;/li&gt;
&lt;li&gt;Where does the Pod run?&lt;/li&gt;
&lt;li&gt;Where are CPU and RAM?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EKS CLUSTER

Control Plane
      ↓
Scheduler
      ↓

WORKER NODE / EC2
┌─────────────────────────────┐
│ CPU                         │
│ RAM                         │
│ Storage                     │
│ Network                     │
│ Linux OS                    │
│                             │
│   Pod                       │
│   ┌─────────────────────┐   │
│   │ Container           │   │
│   │                     │   │
│   │ Nginx Application   │   │
│   └─────────────────────┘   │
└─────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You must clearly explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Worker Node is the server. Pod runs on the Worker Node. Container runs inside the Pod. Application runs inside the Container.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  TASK 7 — Explain How Kubernetes Uses an Image
&lt;/h2&gt;

&lt;p&gt;Explain what happens when Kubernetes sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.27&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain the complete process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment / Pod specification
          ↓
image: nginx:1.27
          ↓
Scheduler chooses Worker Node
          ↓
Container Runtime on Node
          ↓
Obtains Image if necessary
          ↓
Creates Container
          ↓
Nginx starts running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain the difference between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image → Container → Pod → Worker Node&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  TASK 8 — Deployment and ReplicaSet
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a Deployment?&lt;/li&gt;
&lt;li&gt;What is a ReplicaSet?&lt;/li&gt;
&lt;li&gt;What are replicas?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;replicas: 3&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What is desired state?&lt;/li&gt;
&lt;li&gt;What happens if you delete one Deployment-managed Pod?&lt;/li&gt;
&lt;li&gt;Who recreates it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment
    ↓
ReplicaSet
    ↓
┌─────┬─────┬─────┐
Pod   Pod   Pod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desired = 3
Actual = 2
     ↓
Controller reconciliation
     ↓
New Pod
     ↓
Actual = 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 9 — Service
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why shouldn't users connect directly to changing Pod IP addresses?&lt;/li&gt;
&lt;li&gt;What is a Kubernetes Service?&lt;/li&gt;
&lt;li&gt;What is ClusterIP?&lt;/li&gt;
&lt;li&gt;What is LoadBalancer?&lt;/li&gt;
&lt;li&gt;What are Labels?&lt;/li&gt;
&lt;li&gt;What is a Selector?&lt;/li&gt;
&lt;li&gt;What are Endpoints?&lt;/li&gt;
&lt;li&gt;How does a Service know which Pods belong to it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
  ↓
AWS Load Balancer
  ↓
Kubernetes Service
  ↓
selector: app=nginx
  ↓
┌─────┬─────┬─────┐
Pod   Pod   Pod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain what happens if:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service selector = app: nginx

Pod label = app: restaurant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 10 — ConfigMap and Secret
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is ConfigMap?&lt;/li&gt;
&lt;li&gt;What should we store in ConfigMap?&lt;/li&gt;
&lt;li&gt;What is Secret?&lt;/li&gt;
&lt;li&gt;ConfigMap vs Secret.&lt;/li&gt;
&lt;li&gt;Why shouldn't passwords be hard-coded into application code or normal configuration?&lt;/li&gt;
&lt;li&gt;How can a Pod receive a value from ConfigMap or Secret?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ConfigMap ──────┐
                ↓
               Pod
                ↑
Secret ─────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 11 — Resources
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;

  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is &lt;code&gt;requests&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;limits&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Why does Scheduler care about requests?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;100m CPU&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;500m CPU&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What can happen when CPU reaches its limit?&lt;/li&gt;
&lt;li&gt;What can happen when Memory exceeds its limit?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Calculate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6 Pods
Each requests 100m CPU

Total CPU request = ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6 Pods
Each requests 128Mi Memory

Total Memory request = ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TASK 12 — Readiness and Liveness
&lt;/h2&gt;

&lt;p&gt;Explain the difference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness
"Should Kubernetes send traffic to this Pod?"

Liveness
"Is this workload healthy enough to keep running?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can a Pod be &lt;code&gt;Running&lt;/code&gt; but &lt;code&gt;0/1 Ready&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What happens when Readiness fails?&lt;/li&gt;
&lt;li&gt;What can happen after repeated Liveness failures?&lt;/li&gt;
&lt;li&gt;Why do we need both?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TASK 13 — HPA
&lt;/h2&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is HPA?&lt;/li&gt;
&lt;li&gt;What does Horizontal scaling mean?&lt;/li&gt;
&lt;li&gt;What is Metrics Server?&lt;/li&gt;
&lt;li&gt;Where does HPA get CPU metrics?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;minReplicas&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;maxReplicas&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;averageUtilization: 50&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;Why is &lt;code&gt;requests.cpu&lt;/code&gt; important for CPU-utilization HPA?&lt;/li&gt;
&lt;li&gt;Does HPA directly create Pods?&lt;/li&gt;
&lt;li&gt;Does HPA create Worker Nodes?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Draw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users / Traffic ↑
       ↓
Service
       ↓
Pods
       ↓
CPU utilization ↑
       ↓
kubelet
       ↓
Metrics Server
       ↓
HPA
       ↓
Desired replicas ↑
       ↓
Deployment / ReplicaSet
       ↓
More Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  TASK 14 — FULL ARCHITECTURE
&lt;/h1&gt;

&lt;p&gt;This is the &lt;strong&gt;most important part of the homework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Without notes, draw one complete architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USER
 ↓
Browser
 ↓
DNS
 ↓
Public Endpoint / Load Balancer
 ↓
AWS Networking / Security
 ↓
Kubernetes Service
 ↓
Pod
 ↓
Container
 ↓
Nginx Application
 ↓
CPU + RAM


                 EKS CLUSTER

              Control Plane
                    ↓
                 Scheduler
                    ↓

              WORKER NODE
        ┌──────────────────────┐
        │ EC2 Server           │
        │                      │
        │ CPU                  │
        │ RAM                  │
        │ Storage              │
        │ Network              │
        │ Linux OS             │
        │                      │
        │ Pod                  │
        │  └─ Container        │
        │      └─ Nginx        │
        └──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then explain the &lt;strong&gt;entire journey of one user request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example scenario:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A customer opens the Restaurant Company website.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start with the customer and continue until Nginx returns the response.&lt;/p&gt;

&lt;p&gt;Do not skip CPU, RAM, OS, Server, Network, Service, Pod or Container.&lt;/p&gt;




&lt;h1&gt;
  
  
  TASK 15 — TROUBLESHOOTING INTERVIEW
&lt;/h1&gt;

&lt;p&gt;Imagine the interviewer tells you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Our website is down. How would you troubleshoot it?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do NOT answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I will restart the Pod.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You don't know the root cause yet.&lt;/p&gt;

&lt;p&gt;Explain your investigation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is Worker Node healthy?
        ↓
Are Pods Running?
        ↓
Are Pods Ready?
        ↓
What do Pod Events say?
        ↓
What do application logs say?
        ↓
Is Service correct?
        ↓
Does Service have Endpoints?
        ↓
Do Labels match Selectors?
        ↓
Are Probes passing?
        ↓
Are ConfigMap/Secret correct?
        ↓
Are Resources sufficient?
        ↓
Is Load Balancer working?
        ↓
Networking / Security Group / Ports?
        ↓
DNS?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mention commands you would use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
kubectl get pods
kubectl describe pod &amp;lt;POD&amp;gt;
kubectl logs &amp;lt;POD&amp;gt;
kubectl get svc
kubectl get endpoints
kubectl get pods &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
kubectl top nodes
kubectl top pods
kubectl get hpa
kubectl describe hpa &amp;lt;HPA&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  FINAL SUBMISSION
&lt;/h1&gt;

&lt;p&gt;Submit &lt;strong&gt;one 10–15 minute video recording&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your video must include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Draw and explain &lt;strong&gt;CPU, RAM, Storage, OS and Server&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Private IP vs Public IP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Image vs Container&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Container vs Pod&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Worker Node vs Pod&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Deployment → ReplicaSet → Pods&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Service → Labels → Selectors → Endpoints&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;ConfigMap and Secret&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Requests and Limits&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Readiness and Liveness&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;Metrics Server and HPA&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Draw the &lt;strong&gt;complete architecture from User → Application&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Explain &lt;strong&gt;one troubleshooting scenario&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Important rules
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Do not read from notes. Do not just show commands. Do not memorize sentences without understanding them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For every component, answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is it?&lt;br&gt;
Where does it live?&lt;br&gt;
What does it do?&lt;br&gt;
Why do we need it?&lt;br&gt;
What happens if it fails?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is that on Monday, if an interviewer asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Explain how your application runs in Kubernetes.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you can draw the architecture and explain the complete system confidently from &lt;strong&gt;CPU and Operating System all the way to Kubernetes and HPA&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>learning</category>
    </item>
    <item>
      <title>FINAL KUBERNETES PRODUCTION CAPSTONE Dev Staging Production | Helm | Argo CD | Security | Storage | 10 Production Incidents</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Sat, 10 Oct 2026 00:15:08 +0000</pubDate>
      <link>https://dev.to/jumptotech/final-kubernetes-production-capstone-dev-staging-production-helm-argo-cd-security--745</link>
      <guid>https://dev.to/jumptotech/final-kubernetes-production-capstone-dev-staging-production-helm-argo-cd-security--745</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“I built and operated a production-style Kubernetes platform with separate dev, staging, and production environments. I deployed applications with Helm, implemented GitOps with Argo CD, configured resources, probes, autoscaling, availability, RBAC, networking, persistent storage, and practiced production incident response.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Your role
&lt;/h3&gt;

&lt;p&gt;You have joined a financial company as a DevOps Engineer.&lt;/p&gt;

&lt;p&gt;The company is building an online banking platform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers
    ↓
Banking Application
    │
    ├── frontend
    ├── account-service
    ├── payment-service
    └── transaction-service
             ↓
          Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The company wants Kubernetes environments built using production practices.&lt;/p&gt;

&lt;p&gt;You are responsible for designing, deploying, securing, operating, troubleshooting, and explaining the platform.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;not a copy/paste homework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every student must &lt;strong&gt;record a video showing the environment and explaining every major decision&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 1 — Architecture Design
&lt;/h1&gt;

&lt;p&gt;Before creating anything, draw your architecture.&lt;/p&gt;

&lt;p&gt;Your recording must explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         INTERNET
                            │
                            ▼
                    Load Balancer / ALB
                            │
                            ▼
                         Ingress
                            │
                 ┌──────────┼──────────┐
                 ▼          ▼          ▼
             frontend    account    payment
                            │          │
                            └────┬─────┘
                                 ▼
                             Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then explain the Kubernetes architecture underneath:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    KUBERNETES / EKS
                           │
              ┌────────────┴────────────┐
              │                         │
        CONTROL PLANE              WORKER NODES
              │                         │
        API Server                     kubelet
        Scheduler                      runtime
        Controllers                    CNI
        etcd                           kube-proxy
                                        │
                                       Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your recording explain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens from &lt;code&gt;kubectl apply&lt;/code&gt; until the container is actually running?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should be able to explain approximately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl
   ↓
API Server
   ↓
desired state stored
   ↓
Controllers
   ↓
Scheduler
   ↓
Worker Node selected
   ↓
kubelet
   ↓
CRI
   ↓
container runtime
   ↓
Container starts
   ↓
CNI networking
   ↓
Readiness
   ↓
Service can route traffic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not just read component definitions.&lt;/p&gt;

&lt;p&gt;Explain the process.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 2 — Build Three Environments
&lt;/h1&gt;

&lt;p&gt;The company requires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEV
STAGING
PRODUCTION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this homework, you can implement them as namespaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But explain an important production point
&lt;/h3&gt;

&lt;p&gt;In your recording answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Would a bank necessarily run dev, staging and production merely as three namespaces in one cluster?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected explanation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not necessarily.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For stronger isolation, especially in regulated/security-sensitive organizations, production may use separate clusters and often separate AWS accounts/VPC boundaries.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Organization
│
├── Development Account
│      └── Dev EKS
│
├── Staging / Pre-Prod Account
│      └── Staging EKS
│
└── Production Account
       └── Production EKS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Namespaces are acceptable for our training environment because creating several full EKS environments costs additional money and operational effort.&lt;/p&gt;

&lt;p&gt;But students must understand the difference between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lab architecture&lt;/strong&gt; and &lt;strong&gt;real production architecture&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 3 — Build the Application
&lt;/h1&gt;

&lt;p&gt;Create a Deployment for the application.&lt;/p&gt;

&lt;p&gt;Requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application: banking-app
Production replicas: 3
Container: nginx or your own application
Container port: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Deployment must include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a production rolling strategy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RollingUpdate&lt;/span&gt;
  &lt;span class="na"&gt;rollingUpdate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;maxUnavailable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="na"&gt;maxSurge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must decide appropriate values and explain them.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 4 — Explain Requests and Limits
&lt;/h1&gt;

&lt;p&gt;In the recording answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we use requests?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we use limits?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when memory exceeds its limit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can happen when CPU reaches/exceeds its limit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why should we not blindly give every Pod huge requests?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requests
   ↓
Scheduling / reserved expectation

Limits
   ↓
Maximum resource boundary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also explain why bad resource configuration can create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pending Pods
CPU throttling
OOMKilled
Wasted cluster capacity
Higher AWS cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  PART 5 — Probes
&lt;/h1&gt;

&lt;p&gt;Implement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Startup Probe (optional if appropriate)
Readiness Probe
Liveness Probe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness:
Should this Pod receive traffic?

Liveness:
Should Kubernetes restart the container?

Startup:
Has this slow-starting application successfully started?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Demonstrate what happens when readiness fails.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 6 — Service
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClusterIP Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why shouldn't another application communicate directly with a Pod IP?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service
   ↓
Selector
   ↓
Pod labels
   ↓
EndpointSlices
   ↓
Ready Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl get endpointslice &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  PART 7 — Ingress
&lt;/h1&gt;

&lt;p&gt;Create an Ingress for the application.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
   ↓
DNS
   ↓
Load Balancer
   ↓
Ingress Controller
   ↓
Ingress Rules
   ↓
Service
   ↓
Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your recording explain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ingress vs Ingress Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ingress vs Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where HTTPS/TLS could terminate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How traffic reaches the application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For AWS/EKS, explain how an AWS load-balancing solution can integrate with Kubernetes rather than claiming the Ingress resource itself magically creates everything.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 8 — ConfigMap and Secret
&lt;/h1&gt;

&lt;p&gt;Create a ConfigMap containing something such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_ENV=production
LOG_LEVEL=info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a Secret containing a dummy training credential.&lt;/p&gt;

&lt;p&gt;Application must consume configuration through environment variables or mounted files.&lt;/p&gt;

&lt;p&gt;Explain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConfigMap vs Secret&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is base64 encryption?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Correct answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the banking scenario, discuss why real secrets should be managed carefully and why cloud secret-management/encryption solutions may be integrated rather than committing credentials to Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never commit real secrets to the repository.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 9 — RBAC / Least Privilege
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ServiceAccount
Role
RoleBinding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;developer&lt;/code&gt; ServiceAccount.&lt;/p&gt;

&lt;p&gt;It should be allowed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get Pods
list Pods
watch Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should &lt;strong&gt;not&lt;/strong&gt; be allowed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete Pods
delete Deployments
delete Secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl auth can-i list pods &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system:serviceaccount:production:developer &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl auth can-i delete pods &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system:serviceaccount:production:developer &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
=
Who are you?

Authorization
=
What are you allowed to do?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then explain why least privilege is especially important for a banking application.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 10 — NetworkPolicy
&lt;/h1&gt;

&lt;p&gt;Create a production NetworkPolicy.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend
   │
   ▼
payment-service
   │
   ▼
database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allowed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend → payment ✓
payment → database ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not allowed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend → database ✗
random Pod → database ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must explain why RBAC cannot solve this problem.&lt;/p&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RBAC
→ Kubernetes API authorization

NetworkPolicy
→ workload network communication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also explain that NetworkPolicy requires a network implementation that enforces it.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 11 — HPA
&lt;/h1&gt;

&lt;p&gt;Configure HPA.&lt;/p&gt;

&lt;p&gt;Example requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minimum replicas: 3
maximum replicas: 10
CPU target: 60%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl describe hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens when traffic increases?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens if HPA reaches &lt;code&gt;maxReplicas&lt;/code&gt; but traffic continues increasing?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What does CPU-based HPA need?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Metrics and appropriate resource requests.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 12 — PDB
&lt;/h1&gt;

&lt;p&gt;Create a PodDisruptionBudget.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3 replicas

minAvailable: 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain why this matters during voluntary disruption such as node maintenance.&lt;/p&gt;

&lt;p&gt;Also explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does PDB protect against every failure?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 13 — Scheduling
&lt;/h1&gt;

&lt;p&gt;Demonstrate or explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nodeSelector
node affinity
pod anti-affinity
taints
tolerations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production, explain why we might avoid placing every replica on the same node.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node 1
├── payment-1
├── payment-2
└── payment-3

Node 1 fails
→ payment completely unavailable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node 1 → payment-1
Node 2 → payment-2
Node 3 → payment-3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Discuss topology/AZ resilience where appropriate.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 14 — StatefulSet + Persistent Storage
&lt;/h1&gt;

&lt;p&gt;Create a StatefulSet.&lt;/p&gt;

&lt;p&gt;It must demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stable Pod identity
PVC
StorageClass
PV
Persistent data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get statefulset
kubectl get pvc
kubectl get pv
kubectl get storageclass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write data.&lt;/p&gt;

&lt;p&gt;Delete the Pod.&lt;/p&gt;

&lt;p&gt;Allow StatefulSet to recreate it.&lt;/p&gt;

&lt;p&gt;Prove the data still exists.&lt;/p&gt;

&lt;p&gt;Then explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stable identity and persistent storage are related but different concepts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  PART 15 — AWS EBS CSI
&lt;/h1&gt;

&lt;p&gt;Explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;StatefulSet
    ↓
PVC
    ↓
StorageClass
    ↓
EBS CSI Driver
    ↓
AWS EBS
    ↓
PV
    ↓
PVC Bound
    ↓
Pod Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must explain the storage incident we previously encountered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PVC Pending
↓
StorageClass existed
↓
ebs.csi.aws.com expected
↓
EBS CSI add-on/components missing
↓
No dynamic EBS volume
↓
Pod Pending
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And how to investigate it.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 16 — Helm
&lt;/h1&gt;

&lt;p&gt;Convert the application into a Helm chart.&lt;/p&gt;

&lt;p&gt;Suggested structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;banking-app/
│
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-staging.yaml
├── values-prod.yaml
│
└── templates/
    ├── deployment.yaml
    ├── service.yaml
    ├── ingress.yaml
    ├── configmap.yaml
    ├── serviceaccount.yaml
    ├── hpa.yaml
    ├── pdb.yaml
    └── networkpolicy.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different environment values should demonstrate meaningful differences.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEV
replicas: 1
smaller resources

STAGING
replicas: 2
production-like configuration

PRODUCTION
replicas: 3+
HPA
PDB
stronger availability settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm lint
helm template
helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt;
helm list
helm &lt;span class="nb"&gt;history&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain why Helm is useful in a company with many applications and environments.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 17 — Argo CD / GitOps
&lt;/h1&gt;

&lt;p&gt;Put Kubernetes/Helm configuration in Git.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
   ↓
Pull Request
   ↓
Review
   ↓
Merge
   ↓
Git
   ↓
Argo CD
   ↓
EKS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must create/configure an Argo CD Application and demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Synced
Healthy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then manually modify something in Kubernetes.&lt;/p&gt;

&lt;p&gt;Observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OutOfSync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain drift.&lt;/p&gt;

&lt;p&gt;Then restore/reconcile through GitOps.&lt;/p&gt;

&lt;p&gt;Critical production question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If Argo CD manages production, should engineers routinely modify production using &lt;code&gt;kubectl edit&lt;/code&gt;?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;Generally no. Desired changes should normally go through the controlled Git/change process, with emergency procedures handled according to company policy.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 18 — Banking Production Requirements
&lt;/h1&gt;

&lt;p&gt;This section is mandatory in the recording.&lt;/p&gt;

&lt;p&gt;Imagine this is a &lt;strong&gt;banking system handling financial transactions and sensitive data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before saying “production ready,” discuss:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;High availability
Least privilege
Encryption
Secret management
Network segmentation
Auditability
Backups
Disaster recovery
Monitoring
Alerting
Logging
Change control
Image scanning
Vulnerability management
Patch management
Capacity planning
Rollback strategy
Business continuity
Compliance requirements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; simply say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We have three replicas, therefore the bank is production-ready.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Production readiness is much larger than Kubernetes manifests.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 19 — What Costs Money in AWS?
&lt;/h1&gt;

&lt;p&gt;Students must be able to answer this because engineers should understand cost.&lt;/p&gt;

&lt;p&gt;Discuss potential charges for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EKS cluster/control-plane service
EC2 worker nodes
EBS volumes/snapshots
Load balancers
NAT Gateway
Data transfer
CloudWatch logs/metrics
ECR storage/data transfer
Public IPv4 where applicable
Route 53
Backup/storage services
Other managed AWS services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not memorize exact prices because pricing changes.&lt;/p&gt;

&lt;p&gt;Instead explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which architectural decisions create cost?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More nodes → more compute cost

More/larger EBS → more storage cost

Multiple ALBs → load-balancer cost

Large log ingestion → observability cost

NAT traffic → networking cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  PART 20 — Production Monitoring
&lt;/h1&gt;

&lt;p&gt;Your application must have an observability plan.&lt;/p&gt;

&lt;p&gt;Explain what you would monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU
Memory
Pod restarts
Ready replicas
Node health
Request rate
Error rate
Latency
HTTP 5xx
HPA behavior
PVC/storage
Database health
Dependency health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Metrics
Logs
Traces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A strong student should mention service-level signals such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic
Errors
Latency
Saturation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;not only Kubernetes CPU.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 21 — TEN REQUIRED PRODUCTION INCIDENTS
&lt;/h1&gt;

&lt;p&gt;This is the most important part of the homework.&lt;/p&gt;

&lt;p&gt;Each student must &lt;strong&gt;break the environment intentionally, investigate it without jumping directly to the answer, fix/mitigate it, and verify recovery on video.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Incident 1 — Bad Deployment / ImagePullBackOff
&lt;/h2&gt;

&lt;p&gt;Break:&lt;/p&gt;

&lt;p&gt;Deploy an invalid/nonexistent image tag.&lt;/p&gt;

&lt;p&gt;Student must discover:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New rollout
↓
New Pods unhealthy
↓
ImagePullBackOff
↓
describe Pod
↓
Events
↓
Image cannot be pulled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mitigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/&amp;lt;name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl rollout undo deployment/&amp;lt;name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
kubectl rollout status deployment/&amp;lt;name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interview explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A new release introduced an invalid image reference. I correlated the incident with the rollout, confirmed the image pull failure from Pod events, rolled back to the known-good revision, and verified service recovery.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Incident 2 — Production Slow / HPA at Maximum
&lt;/h2&gt;

&lt;p&gt;Generate load.&lt;/p&gt;

&lt;p&gt;Students investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application slow
↓
Pods Running
↓
CPU/resource pressure
↓
HPA target exceeded
↓
maxReplicas reached
↓
capacity insufficient for current load
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They must not say “traffic” without evidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 3 — Service Selector Mismatch
&lt;/h2&gt;

&lt;p&gt;Break Service selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service:
app=wrong-app

Pods:
app=banking-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Symptoms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pods 1/1 Running
Service exists
Application unreachable
No expected Service backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Student must compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe svc
kubectl get pods &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
kubectl get endpointslice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Incident 4 — Readiness Probe Failure
&lt;/h2&gt;

&lt;p&gt;Break:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/does-not-exist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Running 0/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Student must explain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Running ≠ Ready.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use &lt;code&gt;describe&lt;/code&gt; to find probe failure.&lt;/p&gt;

&lt;p&gt;Fix/rollback and verify readiness and Service routing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 5 — OOMKilled
&lt;/h2&gt;

&lt;p&gt;Configure a workload with insufficient memory or a controlled memory-hungry training application.&lt;/p&gt;

&lt;p&gt;Student must find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RESTARTS ↑
↓
CrashLoopBackOff
↓
describe
↓
Last State
↓
OOMKilled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &amp;lt;pod&amp;gt; &lt;span class="nt"&gt;--previous&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explain why simply increasing memory may only be mitigation if the application has unbounded memory growth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 6 — Dependency Failure
&lt;/h2&gt;

&lt;p&gt;Application logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cannot connect to database/Kafka
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Student is &lt;strong&gt;not allowed to say&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Kafka is down.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;until proven.&lt;/p&gt;

&lt;p&gt;Investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS
Service
EndpointSlice
Port
NetworkPolicy
Authentication
Dependency health
Application configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interview statement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The log proves the application cannot connect to the dependency; it does not by itself prove the dependency is down.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Incident 7 — PVC Pending
&lt;/h2&gt;

&lt;p&gt;Break storage provisioning.&lt;/p&gt;

&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod Pending
↓
PVC Pending
↓
Events
↓
StorageClass
↓
CSI
↓
Cloud permissions/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students must walk the entire storage dependency chain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 8 — RBAC Forbidden
&lt;/h2&gt;

&lt;p&gt;Make a ServiceAccount attempt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Student investigates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl auth can-i ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then Role/RoleBinding.&lt;/p&gt;

&lt;p&gt;They must explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication succeeded
but
Authorization denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;Forbidden&lt;/code&gt; response is different from a network failure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 9 — NetworkPolicy Blocks Traffic
&lt;/h2&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend → payment ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because NetworkPolicy blocks the connection.&lt;/p&gt;

&lt;p&gt;Students must prove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pods Running
Service exists
Endpoints exist
DNS may work
BUT network connection blocked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inspect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get networkpolicy
kubectl describe networkpolicy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They must explain why restarting the application doesn't fix the policy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Incident 10 — Argo CD OutOfSync / Configuration Drift
&lt;/h2&gt;

&lt;p&gt;Git says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replicas: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manually change live cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl scale deployment banking-app &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--replicas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe Argo CD.&lt;/p&gt;

&lt;p&gt;Students explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git desired state
      ≠
Live state

→ OutOfSync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restore desired state through the GitOps workflow/reconciliation.&lt;/p&gt;

&lt;p&gt;Explain why uncontrolled manual production changes are dangerous.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 22 — For Every Incident, Use the Same Professional Method
&lt;/h1&gt;

&lt;p&gt;Students may &lt;strong&gt;not&lt;/strong&gt; begin with random commands.&lt;/p&gt;

&lt;p&gt;Every recording must follow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. ALERT / TICKET

2. CUSTOMER IMPACT
   What is broken?

3. SCOPE
   Which application/service/environment?

4. WHAT CHANGED?
   Deployment?
   Config?
   Traffic?
   Infrastructure?

5. OBSERVE
   Metrics
   Logs
   Events
   Traces

6. HYPOTHESIS
   What might explain the evidence?

7. PROVE / DISPROVE
   Collect evidence.

8. ROOT CAUSE
   What actually caused the problem?

9. MITIGATION / FIX
   Restore service safely.

10. VERIFY
    Prove service is healthy.

11. RCA
    Why did this happen?
    How do we prevent recurrence?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sentence I want every student to learn is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“I don't want to guess the root cause. I form a hypothesis and validate it with evidence.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  PART 23 — Production Verification
&lt;/h1&gt;

&lt;p&gt;After every fix, students must prove recovery.&lt;/p&gt;

&lt;p&gt;They cannot say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The command succeeded, so production is fixed.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They must check the relevant layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment healthy
       ↓
Pods Ready
       ↓
Restart count stable
       ↓
Service backend healthy
       ↓
Application responds
       ↓
Errors normal
       ↓
Latency normal
       ↓
Critical customer flow works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  PART 24 — Git Repository Requirements
&lt;/h1&gt;

&lt;p&gt;Repository should look professional.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;banking-platform/
│
├── README.md
│
├── docs/
│   ├── architecture.md
│   ├── troubleshooting.md
│   └── incidents.md
│
├── helm/
│   └── banking-app/
│       ├── Chart.yaml
│       ├── values.yaml
│       ├── values-dev.yaml
│       ├── values-staging.yaml
│       ├── values-prod.yaml
│       └── templates/
│
├── argocd/
│   ├── dev.yaml
│   ├── staging.yaml
│   └── production.yaml
│
└── kubernetes/
    ├── rbac/
    ├── network-policy/
    ├── storage/
    └── troubleshooting/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;README should explain architecture, environments, deployment process, security controls, availability, scaling, storage, GitOps and troubleshooting.&lt;/p&gt;




&lt;h1&gt;
  
  
  PART 25 — Required Video Recording
&lt;/h1&gt;

&lt;p&gt;I would require approximately &lt;strong&gt;45–60 minutes&lt;/strong&gt;, but quality matters more than exact duration.&lt;/p&gt;

&lt;p&gt;Tell students:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do not read definitions from Google or from your notes. Share your screen and explain your own environment as though I am the interviewer.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The recording must show and explain the full lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Architecture
    ↓
AWS / EKS
    ↓
Dev / Staging / Production
    ↓
Docker Image / ECR
    ↓
Deployment / ReplicaSet / Pods
    ↓
Resources / Probes
    ↓
Service / EndpointSlice
    ↓
Ingress
    ↓
ConfigMap / Secret
    ↓
RBAC
    ↓
NetworkPolicy
    ↓
HPA / PDB
    ↓
Scheduling
    ↓
StatefulSet / PV / PVC / StorageClass / CSI
    ↓
Helm
    ↓
Argo CD / GitOps
    ↓
Observability
    ↓
10 Production Incidents
    ↓
RCA / Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At random points in the recording they should be able to answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did you configure it this way?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is more important than merely showing YAML.&lt;/p&gt;




</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>JumpToTech — Weekend Kubernetes Production Lab</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Sat, 10 Oct 2026 00:02:17 +0000</pubDate>
      <link>https://dev.to/jumptotech/jumptotech-weekend-kubernetes-production-lab-13mc</link>
      <guid>https://dev.to/jumptotech/jumptotech-weekend-kubernetes-production-lab-13mc</guid>
      <description>&lt;h2&gt;
  
  
  Restaurant Company: Deploy, Configure, Scale &amp;amp; Troubleshoot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Goal
&lt;/h3&gt;

&lt;p&gt;You are the DevOps Engineer responsible for deploying the Restaurant Company application into Kubernetes.&lt;/p&gt;

&lt;p&gt;By the end of this lab, you should be able to explain and demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EKS Cluster
    ↓
Worker Node
    ↓
Deployment
    ↓
ReplicaSet
    ↓
Pods
    ↓
Service
    ↓
Application

ConfigMap + Secret
        ↓
       Pods

Resources
CPU + Memory
        ↓
       Pods

Metrics Server
        ↓
       HPA
        ↓
Deployment replicas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not simply copy commands. After every section, understand &lt;strong&gt;what Kubernetes created and why&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 1 — Verify Your Kubernetes Environment
&lt;/h1&gt;

&lt;p&gt;Before creating anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Worker Node should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STATUS
Ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe node &amp;lt;NODE-NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Capacity:
  cpu:
  memory:
  pods:

Allocatable:
  cpu:
  memory:
  pods:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Questions
&lt;/h3&gt;

&lt;p&gt;Students must answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is a Worker Node?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;Capacity&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;Allocatable&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Why can Allocatable be smaller than Capacity?&lt;/li&gt;
&lt;li&gt;How many Pods can your Node run?&lt;/li&gt;
&lt;li&gt;Is Pod capacity the same thing as CPU capacity?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;1930m&lt;/code&gt; CPU mean if you see it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1000m = 1 CPU core
500m  = 0.5 CPU
100m  = 0.1 CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 2 — Create Your Working Directory
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/weekend-k8s-lab
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/weekend-k8s-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;weekend-k8s-lab/
├── configmap.yaml
├── secret.yaml
├── deployment.yaml
├── service.yaml
└── hpa.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 3 — ConfigMap
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano configmap.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ConfigMap&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-config&lt;/span&gt;
&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;APP_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production"&lt;/span&gt;
  &lt;span class="na"&gt;APP_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;restaurant-company"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; configmap.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get configmap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe configmap restaurant-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understand
&lt;/h3&gt;

&lt;p&gt;A ConfigMap stores &lt;strong&gt;non-sensitive configuration&lt;/strong&gt; separately from the application image.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_ENV
APP_NAME
LOG_LEVEL
API_URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interview Question
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why shouldn't configuration always be hard-coded into the Docker image?&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 4 — Secret
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano secret.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this classroom lab only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secret&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-secret&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Opaque&lt;/span&gt;
&lt;span class="na"&gt;stringData&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JumpToTech123"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; secret.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe secret restaurant-secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data
====
DB_PASSWORD:  13 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important
&lt;/h3&gt;

&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; commit real production passwords to GitHub.&lt;/p&gt;

&lt;p&gt;Also remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubernetes Secret is not automatically "safe because it is a Secret." Base64 encoding is not encryption.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Part 5 — Deployment
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-deployment&lt;/span&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;

  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;

    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.27&lt;/span&gt;

          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;APP_ENV&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;configMapKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-config&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;APP_ENV&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;APP_NAME&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;configMapKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-config&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;APP_NAME&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restaurant-secret&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;

          &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;

            &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
              &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;

          &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
              &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
            &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

          &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
              &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
            &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
            &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students should understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment
     ↓
ReplicaSet
     ↓
Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 6 — Prove Self-Healing
&lt;/h1&gt;

&lt;p&gt;Get Pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete ONE Deployment-managed Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod &amp;lt;POD-NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Observe
&lt;/h3&gt;

&lt;p&gt;You deleted one Pod.&lt;/p&gt;

&lt;p&gt;But the desired state says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desired = 2
Actual  = 1

ReplicaSet
    ↓
creates replacement
    ↓
Actual = 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interview Question
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why did Kubernetes recreate the Pod?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Because Kubernetes always recreates Pods."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Correct idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Pod is managed by a ReplicaSet created by the Deployment, and the controller reconciles actual state with desired state.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Part 7 — Verify ConfigMap and Secret Injection
&lt;/h1&gt;

&lt;p&gt;Find a Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check ConfigMap values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;POD-NAME&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;printenv &lt;/span&gt;APP_ENV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;POD-NAME&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;printenv &lt;/span&gt;APP_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;restaurant-company
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this classroom lab only, verify that the Secret variable exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;POD-NAME&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;printenv &lt;/span&gt;DB_PASSWORD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not expose production secrets this way.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 8 — Understand Resources
&lt;/h1&gt;

&lt;p&gt;Your Deployment contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;

  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Requests
&lt;/h3&gt;

&lt;p&gt;Requests are especially important to &lt;strong&gt;scheduling&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Pod
   ↓
CPU request = 100m
Memory request = 128Mi
   ↓
Scheduler
   ↓
Find suitable Node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Limits
&lt;/h3&gt;

&lt;p&gt;Limits constrain resource usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU limit exceeded
→ CPU may be throttled

Memory limit exceeded
→ Container may be terminated / OOMKilled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;POD-NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requests:
  cpu:     100m
  memory:  128Mi

Limits:
  cpu:     500m
  memory:  256Mi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Calculation
&lt;/h3&gt;

&lt;p&gt;If there are 6 Pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6 × 100m CPU = 600m requested CPU

6 × 128Mi = 768Mi requested Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 9 — Readiness Probe
&lt;/h1&gt;

&lt;p&gt;Your Deployment contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Readiness asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should Kubernetes send normal Service traffic to this Pod?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now intentionally break it.&lt;/p&gt;

&lt;p&gt;Change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/wrong-page&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;READY
0/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STATUS
Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important Interview Question
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Can a Pod be Running but not Ready?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;YES.&lt;/p&gt;

&lt;p&gt;Investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;POD-NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Events:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected eventually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1/1 Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 10 — Liveness Probe
&lt;/h1&gt;

&lt;p&gt;Your Deployment contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness
→ Should this workload receive traffic?

Liveness
→ Is this workload healthy enough to keep running?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeated liveness failures can cause kubelet to restart the Container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interview Question
&lt;/h3&gt;

&lt;p&gt;Explain the difference between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness Probe
vs
Liveness Probe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in your own words.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 11 — Create a Service
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-service&lt;/span&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;

  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints nginx-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see Pod IP addresses.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
nginx-service
   ↓
selector:
app: nginx
   ↓
matching Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important
&lt;/h3&gt;

&lt;p&gt;The Service does not randomly discover your application.&lt;/p&gt;

&lt;p&gt;It uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finds Pods with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 12 — Break the Service
&lt;/h1&gt;

&lt;p&gt;Now create a real incident.&lt;/p&gt;

&lt;p&gt;Change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wrong-label&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints nginx-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see no endpoints.&lt;/p&gt;

&lt;p&gt;Now troubleshoot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service selector
vs
Pod labels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints nginx-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interview Scenario
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Pods are Running, but the Service has no endpoints. What do you check?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pod labels and Service selector.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 13 — Metrics Server
&lt;/h1&gt;

&lt;p&gt;Now check resource usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understand the difference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REQUEST
100m CPU

≠

ACTUAL USAGE
for example 5m CPU

≠

LIMIT
500m CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three different concepts.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod / Container
      ↓
    kubelet
      ↓
Metrics Server
      ↓
Kubernetes Metrics API
      ↓
HPA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 14 — Create HPA
&lt;/h1&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano hpa.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autoscaling/v2&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HorizontalPodAutoscaler&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-hpa&lt;/span&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-deployment&lt;/span&gt;

  &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;

  &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Resource&lt;/span&gt;
      &lt;span class="na"&gt;resource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cpu&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Utilization&lt;/span&gt;
          &lt;span class="na"&gt;averageUtilization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; hpa.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TARGETS
cpu: 0%/50%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interpret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0% = current CPU utilization
50% = target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe hpa nginx-hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 15 — Understand HPA Before Testing It
&lt;/h1&gt;

&lt;p&gt;HPA does not simply mean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU reaches exactly 50%
→ create exactly 1 Pod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, HPA evaluates the metric and calculates a desired replica count.&lt;/p&gt;

&lt;p&gt;Also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HPA
 ↓
changes desired replicas
 ↓
Deployment / ReplicaSet
 ↓
Pods are created/removed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this CPU-utilization HPA, your CPU request matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU request = 100m

actual usage 10m
≈ 10%

actual usage 50m
≈ 50%

actual usage 80m
≈ 80%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Part 16 — Generate Traffic
&lt;/h1&gt;

&lt;p&gt;Make sure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc nginx-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a load generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run load-generator &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;busybox:1.36 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; /bin/sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'for i in 1 2 3 4 5 6 7 8 9 10; do while true; do wget -q -O- http://nginx-service &amp;gt; /dev/null; done &amp;amp; done; wait'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now use multiple terminals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal 1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Terminal 2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Terminal 3
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load Generator
      ↓
HTTP requests
      ↓
Service
      ↓
Nginx Pods
      ↓
CPU utilization ↑
      ↓
Metrics Server
      ↓
HPA
      ↓
Desired replicas ↑
      ↓
Deployment / ReplicaSet
      ↓
More Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not expect exact CPU percentages or exact scaling timing to be identical on every student's cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 17 — Stop Traffic
&lt;/h1&gt;

&lt;p&gt;Delete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod load-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CPU usage should decrease.&lt;/p&gt;

&lt;p&gt;Eventually HPA can reduce replicas toward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minReplicas = 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scale-down may not happen immediately.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 18 — Production Incident: Pending Pods
&lt;/h1&gt;

&lt;p&gt;This is based on a real incident from class.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node Pod Capacity = 29
Current Pods      = 29
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HPA wants additional replicas.&lt;/p&gt;

&lt;p&gt;What happens?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HPA
 ↓
Desired replicas ↑
 ↓
ReplicaSet creates new Pod objects
 ↓
Scheduler tries to place them
 ↓
Node = 29/29 Pods
 ↓
No available Pod slot
 ↓
Pending
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;PENDING-POD&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Events:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FailedScheduling
Too many pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important
&lt;/h3&gt;

&lt;p&gt;This is different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Insufficient cpu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Insufficient memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not guess the root cause.&lt;/p&gt;

&lt;p&gt;Read the Events.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 19 — Kubernetes Troubleshooting Challenge
&lt;/h1&gt;

&lt;p&gt;For each scenario, write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Symptom
2. Command used
3. Root cause
4. Fix
5. Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incident A
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod = Pending
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;POD&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incident B
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod = Running
READY = 0/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Readiness Probe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incident C
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pods Running
Service exists
Endpoints = none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service selector
vs
Pod labels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incident D
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Container keeps restarting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;POD&amp;gt;
kubectl logs &amp;lt;POD&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider liveness failures, application errors, OOMKilled, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incident E
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HPA shows unknown CPU metric
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods
kubectl describe hpa nginx-hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also verify the workload has appropriate CPU requests for utilization-based CPU HPA.&lt;/p&gt;




&lt;h1&gt;
  
  
  Part 20 — Commands You Must Know
&lt;/h1&gt;

&lt;p&gt;By Monday, students should be comfortable with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
kubectl describe node &amp;lt;NODE&amp;gt;

kubectl get pods
kubectl get pods &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
kubectl describe pod &amp;lt;POD&amp;gt;
kubectl logs &amp;lt;POD&amp;gt;

kubectl get deployment
kubectl describe deployment nginx-deployment
kubectl get rs

kubectl get svc
kubectl describe svc nginx-service
kubectl get endpoints nginx-service

kubectl get configmap
kubectl get secret

kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml

kubectl top nodes
kubectl top pods

kubectl get hpa
kubectl get hpa &lt;span class="nt"&gt;-w&lt;/span&gt;
kubectl describe hpa nginx-hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Final Architecture — Draw This Yourself
&lt;/h1&gt;

&lt;p&gt;Every student must be able to draw and explain this without notes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    USERS
                      ↓
              Load Balancer
                      ↓
                   Service
                      ↓
          ┌───────────┼───────────┐
          ↓           ↓           ↓
        Pod 1       Pod 2       Pod 3
          │           │           │
          └──── Deployment ───────┘
                    ↓
               ReplicaSet


ConfigMap ─────────→ Pods
Secret ────────────→ Pods


Worker Node
├── CPU
├── Memory
├── Storage
├── Networking
└── Pod Capacity


Pods
 ↓
CPU / Memory usage
 ↓
kubelet
 ↓
Metrics Server
 ↓
HPA
 ↓
Deployment desired replicas
 ↓
ReplicaSet
 ↓
More / Fewer Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Weekend Interview Questions
&lt;/h1&gt;

&lt;p&gt;Students should prepare answers to these &lt;strong&gt;without reading from notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is Kubernetes?&lt;/li&gt;
&lt;li&gt;What is Amazon EKS?&lt;/li&gt;
&lt;li&gt;What is the Control Plane?&lt;/li&gt;
&lt;li&gt;What is a Worker Node?&lt;/li&gt;
&lt;li&gt;What is a Pod?&lt;/li&gt;
&lt;li&gt;What is a Container?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;kubectl&lt;/code&gt; do?&lt;/li&gt;
&lt;li&gt;What does the Scheduler do?&lt;/li&gt;
&lt;li&gt;What is a Deployment?&lt;/li&gt;
&lt;li&gt;What is a ReplicaSet?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;replicas: 3&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What is desired state?&lt;/li&gt;
&lt;li&gt;What is reconciliation?&lt;/li&gt;
&lt;li&gt;What happens when you delete a Deployment-managed Pod?&lt;/li&gt;
&lt;li&gt;Why can Pod IP addresses change?&lt;/li&gt;
&lt;li&gt;What problem does a Service solve?&lt;/li&gt;
&lt;li&gt;What is ClusterIP?&lt;/li&gt;
&lt;li&gt;What is LoadBalancer?&lt;/li&gt;
&lt;li&gt;How does a Service find Pods?&lt;/li&gt;
&lt;li&gt;What are labels?&lt;/li&gt;
&lt;li&gt;What is a selector?&lt;/li&gt;
&lt;li&gt;What are endpoints?&lt;/li&gt;
&lt;li&gt;What happens when Service selector does not match Pod labels?&lt;/li&gt;
&lt;li&gt;What is a ConfigMap?&lt;/li&gt;
&lt;li&gt;What is a Secret?&lt;/li&gt;
&lt;li&gt;ConfigMap vs Secret?&lt;/li&gt;
&lt;li&gt;What are resource requests?&lt;/li&gt;
&lt;li&gt;What are resource limits?&lt;/li&gt;
&lt;li&gt;Who uses requests during scheduling?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;100m&lt;/code&gt; CPU?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;1000m&lt;/code&gt; CPU?&lt;/li&gt;
&lt;li&gt;What can happen when CPU reaches its limit?&lt;/li&gt;
&lt;li&gt;What can happen when Memory exceeds its limit?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;OOMKilled&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What is a Readiness Probe?&lt;/li&gt;
&lt;li&gt;What is a Liveness Probe?&lt;/li&gt;
&lt;li&gt;Can a Pod be &lt;code&gt;Running&lt;/code&gt; but &lt;code&gt;0/1 Ready&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is Metrics Server?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;kubectl top pods&lt;/code&gt; show?&lt;/li&gt;
&lt;li&gt;What is HPA?&lt;/li&gt;
&lt;li&gt;What does Horizontal scaling mean?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;minReplicas&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is &lt;code&gt;maxReplicas&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;averageUtilization: 50&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;Why are CPU requests important for CPU-utilization HPA?&lt;/li&gt;
&lt;li&gt;Does HPA directly create Pods?&lt;/li&gt;
&lt;li&gt;Does HPA create Worker Nodes?&lt;/li&gt;
&lt;li&gt;What happens if HPA wants more Pods but the Node is full?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;Pending&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;How do you find why a Pod is Pending?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;FailedScheduling&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;Too many pods&lt;/code&gt; mean?&lt;/li&gt;
&lt;li&gt;What's the difference between CPU capacity and Pod capacity?&lt;/li&gt;
&lt;li&gt;What do you check when Pods are Running but Service has no endpoints?&lt;/li&gt;
&lt;li&gt;What commands would you use if an application is down?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Required Submission
&lt;/h2&gt;

&lt;p&gt;Each student should submit screenshots showing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. kubectl get nodes
2. kubectl get pods
3. kubectl get deployment
4. kubectl get rs
5. kubectl get svc
6. kubectl get endpoints nginx-service
7. kubectl get configmap
8. kubectl get secret
9. kubectl describe pod showing Requests/Limits
10. kubectl top nodes
11. kubectl top pods
12. kubectl get hpa
13. HPA before load
14. Load generator Running
15. HPA during CPU load
16. Additional Nginx Pods created by scaling
17. HPA after load is removed
18. One troubleshooting example and its Events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>kubernetes</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Production Kubernetes Troubleshooting Lab</title>
      <dc:creator>Aisalkyn Aidarova</dc:creator>
      <pubDate>Thu, 08 Oct 2026 01:37:58 +0000</pubDate>
      <link>https://dev.to/jumptotech/production-kubernetes-troubleshooting-lab-1iec</link>
      <guid>https://dev.to/jumptotech/production-kubernetes-troubleshooting-lab-1iec</guid>
      <description>&lt;h3&gt;
  
  
  Observability, Incident Response &amp;amp; Root-Cause Analysis
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; You are the DevOps/SRE on-call team for an e-commerce company.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    CUSTOMER
                        │
                        ▼
                   order-service
                        │
                        ▼
                    Service
                        │
              ┌─────────┼─────────┐
              ▼         ▼         ▼
            Pod-1     Pod-2     Pod-3
                        │
                        ▼
                  Dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today we will deliberately create these incidents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INCIDENT 1 → New deployment → CrashLoopBackOff → Rollback

INCIDENT 2 → Production slow → High traffic / CPU → HPA investigation

INCIDENT 3 → Running Pods but application unavailable → Service selector

INCIDENT 4 → Running 0/1 → Readiness failure

INCIDENT 5 → OOMKilled → Memory investigation

INCIDENT 6 → Application dependency problem → Logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  LAB 0 — Check the Cluster
&lt;/h1&gt;

&lt;p&gt;Everybody starts here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cluster-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                         STATUS   ROLES    AGE
ip-192-168-10-10.ec2...      Ready    &amp;lt;none&amp;gt;   ...
ip-192-168-20-20.ec2...      Ready    &amp;lt;none&amp;gt;   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create our production namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespace production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  LAB 1 — Build Healthy Production First
&lt;/h1&gt;

&lt;p&gt;Before troubleshooting production, we need &lt;strong&gt;healthy production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano production.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;

  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;

    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.27&lt;/span&gt;

        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;64Mi"&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;

        &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

        &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
          &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;order-service&lt;/span&gt;

  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; production.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                             READY   STATUS
order-service-xxxxxxxxxx-abcde   1/1     Running
order-service-xxxxxxxxxx-fghij   1/1     Running
order-service-xxxxxxxxxx-klmno   1/1     Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ctrl+C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Check the Entire Production Environment
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check labels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app=order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on Kubernetes version, you may also use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslice &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should have backend addresses.&lt;/p&gt;

&lt;p&gt;Concept:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service
   │
   │ selector:
   │ app=order-service
   │
   ▼
Pod        Pod        Pod
app=       app=       app=
order      order      order
-service   -service   -service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything matches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production is healthy.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Verify the Application
&lt;/h1&gt;

&lt;p&gt;Create a temporary troubleshooting Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run test-client &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;curlimages/curl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;3600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pod test-client &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should receive the Nginx HTML page.&lt;/p&gt;

&lt;p&gt;Now tell students:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is our known-good production baseline.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's important.&lt;/p&gt;




&lt;h1&gt;
  
  
  INCIDENT 1 — New Deployment Breaks Production
&lt;/h1&gt;

&lt;h2&gt;
  
  
  STUDENTS ONLY RECEIVE THIS MESSAGE
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;INCIDENT:&lt;/strong&gt; Customers cannot place orders. The Order Service started failing immediately after today's deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask students:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What changed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New deployment.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But currently everything works.&lt;/p&gt;




&lt;h1&gt;
  
  
  INSTRUCTOR — Break Production
&lt;/h1&gt;

&lt;p&gt;Don't show students the command.&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;set &lt;/span&gt;image deployment/order-service &lt;span class="se"&gt;\&lt;/span&gt;
order-service&lt;span class="o"&gt;=&lt;/span&gt;nginx:this-version-does-not-exist &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now students run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They should eventually see something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;order-service-old        1/1   Running
order-service-new        0/1   ImagePullBackOff
order-service-new        0/1   ImagePullBackOff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important teaching point:&lt;/p&gt;

&lt;p&gt;Because this is a rolling update, old healthy Pods may remain available while new Pods fail. So production may be &lt;strong&gt;degraded&lt;/strong&gt; rather than completely unavailable.&lt;/p&gt;




&lt;h1&gt;
  
  
  Student Investigation
&lt;/h1&gt;

&lt;p&gt;First:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will not complete normally.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pick one failing Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;NEW-POD-NAME&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at &lt;strong&gt;Events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Students should find something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failed to pull image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ErrImagePull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ImagePullBackOff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is &lt;code&gt;ImagePullBackOff&lt;/code&gt; the root cause?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More precisely, it's the Kubernetes symptom/state. The useful cause in the Events is that the requested image/tag cannot be pulled.&lt;/p&gt;

&lt;p&gt;Check Deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.template.spec.containers[0].image}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx:this-version-does-not-exist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Check Rollout History
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll have revisions.&lt;/p&gt;

&lt;p&gt;Now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Production worked before the release. The new rollout cannot start. Should we sit in production and experiment with the image?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mitigate first.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout undo deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;READY   STATUS
1/1     Running
1/1     Running
1/1     Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.spec.template.spec.containers[0].image}{"\n"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should be back to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx:1.27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify from customer path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incident #1 conclusion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Deployment
      ↓
New Pods fail
      ↓
ImagePullBackOff
      ↓
Events
      ↓
Invalid/unavailable image tag
      ↓
ROLLBACK
      ↓
Previous known-good release
      ↓
VERIFY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  INCIDENT 2 — Production Is Slow
&lt;/h1&gt;

&lt;p&gt;Now we make the lab more professional.&lt;/p&gt;

&lt;p&gt;Tell students only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;INCIDENT:&lt;/strong&gt; Production is slow. Customers report that Order Service responses are taking much longer than normal. There has been no new deployment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's the cause?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Students should NOT answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Traffic.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They should say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We need evidence.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  First Establish Baseline
&lt;/h1&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1/1 Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this command works, save/observe the CPU usage.&lt;/p&gt;

&lt;p&gt;If it returns something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: Metrics API not available
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that itself is an observability problem: Metrics Server isn't available/configured. Don't confuse that with the application incident.&lt;/p&gt;

&lt;p&gt;Check HPA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There probably isn't one yet.&lt;/p&gt;




&lt;h1&gt;
  
  
  Create HPA
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl autoscale deployment order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cpu-percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;50 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe hpa order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Metrics Server is functioning, after metrics become available you'll see current/target CPU utilization.&lt;/p&gt;




&lt;h1&gt;
  
  
  Generate Traffic
&lt;/h1&gt;

&lt;p&gt;Run a load-generator Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run load-generator &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;busybox:1.36 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; /bin/sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;'while true; do wget -q -O- http://order-service &amp;gt;/dev/null; done'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One loop may not produce enough CPU to demonstrate scaling. Create several:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in &lt;/span&gt;1 2 3 4 5&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;kubectl run load-&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;busybox:1.36 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; /bin/sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'while true; do wget -q -O- http://order-service &amp;gt;/dev/null; done'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in another terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What should students investigate?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request/load increased
        ↓
CPU may increase
        ↓
HPA observes CPU relative to requests
        ↓
Desired replicas may increase
        ↓
Deployment creates additional Pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: &lt;strong&gt;don't promise a particular CPU percentage or replica count.&lt;/strong&gt; It depends on your cluster, Nginx workload, Metrics Server, timing, and how much load the generators produce.&lt;/p&gt;

&lt;p&gt;That's actually good for the class: students must observe evidence rather than copy an expected number.&lt;/p&gt;

&lt;p&gt;Stop watchers with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ctrl+C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Make Scaling Intentionally Too Restrictive
&lt;/h1&gt;

&lt;p&gt;Now create a more interesting scenario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch hpa order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"maxReplicas":3}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get hpa order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MINPODS = 3
MAXPODS = 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The HPA cannot scale beyond three.&lt;/p&gt;

&lt;p&gt;Keep load running.&lt;/p&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl top pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe hpa order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What evidence would you need before saying traffic/capacity is the reason for slowness?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Students should correlate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Load/request rate ↑
CPU/resource pressure ↑
Latency ↑
HPA target exceeded
Replicas already at configured maximum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production slow
→ probably traffic.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Stop Traffic
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod load-generator &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--ignore-not-found&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod &lt;span class="se"&gt;\&lt;/span&gt;
load-1 load-2 load-3 load-4 load-5 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--ignore-not-found&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restore HPA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch hpa order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"maxReplicas":6}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  INCIDENT 3 — All Pods Running, Application Doesn't Work
&lt;/h1&gt;

&lt;p&gt;This is one of the best incidents.&lt;/p&gt;

&lt;p&gt;Tell students:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;INCIDENT:&lt;/strong&gt; All Order Service Pods show &lt;code&gt;Running 1/1&lt;/code&gt;, but requests to the Order Service fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If Pods are Running, does that prove production is working?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  INSTRUCTOR — Break Service
&lt;/h1&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch service order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"selector":{"app":"wrong-order-service"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students don't see this command.&lt;/p&gt;




&lt;h1&gt;
  
  
  Student Investigation
&lt;/h1&gt;

&lt;p&gt;They start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Running
Running
Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fails/times out depending on the exact networking behavior.&lt;/p&gt;

&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Service exists.&lt;/p&gt;

&lt;p&gt;Next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Likely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENDPOINTS   &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On newer clusters also inspect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpointslice &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe service order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Service selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app=wrong-order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pod label:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app=order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is your evidence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pods Running ✓
      ↓
Service exists ✓
      ↓
Endpoints ✗
      ↓
Selector does not match labels
      ↓
ROOT CAUSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Fix It
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch service order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"selector":{"app":"order-service"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Addresses should return.&lt;/p&gt;

&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production works again.&lt;/p&gt;




&lt;h1&gt;
  
  
  INCIDENT 4 — Running 0/1
&lt;/h1&gt;

&lt;p&gt;Tell students:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;INCIDENT:&lt;/strong&gt; Pods are running, but they are not becoming Ready.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instructor breaks readiness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch deployment order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'[
  {
    "op":"replace",
    "path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path",
    "value":"/health-does-not-exist"
  }
]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Students check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New Pods may show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0/1 Running
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's the difference between STATUS and READY?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod &amp;lt;POD-NAME&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They should find readiness probe failures such as an HTTP failure status.&lt;/p&gt;

&lt;p&gt;Now check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ready backends can disappear as the bad rollout progresses.&lt;/p&gt;

&lt;p&gt;Concept:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Container
   ↓
Running
   ↓
Readiness check
   ↓
FAIL
   ↓
Pod not Ready
   ↓
Not a healthy Service backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  What Do We Do in Production?
&lt;/h1&gt;

&lt;p&gt;Again ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This happened immediately after a new configuration/deployment. Previous revision worked. What is our fastest safe mitigation?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rollback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout undo deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  INCIDENT 5 — OOMKilled
&lt;/h1&gt;

&lt;p&gt;For this one use a separate workload so we don't destroy the main application.&lt;/p&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano memory-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory-app&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory-app&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python:3.12-alpine&lt;/span&gt;

    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;20Mi"&lt;/span&gt;
      &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;40Mi"&lt;/span&gt;

    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;python&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-c&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;import time&lt;/span&gt;
        &lt;span class="s"&gt;data = []&lt;/span&gt;
        &lt;span class="s"&gt;while True:&lt;/span&gt;
            &lt;span class="s"&gt;data.append(bytearray(10 * 1024 * 1024))&lt;/span&gt;
            &lt;span class="s"&gt;print("Allocated more memory", flush=True)&lt;/span&gt;
            &lt;span class="s"&gt;time.sleep(1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; memory-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pod memory-app &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container should exceed its memory limit and be terminated/restarted. Depending on timing, you may see &lt;code&gt;OOMKilled&lt;/code&gt; most clearly in &lt;code&gt;describe&lt;/code&gt; rather than as the STATUS column.&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod memory-app &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Last State:
  Terminated
Reason:
  OOMKilled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs memory-app &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And critically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs memory-app &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--previous&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very good place to teach &lt;code&gt;--previous&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was there a deployment?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should we automatically rollback?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Evidence points toward memory behavior/resource limit.&lt;/p&gt;

&lt;p&gt;Remove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pod memory-app &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  INCIDENT 6 — Dependency Failure
&lt;/h1&gt;

&lt;p&gt;Now we'll simulate the idea of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Order Service
     ↓
Kafka / Database / API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without requiring Kafka installation.&lt;/p&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano dependency-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-service&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-service&lt;/span&gt;

  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-service&lt;/span&gt;

    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-service&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;busybox:1.36&lt;/span&gt;

        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/bin/sh&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-c&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Starting payment-service"&lt;/span&gt;
          &lt;span class="s"&gt;echo "Connecting to Kafka..."&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
          &lt;span class="s"&gt;echo "ERROR: Cannot connect to kafka.production.svc:9092"&lt;/span&gt;
          &lt;span class="s"&gt;echo "Application exiting"&lt;/span&gt;
          &lt;span class="s"&gt;exit 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; dependency-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CrashLoopBackOff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now tell students only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;INCIDENT:&lt;/strong&gt; Payment Service is unavailable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They should investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs deployment/payment-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually use the actual Pod name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;payment-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &amp;lt;PAYMENT-POD&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--previous&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They'll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Starting payment-service
Connecting to Kafka...
ERROR: Cannot connect to kafka.production.svc:9092
Application exiting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have we proven Kafka itself is down?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is very important.&lt;/p&gt;

&lt;p&gt;We have proven:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Payment application reports that it cannot connect to the Kafka endpoint.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We haven't yet proven why.&lt;/p&gt;

&lt;p&gt;Potential investigation branches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Kafka connection failure
                           │
         ┌─────────────────┼─────────────────┐
         ↓                 ↓                 ↓
      DNS/name           Network           Kafka
      wrong?             blocked?          unhealthy?
         │                 │                 │
         ↓                 ↓                 ↓
      Service?        NetworkPolicy?      Brokers?
         │
         ↓
       Port?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's production thinking.&lt;/p&gt;

&lt;p&gt;Delete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete deployment payment-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  FINAL INCIDENT — Students Get No Hints
&lt;/h1&gt;

&lt;p&gt;Now combine everything.&lt;/p&gt;

&lt;p&gt;Tell them:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🚨 &lt;strong&gt;SEV-1 INCIDENT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Customers report that the Order Service is unavailable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are the on-call DevOps team. Investigate and restore service.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't tell them anything else.&lt;/p&gt;

&lt;p&gt;Instructor secretly breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch service order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"selector":{"app":"orders"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then sit back.&lt;/p&gt;

&lt;p&gt;Students should develop this process themselves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What's affected?
       ↓
Order Service
       ↓
Any deployment?
       ↓
No
       ↓
Pods?
       ↓
Running / Ready
       ↓
Resources?
       ↓
Healthy
       ↓
Service?
       ↓
Exists
       ↓
Endpoints?
       ↓
NONE
       ↓
Why?
       ↓
Selector vs labels
       ↓
Mismatch
       ↓
ROOT CAUSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch service order-service &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"selector":{"app":"order-service"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But don't accept:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Fixed.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PROVE IT.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They need to verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get endpoints order-service &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production test-client &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://order-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only now:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Production restored.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The Troubleshooting Command Sheet
&lt;/h1&gt;

&lt;p&gt;This is the part I would have every student save.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 1. WORKLOAD&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;-o&lt;/span&gt; wide

kubectl describe pod &amp;lt;pod&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 2. LOGS&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl logs &amp;lt;pod&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl logs &amp;lt;pod&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--previous&lt;/span&gt;


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 3. EVENTS&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get events &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.metadata.creationTimestamp


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 4. METRICS&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl top pods &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl top nodes


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 5. DEPLOYMENT&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get deployment &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl describe deployment &amp;lt;deployment&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl rollout status deployment/&amp;lt;deployment&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/&amp;lt;deployment&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl rollout undo deployment/&amp;lt;deployment&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 6. NETWORK&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl describe svc &amp;lt;service&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get endpoints &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get endpointslice &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get ingress &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get networkpolicy &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 7. STORAGE&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get pv

kubectl get storageclass

kubectl describe pvc &amp;lt;pvc&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 8. SCALING&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get hpa &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl describe hpa &amp;lt;hpa&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 9. SECURITY&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl auth can-i get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl auth can-i delete pods &lt;span class="nt"&gt;-n&lt;/span&gt; production


&lt;span class="c"&gt;# =====================================================&lt;/span&gt;
&lt;span class="c"&gt;# 10. CONFIGURATION&lt;/span&gt;
&lt;span class="c"&gt;# =====================================================&lt;/span&gt;

kubectl get configmap &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get secret &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The Production Rule Students Need to Remember
&lt;/h1&gt;

&lt;p&gt;Don't teach them this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Production Down
     ↓
kubectl get pods
     ↓
restart everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Teach them this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    INCIDENT
                       │
                       ▼
              WHAT IS THE IMPACT?
                       │
                       ▼
               WHAT CHANGED?
                       │
                       ▼
          IDENTIFY AFFECTED COMPONENT
                       │
                       ▼
         ┌─────────────┼─────────────┐
         ▼             ▼             ▼
       LOGS          METRICS       EVENTS
         │             │             │
         └─────────────┼─────────────┘
                       ▼
                  HYPOTHESIS
                       │
                       ▼
                    EVIDENCE
                       │
                       ▼
                  ROOT CAUSE
                       │
             ┌─────────┴─────────┐
             ▼                   ▼
         MITIGATE               FIX
       e.g. rollback
             │
             ▼
           VERIFY
             │
             ▼
      PRODUCTION RESTORED
             │
             ▼
       ROOT CAUSE ANALYSIS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And throughout the lab, whenever a student says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“I think it's traffic.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your response should be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Show me the evidence.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If they say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It's Kubernetes.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Which Kubernetes component? Show me the evidence.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If they say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Kafka is down.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Have you proven Kafka is down, or have you only proven that your application cannot connect to Kafka?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If they say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I fixed it.”&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>sre</category>
    </item>
  </channel>
</rss>
