Kubernetes
kubectl
CURL
command-line
DevOps

Execute CURL with kubectl

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

kubectl does not run HTTP requests by itself, but it can start a process inside a pod that does. In practice, that means you either execute curl in an existing container or launch a short-lived troubleshooting pod that already contains the tool.

Running curl Inside an Existing Pod

The most direct approach is kubectl exec. This works when the target container already has curl installed.

bash
1kubectl get pods -n payments
2
3kubectl exec -n payments -it api-7c89d9f7f7-9x2lm -- \
4  curl -sS http://localhost:8080/healthz

That command does three things:

  • It connects to the pod over the Kubernetes API.
  • It starts curl inside the container process namespace.
  • It sends the request from the pod's network location, not from your laptop.

If the pod has more than one container, add -c to choose the right one:

bash
kubectl exec -n payments -it api-7c89d9f7f7-9x2lm -c app -- \
  curl -sS http://localhost:8080/ready

This is especially useful for checking endpoints that only listen on localhost, because traffic originates inside the same container.

Starting a Temporary Debug Pod

Many production images are intentionally minimal and do not include curl. In that case, spin up a disposable pod with a debugging image.

bash
1kubectl run curl-debug \
2  -n payments \
3  --rm -it \
4  --restart=Never \
5  --image=curlimages/curl:8.7.1 -- sh

Once the shell opens, you can query cluster services:

bash
curl -sS http://api.payments.svc.cluster.local:8080/healthz
curl -sS http://api:8080/metrics | head

Using a temporary pod is cleaner than modifying an application image just to add troubleshooting tools. It also lets you test service discovery, DNS, and network policies from the same namespace as the workload.

Calling Services, Pods, and External Endpoints

Inside a cluster, curl can target several kinds of addresses:

  • Pod-local endpoints such as http://localhost:8080
  • Service names such as http://api:8080
  • Fully qualified service DNS names such as http://api.payments.svc.cluster.local:8080
  • Public URLs if egress is allowed

For authenticated APIs, include headers the same way you would on any Linux shell:

bash
1TOKEN="$(kubectl get secret api-token -n payments -o jsonpath='{.data.token}' | base64 --decode)"
2
3kubectl exec -n payments deploy/api -c app -- \
4  curl -sS \
5    -H "Authorization: Bearer ${TOKEN}" \
6    -H "Accept: application/json" \
7    http://localhost:8080/v1/orders

A common debugging pattern is to hit a service from another namespace to confirm routing and RBAC assumptions:

bash
1kubectl run netcheck \
2  -n reporting \
3  --rm -it \
4  --restart=Never \
5  --image=curlimages/curl:8.7.1 -- \
6  curl -sS http://api.payments.svc.cluster.local:8080/healthz

If that request fails while the same service works from the payments namespace, the problem is often a network policy or a namespace-scoped DNS assumption.

Useful Flags When Debugging

curl becomes much more informative with a few extra flags:

bash
kubectl exec -n payments deploy/api -c app -- \
  curl -v --connect-timeout 3 --max-time 10 http://localhost:8080/healthz
  • '-v prints request and response details'
  • '--connect-timeout limits how long the TCP connect phase can hang'
  • '--max-time prevents a stuck request from blocking your terminal'
  • '-k can bypass certificate validation for temporary HTTPS debugging, though it should not be your default'

For JSON APIs, pairing curl with jq is often helpful, but remember that both tools must exist inside the container if you are using kubectl exec.

Port-forwarding is a different tool

If the real goal is to run curl from your laptop against an in-cluster service, kubectl port-forward may be simpler than executing curl inside a pod. That approach tests a different network path, though, so it should not be confused with in-cluster connectivity debugging.

Common Pitfalls

The most common mistake is assuming kubectl exec gives you the pod network but still uses tools from your local machine. It does not. The command runs inside the container, so missing binaries such as curl or sh will cause errors immediately.

Another frequent issue is forgetting the namespace. A service name like api resolves only within the current namespace unless you use the full service DNS name. Multi-container pods are another source of confusion, because kubectl exec may default to the wrong container if you omit -c.

Finally, do not treat troubleshooting pods as permanent infrastructure. Use --rm and --restart=Never so the pod disappears after the session, otherwise these helpers tend to accumulate and make operational cleanup harder.

Summary

  • Use kubectl exec when the target container already has curl.
  • Use kubectl run --rm -it --image=curlimages/curl when the application image is minimal.
  • Prefer service DNS names when you want to test Kubernetes networking instead of pod-local behavior.
  • Add -c for multi-container pods and -n for the correct namespace.
  • Use verbose and timeout flags to turn a hanging request into a useful diagnostic signal.

Course illustration
Course illustration

All Rights Reserved.