---
title: Troubleshooting Kubernetes
url: https://www.tines.com/docs/self-hosted/troubleshooting/troubleshooting-kubernetes/
updated: 2026-07-10T14:12:08+00:00
---

*[tines.com](https://www.tines.com/llms.txt) › [Docs](https://www.tines.com/docs/llms.txt) › [Self-Hosted](https://www.tines.com/llm/docs/self-hosted.md) › [Troubleshooting](https://www.tines.com/llm/docs/self-hosted/troubleshooting.md)*

# Troubleshooting Kubernetes

*[View on tines.com](https://www.tines.com/docs/self-hosted/troubleshooting/troubleshooting-kubernetes/)*

We provide a read-only script `k8s-diagnostics-collector.sh` that collects Kubernetes logs, events, and API objects from a single namespace. It packages everything into a `.tar.gz` bundle you can send to Tines support to help diagnose issues with your deployment (for example pods that restart, crash, or fail health checks).

The bundle includes kubectl context and version information, pod status, resource usage, namespace events, container logs, and namespaced Kubernetes objects. Secrets and ConfigMaps are excluded because they may contain credentials or sensitive configuration.

When you contact support, include:

- **Tines version** — the Helm chart version and/or application version you have deployed
- **Kubernetes platform** — where the cluster runs, for example Google Kubernetes Engine (GKE), Amazon EKS, Microsoft Azure Kubernetes Service (AKS), or another distribution

Review the bundle and **remove sensitive information** before sending it to support. Container logs and exported objects may contain sensitive data you do not want to share. Pay close attention to app secrets, passwords, and tokens.

## Quickstart

You need `kubectl` configured for the target cluster. Install it from the [Kubernetes documentation](https://kubernetes.io/docs/tasks/tools/) if it is not already on your PATH.

Download the script, make it executable, and run it against your Tines namespace:

```bash
curl -fsSL -O https://assets.sh.tines.com/collectors/k8s/k8s-diagnostics-collector.sh
chmod +x k8s-diagnostics-collector.sh
./k8s-diagnostics-collector.sh --namespace your-tines-namespace
```

The script prints the current kubectl context and asks you to confirm before collecting any data. When it finishes, it creates an archive named `k8s-namespace-debug-<namespace>-<timestamp>.tar.gz`.

Send that archive to your Tines support contact after reviewing its contents and removing anything sensitive.

---

## Manual collection

This section walks through the same read-only diagnostic collection performed by `k8s-diagnostics-collector.sh`, but as individual commands you can run yourself. Use this when you prefer not to run the script, need to collect only part of the bundle, or want to inspect output as you go.

The automated script is equivalent to running every section below in order and packaging the result into a `.tar.gz` archive.

## What is collected

- Current kubectl context and client/server version
- Pod status for all pods in the namespace
- Current CPU and memory usage for all pods (`kubectl top`; requires metrics-server)
- Namespace events (probe failures, OOMKills, scheduling, and so on)
- Container logs for every pod (current and previous for regular containers; current for init containers)
- All namespaced Kubernetes API objects **except Secrets and ConfigMaps**

## What is not collected

- Secrets (may contain credentials)
- ConfigMaps (may contain sensitive application configuration)
- Cluster-wide resources outside the target namespace
- Historical metrics or live profiling data

## Prerequisites

- `kubectl` installed and configured for the target cluster
- Permission to read pods, logs, events, and other namespace resources in the target namespace
- `bash`, `date`, `mkdir`, `tar`, and standard Unix utilities on your PATH

---

## 1. Set environment variables

Define these once at the start of your shell session. Every section below reuses them.

```bash
# Required: namespace to collect from
NAMESPACE="your-namespace"

# Optional: max log lines per container (default in the script is 5000)
LOG_TAIL=5000

# Output directory and archive names (timestamp keeps each run unique)
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
OUT_DIR="k8s-namespace-debug-${NAMESPACE}-${TIMESTAMP}"
ARCHIVE="${OUT_DIR}.tar.gz"
```

---

## 2. Confirm kubectl context

**Purpose:** Verify you are connected to the intended cluster before collecting any data.

```bash
kubectl config current-context
```

Review the output. Switch context if needed:

```bash
kubectl config use-context <context-name>
```

Optionally store the context name for your records:

```bash
CONTEXT="$(kubectl config current-context)"
echo "Using context: ${CONTEXT}"
```

---

## 3. Verify the namespace exists

**Purpose:** Fail fast if the namespace name is wrong or you lack access.

```bash
kubectl get namespace "${NAMESPACE}"
```

---

## 4. Create the output directory

**Purpose:** Prepare the folder layout used by the script (`logs/` and `objects/` subdirectories).

```bash
mkdir -p "${OUT_DIR}/logs" "${OUT_DIR}/objects"
```

---

## 5. Write collection metadata

**Purpose:** Record when the bundle was collected and which options were used.

```bash
{
  echo "collected_at=${TIMESTAMP}"
  echo "namespace=${NAMESPACE}"
  echo "log_tail=${LOG_TAIL}"
} > "${OUT_DIR}/metadata.txt"
```

---

## 6. Save kubectl context

**Purpose:** Capture which cluster/context the data came from.

**Command:** `kubectl config current-context`

**Output file:** `${OUT_DIR}/context.txt`

```bash
kubectl config current-context > "${OUT_DIR}/context.txt" 2>&1
```

---

## 7. Save kubectl client and server version

**Purpose:** Document kubectl and API server versions for compatibility troubleshooting.

**Command:** `kubectl version --output=yaml`

**Output file:** `${OUT_DIR}/kubectl-version.yaml`

```bash
kubectl version --output=yaml > "${OUT_DIR}/kubectl-version.yaml" 2>&1
```

---

## 8. Save pod status

**Purpose:** Snapshot pod names, phases, nodes, restart counts, and IP addresses.

**Command:** `kubectl get pods -o wide`

**Output file:** `${OUT_DIR}/pods.txt`

```bash
kubectl -n "${NAMESPACE}" get pods -o wide > "${OUT_DIR}/pods.txt" 2>&1
```

---

## 9. Save pod resource usage

**Purpose:** Capture current CPU and memory usage for every pod in the namespace. Requires metrics-server in the cluster; the command fails harmlessly if it is not installed.

**Command:** `kubectl top pods`

**Output file:** `${OUT_DIR}/pods-top.txt`

```bash
kubectl -n "${NAMESPACE}" top pods > "${OUT_DIR}/pods-top.txt" 2>&1
```

---

## 10. Save namespace events

**Purpose:** Collect scheduling, probe failure, OOMKill, and other cluster events for the namespace, ordered by time.

**Command:** `kubectl get events --sort-by=.lastTimestamp`

**Output file:** `${OUT_DIR}/events.txt`

```bash
kubectl -n "${NAMESPACE}" get events --sort-by=.lastTimestamp \
  > "${OUT_DIR}/events.txt" 2>&1
```

---

## 11. Save namespace API objects (excluding Secrets and ConfigMaps)

**Purpose:** Export YAML for every namespaced resource type the API exposes, except Secrets and ConfigMaps.

**Command:** For each namespaced resource type, `kubectl get <resource> -o yaml`

**Output directory:** `${OUT_DIR}/objects/` (one file per resource type)

```bash
for RESOURCE in $(kubectl api-resources --namespaced=true --verbs=list -o name); do
  case "${RESOURCE}" in
    secrets|configmaps)
      continue
      ;;
  esac
  SAFE_NAME="${RESOURCE//\//_}"
  echo "Collecting ${RESOURCE} -> objects/${SAFE_NAME}.yaml"
  kubectl -n "${NAMESPACE}" get "${RESOURCE}" -o yaml \
    > "${OUT_DIR}/objects/${SAFE_NAME}.yaml" 2>&1
done
```

To collect a single resource type instead of everything, run one command directly. Example for Deployments:

```bash
kubectl -n "${NAMESPACE}" get deployments.apps -o yaml \
  > "${OUT_DIR}/objects/deployments.apps.yaml" 2>&1
```

---

## 12. Save container logs

**Purpose:** Capture application output from every pod. Regular containers get both current logs and previous (crashed) logs; init containers get current logs only. Each file is capped at `${LOG_TAIL}` lines.

### 12a. Regular containers — current logs

**Command:** `kubectl logs <pod> -c <container> --tail=<lines>`

**Output file pattern:** `${OUT_DIR}/logs/<pod>__<container>__current.log`

```bash
for pod in $(kubectl -n "${NAMESPACE}" get pods -o name); do
  POD="${pod#pod/}"
  for CONTAINER in $(kubectl -n "${NAMESPACE}" get pod "${POD}" \
    -o jsonpath='{.spec.containers[*].name}'); do
    kubectl -n "${NAMESPACE}" logs "${POD}" -c "${CONTAINER}" \
      --tail="${LOG_TAIL}" \
      > "${OUT_DIR}/logs/${POD}__${CONTAINER}__current.log" 2>&1
  done
done
```

### 12b. Regular containers — previous (crashed) logs

**Command:** `kubectl logs <pod> -c <container> --previous --tail=<lines>`

**Output file pattern:** `${OUT_DIR}/logs/<pod>__<container>__previous.log`

No previous log exists if the container has never restarted; that command will fail harmlessly for those containers.

```bash
for pod in $(kubectl -n "${NAMESPACE}" get pods -o name); do
  POD="${pod#pod/}"
  for CONTAINER in $(kubectl -n "${NAMESPACE}" get pod "${POD}" \
    -o jsonpath='{.spec.containers[*].name}'); do
    kubectl -n "${NAMESPACE}" logs "${POD}" -c "${CONTAINER}" --previous \
      --tail="${LOG_TAIL}" \
      > "${OUT_DIR}/logs/${POD}__${CONTAINER}__previous.log" 2>&1
  done
done
```

### 12c. Init containers — current logs

**Command:** `kubectl logs <pod> -c <init-container> --tail=<lines>`

**Output file pattern:** `${OUT_DIR}/logs/<pod>__init-<init-container>__current.log`

```bash
for pod in $(kubectl -n "${NAMESPACE}" get pods -o name); do
  POD="${pod#pod/}"
  for INIT_CONTAINER in $(kubectl -n "${NAMESPACE}" get pod "${POD}" \
    -o jsonpath='{.spec.initContainers[*].name}'); do
    kubectl -n "${NAMESPACE}" logs "${POD}" -c "${INIT_CONTAINER}" \
      --tail="${LOG_TAIL}" \
      > "${OUT_DIR}/logs/${POD}__init-${INIT_CONTAINER}__current.log" 2>&1
  done
done
```

### 12d. Single pod or container

To collect logs for one pod only, set `POD` and run the relevant command directly:

```bash
POD="my-pod-name"
CONTAINER="my-container"

kubectl -n "${NAMESPACE}" logs "${POD}" -c "${CONTAINER}" \
  --tail="${LOG_TAIL}" \
  > "${OUT_DIR}/logs/${POD}__${CONTAINER}__current.log" 2>&1
```

---

## 13. Create the archive

**Purpose:** Package the output directory into a single file for sharing with support, matching the script's deliverable.

**Command:** `tar -czf`

**Output file:** `${ARCHIVE}`

```bash
tar -czf "${ARCHIVE}" "${OUT_DIR}"
echo "Created archive: ${ARCHIVE}"
```

---

## Before sharing

Container logs and exported objects may contain sensitive application data. Review the contents of `${OUT_DIR}` or `${ARCHIVE}` and remove anything you do not want to share before sending the bundle to Tines support.

When you open a support request, include your **Tines version** (Helm chart and/or application version) and **Kubernetes platform** (for example GKE, EKS, or AKS).
