kubectl logs from all pods of a Deployment at once
kubectl logs deployment/NAME reads one pod. On a Deployment with
6 replicas it printed that pod's lines, wrote Found 6 pods, using pod/… to stderr
and exited 0. --all-pods (kubectl 1.31 and later) or a label selector with
-l reads every pod and prints the lines pod by pod. With -f, kubectl
stops at five streams until you raise --max-log-requests.
By Ostgate · Updated
The test
We ran every command below on 10 November 2026 with kubectl client v1.35.0, against an
Autopilot cluster on GKE 1.36.4-gke.2377000. The Deployment t9-logs in namespace
ostgate-t ran 6 replicas of busybox:1.37, and each wrote the time,
its pod name and a counter every 2 seconds. The pods were about 30 seconds old at the first
command, 15:33Z.
replicas: 6
selector:
matchLabels: {app: t9-logs}
command: ["sh", "-c", "i=0; while true; do i=$((i+1)); echo \"$(date -u +%H:%M:%S) $HOSTNAME request $i\"; sleep 2; done"]
kubectl logs deployment/NAME reads one pod
kubectl -n ostgate-t logs deployment/t9-logs --tail=2
15:33:41 t9-logs-65cc449898-8bk9c request 11 15:33:43 t9-logs-65cc449898-8bk9c request 12
On stderr, one line:
Found 6 pods, using pod/t9-logs-65cc449898-8bk9c
The exit code was 0. A log piped into grep or saved to a file holds one replica
of six. kubectl port-forward to a
Service also settles on a single pod when it starts
(port-forward that survives pod restarts).
--all-pods: kubectl 1.31 and later
“Added flag to kubectl logs called --all-pods to get all pods from
a object that uses a pod selector” is the release note of
kubernetes#124732, merged
for v1.31. The flag “Sets prefix to true”
(kubectl logs
reference), so each line starts with [pod/POD/CONTAINER].
kubectl -n ostgate-t logs deployment/t9-logs --all-pods --tail=1 --prefix
[pod/t9-logs-65cc449898-8bk9c/app] 15:33:45 t9-logs-65cc449898-8bk9c request 13 [pod/t9-logs-65cc449898-dlhnp/app] 15:33:43 t9-logs-65cc449898-dlhnp request 12 [pod/t9-logs-65cc449898-2q6b5/app] 15:33:44 t9-logs-65cc449898-2q6b5 request 12 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:44 t9-logs-65cc449898-5wtcj request 12 [pod/t9-logs-65cc449898-6c8p5/app] 15:33:44 t9-logs-65cc449898-6c8p5 request 12 [pod/t9-logs-65cc449898-9gq8z/app] 15:33:44 t9-logs-65cc449898-9gq8z request 12
We passed --tail=1 here. The reference gives --tail a default of
“-1 with no selector, showing all log lines otherwise 10, if a selector is provided”, and we
didn't check which of the two --all-pods gets. On pods that have logged for a
week, set it yourself.
A label selector with -l
With an older kubectl, pass the labels from the Deployment's spec.selector. A
selector matches pods by label alone
(kubectl
logs reference), so a pod of another workload with the same labels is read as well.
kubectl -n ostgate-t logs -l app=t9-logs --prefix
[pod/t9-logs-65cc449898-5wtcj/app] 15:33:26 t9-logs-65cc449898-5wtcj request 3 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:28 t9-logs-65cc449898-5wtcj request 4 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:30 t9-logs-65cc449898-5wtcj request 5 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:32 t9-logs-65cc449898-5wtcj request 6 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:34 t9-logs-65cc449898-5wtcj request 7 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:36 t9-logs-65cc449898-5wtcj request 8 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:38 t9-logs-65cc449898-5wtcj request 9 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:40 t9-logs-65cc449898-5wtcj request 10
Those are the first 8 of 60 lines. With a selector and no --tail, kubectl
printed 10 lines per pod, and each pod's 10 came as one block before the next pod's.
For pods with sidecars, --all-containers reads every container (“Get all
containers' logs in the pod(s).”). Our pods had one container each, so we didn't see how
extra containers count toward --max-log-requests.
Follow more than five pods with -f
kubectl -n ostgate-t logs -l app=t9-logs --tail=1 --prefix -f --request-timeout=5s
error: you are attempting to follow 6 log streams, but maximum allowed concurrency is 5, use --max-log-requests to increase the limit
Exit 1 and no log lines. The reference describes --max-log-requests as the
“maximum number of concurrent logs to follow when using by a selector” and adds “Defaults to
5.”, yet deployment/t9-logs --all-pods --tail=1 -f, with no -l,
stopped with the same error. Set the limit to the pod count or higher:
kubectl -n ostgate-t logs -l app=t9-logs --tail=1 --prefix -f --max-log-requests=6 --request-timeout=4s
[pod/t9-logs-65cc449898-9gq8z/app] 15:33:46 t9-logs-65cc449898-9gq8z request 13 [pod/t9-logs-65cc449898-6c8p5/app] 15:33:46 t9-logs-65cc449898-6c8p5 request 13 [pod/t9-logs-65cc449898-8bk9c/app] 15:33:47 t9-logs-65cc449898-8bk9c request 14 [pod/t9-logs-65cc449898-dlhnp/app] 15:33:47 t9-logs-65cc449898-dlhnp request 14 [pod/t9-logs-65cc449898-5wtcj/app] 15:33:46 t9-logs-65cc449898-5wtcj request 13 [pod/t9-logs-65cc449898-2q6b5/app] 15:33:46 t9-logs-65cc449898-2q6b5 request 13 [pod/t9-logs-65cc449898-2q6b5/app] 15:33:48 t9-logs-65cc449898-2q6b5 request 14 [pod/t9-logs-65cc449898-9gq8z/app] 15:33:48 t9-logs-65cc449898-9gq8z request 14
All six pods streamed, in no time order (8 of the 18 lines are shown). We put --request-timeout on these
commands only to end the test, and it's why this run exited 1 with
error: net/http: request canceled (Client.Timeout or context cancellation while reading
body).
How Ostgate does it
On six pods of the same Deployment the pod menu read “5 of 6 pods”. We copied the tab once the 500-line tails and some live lines were in: 2,856 lines, 571 or 572 from each of the five followed pods, and no two consecutive lines from the same pod. One line was 3 ms older than the line above it, where the tails met the live stream.
Logs (All Pods) in the inspector of a Deployment, StatefulSet, DaemonSet or Job, or
Show Logs (All Pods) in its row menu, opens one tab for the workload. Ostgate finds the
pods by owner, a Deployment's through its ReplicaSets, so a pod that only shares the labels
stays out, and during a rollout the pods of an older ReplicaSet are marked “old”. Each pod's
stream starts with its last 500 lines. The tab places every line by its full timestamp,
nanoseconds included, and after the time comes a pod column: the part of the pod's name after
the workload's, such as 65cc449898-8bk9c, in a colour of its own.
Ostgate follows at most five pods at once, the same default as
--max-log-requests. With more, it follows the five newest, the pod menu shows
the count, and its Follow items change which five. A pod that starts later joins the tab, and
one that goes away keeps its lines, greyed.
Symptoms and causes
| You see | Cause | Fix |
|---|---|---|
One pod's lines and Found 6 pods, using pod/… on stderr |
deployment/NAME resolves to one pod |
Add --all-pods, or use -l |
kubectl doesn't know --all-pods |
kubectl older than 1.31 | -l with the Deployment's selector labels |
maximum allowed concurrency is 5 on -f |
-f over more than 5 pods, with -l or --all-pods |
--max-log-requests at or above the pod count |
| 10 lines per pod | --tail defaults to 10 with a selector |
--tail with the number you want |
Each pod's lines in one block, or out of time order with -f |
kubectl doesn't sort lines across pods | --timestamps to compare the times |
| Lines from a pod of another workload | Its labels match the selector | A narrower -l |
Questions
How do I get logs from all pods of a Deployment with kubectl?
kubectl logs deployment/NAME --all-pods, in kubectl 1.31 and later, reads every pod the Deployment's selector matches and prefixes each line with the pod and container. With an older kubectl, pass the Deployment's labels: kubectl logs -l app=NAME --prefix. Plain kubectl logs deployment/NAME reads one pod, names it on stderr (Found 6 pods, using pod/t9-logs-65cc449898-8bk9c in our test) and exits 0.
Why does kubectl logs -f fail with “maximum allowed concurrency is 5”?
kubectl follows at most 5 log streams unless --max-log-requests sets a higher number. Following 6 pods failed with “error: you are attempting to follow 6 log streams, but maximum allowed concurrency is 5, use --max-log-requests to increase the limit”, both with -l app=t9-logs and with deployment/t9-logs --all-pods. With --max-log-requests=6 all six pods streamed.
Why does kubectl logs -l show only 10 lines per pod?
With a selector, --tail defaults to 10 lines per pod; without one it defaults to all lines. Pass --tail with the number of lines you want. In our test kubectl logs -l app=t9-logs --prefix printed 60 lines for 6 pods.
Does kubectl merge logs from several pods in time order?
It didn't in our test. Without -f, kubectl logs -l printed each pod's lines as one block, pod after pod. With -f, one pod's 15:33:46 line came after two lines stamped 15:33:47. --timestamps adds the time to each line, so you can at least compare them.
Ostgate runs on Apple Silicon Macs with macOS 15 or later, with a 7-day trial and no sign-up. The Logs tabs are described in the GKE docs, and GKE on a Mac lists what the GKE area does.