Skip to content
Back to skills

Gke Workload Troubleshooting

ASecurity

Systematic Standard Operating Procedure (SOP) for diagnosing GKE workload failures, crash loops, resource OOMs, mounting errors, and connectivity timeouts.

  • 7 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentsgobashnodegcpgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add go-steer/core-agent --skill gke-workload-troubleshooting --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gke Workload Troubleshooting?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gke Workload Troubleshooting
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/go-steer-gke-workload-troubleshooting-core-agent/badge)](https://www.skillsdirectory.com/skills/go-steer-gke-workload-troubleshooting-core-agent)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gke-workload-troubleshooting
description: Systematic Standard Operating Procedure (SOP) for diagnosing GKE workload failures, crash loops, resource OOMs, mounting errors, and connectivity timeouts.
---

# GKE Workload Troubleshooting Skill

Use this skill to systematically diagnose and resolve failures in application workloads deployed in GKE clusters. This skill enforces a read-only diagnostics boundary before proposing manifest or config corrections.

## πŸ” Diagnostic Workflow

### Step 0: Context Acquisition & Time Window Definition

To begin troubleshooting, acquire the following context from the user or active `SETTINGS.md` config:

- **Project ID** (e.g., `my-gcp-project`)
  - **Cluster Name** (e.g., `my-gke-cluster`)
  - **Cluster Location** (e.g., `us-central1`)
  - **Workload Name** (e.g., `payment-api`)
  - **Workload Namespace** (e.g., `checkout`)
  - **Issue Time** (Optional, e.g., `2026-06-01T15:30:00Z`)

Before running any diagnostics or `kubectl` commands, you **must** fetch GKE credentials and context for the target GKE cluster:

```bash
gcloud container clusters get-credentials <cluster_name> --region <cluster_location>
```

#### Time Handling & Fallbacks:

1. **Determine Issue Timestamp ($T$)**:
   - **Specific Time Provided**: If the user provides a specific timestamp, use it as $T$.
   - **Relative Time Provided (e.g., "5 minutes ago")**: Dynamically calculate the corresponding UTC timestamp based on the current system time, and use it as $T$.
   - **No Time Provided (Default)**:
     1. Retrieve the GKE pod status (`kubectl get pods -n <namespace> -o yaml`).
     2. If there are crashing or pending containers, check their state transition timestamps (e.g. `status.containerStatuses[*].lastState.terminated.finishedAt` or `status.startTime`) and use that transition time as $T$.
     3. If no active transitions are found, default to the **current system time** as $T$.

2. **Window Calculation**: Center a 1-hour query window around the issue timestamp $T$:
   - `Start_Time` = `T - 30m`
   - `End_Time` = `T + 30m`

---

### Step 1: Analyze Pod Status and Conditions

Inspect the workload's active pod states and controller status.

**Diagnostic Commands:**

```bash
# 1. Inspect the deployment's actual selector labels:
kubectl get deployment <workload_name> -n <workload_namespace> -o jsonpath='{.spec.selector.matchLabels}'
# 2. Query the pods using the returned labels, for example:
kubectl get pods -l <selector_labels> -n <workload_namespace>
kubectl get deploy/<workload_name> -n <workload_namespace> -o yaml
```

#### Diagnostic Decision Tree:

- **Phase: Pending**:
  - The Pod cannot schedule on any node. Proceed directly to **Step 2 (Query Namespace Events)**.
- **State: CrashLoopBackOff / Error**:
  - Container is booting but exiting repeatedly. Check the terminated status using:

    ```bash
    kubectl get pod <pod_name> -n <workload_namespace> -o jsonpath='{.status.containerStatuses[*].lastState.terminated}'
    ```

    - **ExitCode: 137 (OOMKilled)**: Memory limit reached. Proceed to **Step 3 (Inspect Logs)** and inspect container startup command to differentiate between an application-level memory leak/loop vs an infrastructure capacity limit mismatch, then proceed to **Step 5** to propose fixes.
    - **ExitCode: 1 or other non-zero codes**: The application code crashed. Proceed directly to **Step 3 (Inspect Logs)**.

- **State: ContainerCreating**:
  - The container is blocked during volume mount, networking setup, or image pulling. Proceed directly to **Step 2 (Query Namespace Events)**.

---

### Step 2: Query Namespace Events

Look for infrastructure, volume, image, or scheduling alerts in GKE.

**Diagnostic Command:**

```bash
kubectl get events -n <workload_namespace> --sort-by='.metadata.creationTimestamp'
# Or query Cloud Logging for historical GKE events within the time window:
gcloud logging read "resource.type=\"k8s_cluster\" AND logName=\"projects/<project_id>/logs/events\" AND jsonPayload.involvedObject.namespace=\"<workload_namespace>\"" --start-time="[Start_Time]" --end-time="[End_Time]" --project="<project_id>"
```

_Note: Retrieve the sorted events list and manually inspect the event timestamps (CreationTimestamp/LastSeen) to identify failures occurring within the `[Start_Time]` and `[End_Time]` window._

#### Signature Identifiers:

- **`FailedScheduling`**: Node resource exhaustion. Look for messages like `0/3 nodes are available: 3 Insufficient memory.` or missing node affinity tolerations (e.g. Spot VM taints).
- **`FailedMount`**:
  - Missing PersistentVolumeClaim (`PVC`).
  - Missing Secret (`Secret "<secret-name>" not found`).
  - Missing ConfigMap (`ConfigMap "<configmap-name>" not found`).
- **`Failed` / `BackOff` (Image Pull)**:
  - Wrong image tag, missing image registry authentication (e.g., ImagePullBackOff).
  - **Resolution Steps for Wrong Image Tag**:
    1. Identify the failing container image name and the invalid tag.
    2. Check the Git repository history for the last known working image tag for this workload. Run `git log -p -S "<image_name>" -- <manifest_file_path>` (or use `git log` on the folder containing manifests) to identify the previous working tag in Git.
    3. If the invalid tag is a recent change in git history, compare it to the tag from the last successful commit.
    4. Propose reverting the image tag to the last working version, or correcting the tag version in the manifest patch.

---

### Step 3: Inspect Application Logs

Extract exceptions and stack traces from the application runtime.

**Diagnostic Commands:**

```bash
# Check current active log stream (handles multi-container pods)
kubectl logs <pod_name> -n <workload_namespace> --all-containers --tail=100

# Check logs from previously terminated container instances (handles multi-container pods)
kubectl logs <pod_name> -n <workload_namespace> --all-containers -p --tail=100
```

#### Signature Identifiers:

- **Out-of-Memory (OOM) Analysis**: Inspect container logs and startup commands (`spec.containers[*].command`). Differentiate between an **Application Code Leak/Loop** (unbounded array appending, memory leak signatures) vs an **Infrastructure Capacity Ceiling Mismatch** (legitimate workload demand exceeding limits).
- **Stack Trace / Unhandled Exception**: Look for language-specific stack traces (e.g., `panic:`, `NullPointerException`, `Traceback (most recent call)`). This indicates an application bug.
- **Egress Network Timeout**: Look for connection timeouts (e.g., `Connection timed out`, `dial tcp: i/o timeout`). Proceed to **Step 4 (Verify Connectivity)**.
- **Permission Errors (ReadOnlyRootFilesystem)**: Look for write errors (e.g., `Read-only file system`, `Permission denied` when writing to `/tmp` or `/var/log`). Propose adding an `emptyDir` volume mount to that directory in the manifest.

---

### Step 4: Verify Service Connectivity and Network Policies

Troubleshoot connection drops to other services.

**Diagnostic Commands:**

```bash
# Verify target endpoint is active
kubectl get endpoints <target_service_name> -n <target_namespace>

# Query network policies inside namespace
kubectl get networkpolicies -n <workload_namespace> -o yaml
```

#### Logic:

- If the endpoints list is empty, the target microservice itself is failing to schedule or boot (troubleshoot target service).
- If endpoints exist but logs show timeouts, analyze the `NetworkPolicy` egress blocks. Verify if egress to the target service's IP/port is explicitly whitelisted.

---

### Step 5: Report the RCA & proposed correction

<!-- core-agent deviation: this step is the ONE modification to the six
     otherwise-unmodified cluster skills. Upstream routed the handoff
     through a kanban card and told the agent to keep the RCA *out* of its
     reply. No such tool is registered in this runtime and the report is
     the only channel to the parent, so following upstream verbatim
     discards the entire investigation. The upstream text and the full
     rationale are in upstream/PROVENANCE.md; see also the frozen-recipe
     note in README.md. -->

You operate under a strict **read-only** boundary: **do not apply patches directly to the cluster, and do not open Pull Requests yourself.** The GitOps write path (`submit-suggestion`) is owned exclusively by the Platform Agent. Your job ends at a clear explanation and a concrete proposed fix.

**Your report is how that work reaches the parent β€” so put it all in the report.**

1. Synthesize the root cause analysis (e.g. _"payment-api is failing with exit code 137 because its memory limit is set to 256Mi while actual usage spiked to 270Mi"_), grounded in the exact diagnostic evidence you collected.
2. Generate the corrected YAML manifest patch (e.g. increase memory limits, add missing Secret mounts, or add tolerations for Spot nodes).
3. **Write all three into your final report**, structured as:

   - **Root cause** β€” one or two sentences, specific and causal.
   - **Evidence** β€” the quoted event/log/spec excerpts and which `gke_*` reads produced them.
   - **Proposed patch** β€” the YAML, ready for the parent to hand off.

Do **not** end with a bare status line like "diagnosed the issue" β€” a summary without the analysis leaves the parent with nothing to act on, and it will redo your work. If you could not determine the cause, say exactly that and report what you ruled out; a documented dead end is a real result, a confident guess is not.

The Platform Agent reads your report and decides whether to open or update a Pull Request via `submit-suggestion`; do not duplicate an existing PR.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.