Running kubectl logs
shows me the stderr/stdout of one Kubernetes container.
How can I get the aggregated stderr/stdout of a set of pods, preferably those created by a certain replication controller?
This question is related to
logging
kubernetes
google-kubernetes-engine
Not sure if this is a new thing, but with deployments it is possible to do it like this:
kubectl logs deployment/app1
You can get the logs from multiple containers using labels as Adrian Ng suggested:
kubectl logs --selector app=yourappname
In case you have a pod with multiple containers, the above command is going to fail and you'll need to specify the container name:
kubectl logs --selector app=yourappname --container yourcontainername
Note: If you want to see which labels are available to you, the following command will list them all:
kubectl get pod <one of your pods> -o template --template='{{.metadata.labels}}'
...where the output will look something like
map[app:yourappname controller-revision-hash:598302898 pod-template-generation:1]
Note that some of the labels may not be shared by other pods - picking "app" seems like the easiest one
Worked for me:
kubectl logs -n namespace -l app=label -c container
You can also do this by service name.
First, try to find the service name of the respective pod which corresponds to multiple pods of the same service. kubectl get svc
.
Next, run the following command to display logs from each container.
kubectl logs -f service/<service-name>
I use this command.
kubectl -n <namespace> logs -f deployment/<app-name> --all-containers=true --since=10m
One option is to set up cluster logging via Fluentd/ElasticSearch as described at https://kubernetes.io/docs/user-guide/logging/elasticsearch/. Once logs are in ES, it's easy to apply filters in Kibana to view logs from certain containers.
In this example, you can replace the <namespace>
and <app-name>
to get the logs when there are multiple Containers defined in a Pod.
kubectl -n <namespace> logs -f deployment/<app-name> \
--all-containers=true --since=10m
Previously provided solutions are not that optimal. The kubernetes team itself has provided a solution a while ago, called stern.
stern app1
It is also matching regular expressions and does tail and -f (follow) by default. A nice benefit is, that it shows you the pod which generated the log as well.
app1-12381266dad-3233c foobar log
app1-99348234asd-959cc foobar log2
Grab the go-binary for linux or install via brew for OSX.
https://kubernetes.io/blog/2016/10/tail-kubernetes-with-stern/
You can get help from kubectl logs -h
and according the info,
kubectl logs -f deployment/myapp -c myapp --tail 100
-c
is the container name and --tail
will show the latest num lines,but this will choose one pod of the deployment, not all pods. This is something you have to bear in mind.
kubectl logs -l app=myapp -c myapp --tail 100
If you want to show logs of all pods, you can use -l
and specify a lable, but at the same time -f
won't be used.
Another solution that I would consider is using K9S which is a great kube administration tool.
After installation, the usage is very straightforward:
k9s -n my-namespace --context the_context_name_in_kubeconfig
(If kubeconfig is not in the default location add KUBECONFIG=path/to/kubeconfig
prefix).
The default view will list all pods as a list:
We can change the view to other Kube controllers like replica set (question asked for replication controllers so notice they are deprecated), deployments, cron jobs, etc' by entering a colon :
and start typing the desired controller - as we can see K9S provides autocompletion for us:
And we can see all replica sets in the current namespace:
We can just choose the desired replica set by clicking enter and then we'll see the list of all pods which are related to this replica set - we can then press on 'l' to view logs of each pod.
So, unlike in the case of stern, we still need to go on each pod and view its logs but I think it is very convenient with K9S - we first view all pods of a related controller and then investigate logs of each pod by simply navigating with enter
, l
and escape
.
To build on the previous answer if you add -f
you can tail the logs.
kubectl logs -f deployment/app
I use this simple script to get a log from the pods of a deployment:
#!/usr/bin/env bash
DEPLOYMENT=$1
for p in $(kubectl get pods | grep ^${DEPLOYMENT}- | cut -f 1 -d ' '); do
echo ---------------------------
echo $p
echo ---------------------------
kubectl logs $p
done
Usage: log_deployment.sh "deployment-name".
Script will then show log of all pods that start with that "deployment-name".
I've created a small bash script called kubetail
that makes this possible. For example to tail all logs for pods named "app1" you can do:
kubetail app1
You can find the script here.
If the pods are named meaningfully one could use simple Plain Old Bash:
keyword=nodejs
command="cat <("
for line in $(kubectl get pods | \
grep $keyword | grep Running | awk '{print $1}'); do
command="$command (kubectl logs --tail=2 -f $line &) && "
done
command="$command echo)"
eval $command
Explanation: Loop through running pods with name containing "nodejs". Tail the log for each of them in parallel (single ampersand runs in background) ensuring that if any of the pods fail the whole command exits (double ampersand). Cat the streams from each of the tail commands into a unique stream. Eval is needed to run this dynamically built command.
Source: Stackoverflow.com