TT Lab
Get started
Learn Learning paths Courses

CKAD — Kubernetes Application Developer

Let the Pod Clock Out After the Response

Continue in TT Lab

Goal

On a personal k3s VM, you terminate a Pod while leaving an HTTP request that is already being handled, and explain it by connecting the app's shutdown handling, the EndpointSlice, and the termination grace. It uses a real process and is not a kwok state simulation.

Why it matters

A Deployment's success indication does not guarantee the completion of requests that were being handled. Here you place a small HTTP server that runs as read-only code, and the helper creates the Pod declaration the student wrote as is. You first check the Service path and the acceptance of the request and delete with the Pod watch already started, so you can connect the response, disconnection, and exit code of the same UID.

It compares a normal termination with an insufficient grace, but this is not a lab where you hit fractions of a second. You do not copy an input file or observation file to produce a success sentence; you check whether the real execution and its interpretation agree. Excluding new requests and terminating existing connections are not the same event, and this experiment does not guarantee zero downtime for a whole service including an external load balancer.

The estimate is 80 minutes. The session defaults to 60 minutes, so extend it with +time before it expires (up to 180 minutes). When the session ends, the VM and files are reclaimed. Keep the results you need separately before it ends.

Steps

  1. Record the personal VM's node_name, server_version, namespace_uid, and image in /root/ckad-inflight-termination/environment.json, and run run 1. The namespace is ckad-inflight-termination, and the image is the server image in the provided pod-template.json.
  2. Create immediate.json. The Pod name and case label are immediate, MODE is immediate, WORK_SECONDS is the string 8, terminationGracePeriodSeconds is the integer 15, and there is no lifecycle. With run 2, observe a request the server accepted during termination.
  3. In immediate-analysis.json, write the observed pod_uid, client_error, and exit_code and your judgments of accepted_before_delete and readiness_alone_drains_requests, and run run 3. Distinguish whether it was accepted before deletion and whether readiness alone can finish the request.
  4. Create graceful.json. The name and case label are graceful, MODE is graceful, WORK_SECONDS is the string 8, and the grace is the integer 15. Keep the template's preStop so that it waits 2 seconds after the /drain call, and run run 4.
  5. In graceful-analysis.json, write the pod_uid and, as first_terminating_conditions, the entire conditions of the first terminating endpoint. Judge hook_before_term, accepted_response_complete, and endpoint_ready_false_means_connection_closed by connecting them to the observation, and run run 5.
  6. Create exhausted.json. The name and case label are exhausted, MODE is graceful, WORK_SECONDS is the string 10, and the grace is the integer 5. Change only the sleep after /drain in preStop to 3 seconds, and run run 6. See whether the request result differs even when the termination mode is the same.
  7. Create repaired.json. The name and case label are repaired, MODE is graceful, WORK_SECONDS is the string 10, the grace is the integer 15, and preStop is 3 seconds after /drain. With run 7, confirm the actual completion response. Do not edit the existing observation files.
  8. In the outcomes of comparison.json, record pod_uid, client_completed, and exit_code for each of immediate, graceful, exhausted, and repaired. Judge grace_includes_prestop, api_delete_is_exact_deadline, and service_zero_downtime_proven, and run run 8.

Notes

Confirm it is a real kitchen

Record the personal VM's node_name, server_version, namespace_uid, and image in /root/ckad-inflight-termination/environment.json, and run run 1. The namespace is ckad-inflight-termination, and the image is the server image in the provided pod-template.json.

Read kubectl get nodes, kubectl version -o json, the metadata.uid from kubectl get namespace, and the Pod template. Do not connect to an external cluster.

Clock out right away, leaving the guests behind

Create immediate.json. The Pod name and case label are immediate, MODE is immediate, WORK_SECONDS is the string 8, terminationGracePeriodSeconds is the integer 15, and there is no lifecycle. With run 2, observe a request the server accepted during termination.

From pod-template.json, change only the name, the case label, MODE, WORK_SECONDS, the termination grace, and preStop. The run observes the real request and deletion with that declaration.

A ready flag does not finish the order

In immediate-analysis.json, write the observed pod_uid, client_error, and exit_code and your judgments of accepted_before_delete and readiness_alone_drains_requests, and run run 3. Distinguish whether it was accepted before deletion and whether readiness alone can finish the request.

From the observation in observation-2.json, connect initial.events, delete_at, client, and pod_watch. The exit code is in the last container terminated state.

Finish the orders already taken, then clock out

Create graceful.json. The name and case label are graceful, MODE is graceful, WORK_SECONDS is the string 8, and the grace is the integer 15. Keep the template's preStop so that it waits 2 seconds after the /drain call, and run run 4.

From pod-template.json, change only the name, the case label, MODE, WORK_SECONDS, the termination grace, and preStop. The run observes the real request and deletion with that declaration.

The door is closed, but the response still arrives

In graceful-analysis.json, write the pod_uid and, as first_terminating_conditions, the entire conditions of the first terminating endpoint. Judge hook_before_term, accepted_response_complete, and endpoint_ready_false_means_connection_closed by connecting them to the observation, and run run 5.

Read the endpoints in observation-4.json in time order. Compare the hook and term in server_events with client.completed, and do not equate ready=false with a disconnection of the existing connection.

Give too short a termination grace

Create exhausted.json. The name and case label are exhausted, MODE is graceful, WORK_SECONDS is the string 10, and the grace is the integer 5. Change only the sleep after /drain in preStop to 3 seconds, and run run 6. See whether the request result differs even when the termination mode is the same.

From pod-template.json, change only the name, the case label, MODE, WORK_SECONDS, the termination grace, and preStop. The run observes the real request and deletion with that declaration.

Fix the grace and observe again

Create repaired.json. The name and case label are repaired, MODE is graceful, WORK_SECONDS is the string 10, the grace is the integer 15, and preStop is 3 seconds after /drain. With run 7, confirm the actual completion response. Do not edit the existing observation files.

From pod-template.json, change only the name, the case label, MODE, WORK_SECONDS, the termination grace, and preStop. The run observes the real request and deletion with that declaration.

Write conclusions only as far as you observed

In the outcomes of comparison.json, record pod_uid, client_completed, and exit_code for each of immediate, graceful, exhausted, and repaired. Judge grace_includes_prestop, api_delete_is_exact_deadline, and service_zero_downtime_proven, and run run 8.

Compare the observations of steps 2, 4, 6, and 7. The grace budget includes the hook, but the API deletion time does not guarantee the exact termination time, and a single request does not prove the availability of the whole service.