如何从Kubernetes复制控制器的所有pod中获取日志?

运行kubectl logs显示了一个Kubernetes容器的stderr/stdout。

我如何获得一组pod的聚合stderr/stdout,最好是由某个复制控制器创建的那些?

218431 次浏览

一种选择是通过Fluentd/ElasticSearch设置集群日志记录,如https://kubernetes.io/docs/user-guide/logging/elasticsearch/所述。一旦日志在ES中,就很容易在Kibana中应用过滤器来查看特定容器中的日志。

我已经创建了一个名为kubetail的小bash脚本,使这成为可能。例如,跟踪名为“app1”的pod的所有日志,你可以这样做:

kubetail app1

你可以找到脚本在这里

我使用这个简单的脚本从部署的pods中获取日志:

#!/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

脚本的要点 . b

使用方法:log_deploy .sh "deploy -name"。

然后脚本将显示所有以“deployment-name”开头的pod的日志。

你可以使用标签

kubectl logs -l app=elasticsearch

你可能想要指定--all-containers --ignore-errors,以便:

  • 包括来自多个容器的吊舱的日志
  • 在致命错误(例如,无法检索日志)时继续到下一个pod

如果豆荚的命名有意义,可以使用简单的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

说明:循环运行名称包含“nodejs”的pod。并行跟踪每个pod的日志(单&号在后台运行),确保如果任何pod失败,整个命令都退出(双&号)。将来自每个tail命令的流合并到一个唯一的流中。Eval需要运行这个动态构建的命令。

不确定这是否是一个新事物,但随着部署,可以这样做:

kubectl logs deployment/app1

你可以像Adrian Ng建议的那样,使用标签从多个容器中获取日志:

kubectl logs --selector app=yourappname

但是如果你有一个包含多个容器的pod,上面的命令将会失败,你需要指定容器名称:

kubectl logs --selector app=yourappname --container yourcontainername

注意:如果你想查看哪些标签是可用的,下面的命令将列出所有标签:

kubectl get pod <one of your pods> -o template --template='\{\{.metadata.labels}}'

...输出会是这样的

映射[app:yourappname controller-revision-hash:598302898 pod-template-generation:1]

注意,有些标签可能不会被其他pod共享- pick "app"似乎是最简单的一个

以前提供的解决方案并不是最优的。kubernetes团队自己在一段时间前提供了一个解决方案,称为stern。

stern app1

它还匹配正则表达式,默认情况下执行tail和-f (follow)。一个很好的好处是,它显示了生成日志的pod。

app1-12381266dad-3233c foobar log
app1-99348234asd-959cc foobar log2

抓取go-binary for linux或通过brew for OSX安装。

< a href = " https://kubernetes。io /博客/ 2016/10 / tail-kubernetes-with-stern / noreferrer“rel = > https://kubernetes.io/blog/2016/10/tail-kubernetes-with-stern/ < / >

https://github.com/wercker/stern

在前面的答案的基础上,如果你添加-f,你可以跟踪日志。

kubectl logs -f deployment/app

你可以从kubectl logs -h中获得帮助,根据信息,

kubectl logs -f deployment/myapp -c myapp --tail 100

-c是容器名称,--tail将显示最新的num行,但这将选择部署的一个pod,而不是所有pod。这是你必须记住的。

kubectl logs -l app=myapp -c myapp --tail 100

如果你想显示所有pod的日志,你可以使用-l并指定一个标签,但同时不会使用-f

在这个例子中,当一个Pod中定义了多个容器时,你可以替换<namespace><app-name>来获取日志。

kubectl -n <namespace> logs -f deployment/<app-name> \
--all-containers=true --since=10m

您也可以通过服务名称来完成此操作。

首先,尝试找到对应于相同服务的多个pod的各自pod的服务名称。kubectl get svc

接下来,运行以下命令显示每个容器的日志。

kubectl logs -f service/<service-name>

我使用这个命令。

kubectl -n <namespace> logs -f deployment/<app-name> --all-containers=true --since=10m

我考虑的另一个解决方案是使用k9,这是一个很棒的kube管理工具。

安装后使用非常简单明了:

 k9s -n my-namespace --context the_context_name_in_kubeconfig

(如果kubecconfig不在默认位置,则添加KUBECONFIG=path/to/kubeconfig前缀)。

默认视图将列出所有pod列表:

enter image description here

我们可以将视图更改为其他Kube控制器,如副本集(关于复制控制器的问题,请注意它们已弃用),部署,cron作业等,通过输入:并开始输入所需的控制器-正如我们可以看到K9S为我们提供了自动补全:

enter image description here

我们可以看到当前命名空间中的所有副本集:

enter image description here

我们可以通过单击enter选择所需的副本集,然后我们将看到与此副本集相关的所有pod的列表-然后我们可以按“l”查看日志每个pod。

因此,与斯特恩的情况不同,我们仍然需要在每个pod上查看其日志,但我认为用K9S非常方便-我们首先查看相关控制器的所有pod,然后通过简单地导航enterlescape来调查每个pod的日志。

对我有用:

Kubectl logs -n namespace -l app=label -c container

@johan的回答让我想到了一句话:

for i in $(kubectl get pods -n default |cut -d" " -f1); do kubectl logs $i -n default; done

您可以根据需要选择以下两种方式:

  1. kubectl -n my_namespace logs deployment/my_deployment --all-containers=true --since 10m
  2. for i in $(kubectl get pods -n "my_namespace" | sed 1d | cut -d" " -f1); do kubectl logs $i -n "my_namespace" "app_name" | grep -i "filter_string you want to" ; done

这个回答试图提供一个简洁的例子和解释。为了获得一组pod中所有容器的所有输出,您必须使用标签(选择器),除非您计划执行一些额外的脚本。

kubectl logs \
--namespace my-namespace \
-l app=my-app-label \
--tail=-1 \
--timestamps=true \
--prefix=true \
--all-containers=true

这个例子返回标签app=my-app-label定义的pods中所有容器的完整快照日志。

可选选项

添加--timestamps=true--prefix=true标志可能会有帮助,这样时间戳和日志源在输出中可见,但这不是必需的。

按资源划分的日志

如果指定了一个资源,例如部署,并且该部署具有 多个pod(如ReplicaSet),则只返回其中一个pod日志。这就是为什么要使用选择器来标识pod

尽管指定了--all-containers,但在编写此响应时,使用kubectl v1.22.5针对服务或部署等资源不会成功返回所有pod中所有容器的日志。这就是必须使用选择器的原因。

容器名称

根据kubectl logs --help的输出

打印pod中容器或指定资源的日志。 如果pod只有一个容器,容器名是可选的

这意味着如果有多个容器,您必须执行以下操作之一:

  • 让命令为您选择一个容器
  • 使用--all-containers=true选项

跟踪和拖尾

如果你像上面的例子一样指定一个标签,那么tail将被设置为10,只返回每个容器的最后10个日志。要获取所有日志,将tail设置为-1

在示例中添加-f--follow以跟踪日志。如果你不需要所有的日志,改变--tail选项的值。在跟踪日志时,您可能希望确保默认选项--max-log-requests=5是足够的。如果有20个容器,则需要--max-log-requests=20

我们刚刚推出了一个Kubernetes本地日志工具,可以从所有的pod(你指定的)收集日志,并将日志发送到一个集中的位置。

我希望它能帮助任何人登陆本页:https://github.com/parseablehq/collector