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

Tor*_*ger 91 logging kubernetes google-kubernetes-engine

"kubectl logs"向我展示了一个Kubernetes容器的stderr/stdout.如何获取一组pod的聚合stderr/stdout,最好是由某个复制控制器创建的那些?

小智 121

你可以使用标签

kubectl logs -l app=elasticsearch
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,很可能足以回答原始问题,但它不会尾随:"错误:只允许跟随(-f)或选择器(-l)中的一个". (20认同)
  • 此外,没有`--all-namespaces`。 (4认同)
  • 可能想要使用 `-n <namespace> --tail=<lines>` (4认同)
  • 似乎现在可以使用-f(从Kubernetes 1.12+ /`kubectl` 1.12+开始)。还有@Shubham-它按接收到的顺序显示消息,日志行上没有标签或任何内容。这只是为了快速调试。如果您需要更多日志详细信息,则需要将日志发送到中央日志系统,例如EFK,SumoLogic,Datadog等。 (3认同)

Joh*_*han 60

我已经创建了一个小的bash脚本kubetail,这使得这成为可能.例如,要为名为"app1"的pod添加所有日志,您可以执行以下操作:

kubetail app1
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到这个脚本.

  • 这是一个非常酷的脚本,如果您问我,它应该是kubectl的一部分 (3认同)

小智 11

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

kubectl logs \
--namespace my-namespace \
-l app=my-app-label \
--tail=-1 \
--timestamps=true \
--prefix=true \
--all-containers=true
Run Code Online (Sandbox Code Playgroud)

此示例从 label 定义的 pod 中的所有容器返回完整的快照日志app=my-app-label

可选选项

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

按资源划分的日志

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

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

容器名称

根据输出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就需要加高。


小智 10

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

kubectl -n <namespace> logs -f deployment/<app-name> \
    --all-containers=true --since=10m
Run Code Online (Sandbox Code Playgroud)

  • 由于某种原因,此命令会提取随机 pod 的日志,但不会提取所有 pod 的日志。我已经改用标签 (4认同)
  • 如果它转储了数天的日志,那就太棒了,我想知道限制是什么? (2认同)

Mar*_*ark 9

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

#!/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
Run Code Online (Sandbox Code Playgroud)

脚本要点

用法:log_deployment.sh“部署名称”。

然后脚本将显示以该“部署名称”开头的所有 pod 的日志。

  • 您可以使用“kubectl get pods -o name”来输出 pod 名称,而无需使用“cut”。 (2认同)

Jea*_*tor 9

您可以使用Adrian Ng建议的标签从多个容器中获取日志:

kubectl logs --selector app=yourappname
Run Code Online (Sandbox Code Playgroud)

如果您的Pod中包含多个容器,则上述命令将失败,并且需要指定容器名称:

kubectl logs --selector app=yourappname --container yourcontainername
Run Code Online (Sandbox Code Playgroud)

注意:如果要查看可用的标签,以下命令将列出所有标签:

kubectl get pod <one of your pods> -o template --template='{{.metadata.labels}}'
Run Code Online (Sandbox Code Playgroud)

...输出看起来像

map [app:您的应用名称控制器-修订版哈希:598302898 pod-template-generation:1]

请注意,某些标签可能不会与其他Pod共享-选择“应用”似乎是最简单的标签


zim*_*mer 9

您可以kubectl logs -h根据信息获得帮助,

kubectl logs -f deployment/myapp -c myapp --tail 100
Run Code Online (Sandbox Code Playgroud)

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

kubectl logs -l app=myapp -c myapp --tail 100
Run Code Online (Sandbox Code Playgroud)

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

  • “但这将选择部署的一个 pod,而不是所有 pod”-&gt; true,我花了很多时间调试我的应用程序,然后才意识到并非所有日志都被显示。这在其他答案和官方文档中应该更加明确。 (3认同)

小智 7

先前提供的解决方案不是最佳的。kubernetes团队本身已经提供了一个称为stern的解决方案。

stern app1
Run Code Online (Sandbox Code Playgroud)

它还匹配正则表达式,并且默认情况下执行tail和-f(跟随)。一个不错的好处是,它还向您显示了生成日志的Pod。

app1-12381266dad-3233c foobar log
app1-99348234asd-959cc foobar log2
Run Code Online (Sandbox Code Playgroud)

为Linux抓取go-binary或通过brew为OSX安装。

https://kubernetes.io/blog/2016/10/tail-kubernetes-with-stern/

https://github.com/wercker/stern


小智 7

如果要添加上一个答案,则可以添加-f日志尾部。

kubectl logs -f deployment/app
Run Code Online (Sandbox Code Playgroud)

  • 当心!此命令仅选择一个 pod 来传输日志。它不会从副本集/部署中的所有 Pod 流式传输日志。 (32认同)
  • 但它仍然不会从运行此部署的所有 *pods* 记录,只会记录这些 pod 中的所有 *container*(通常每个 pod 只有一个容器,但每个部署有多个 pod) (6认同)
  • 最佳答案:kubectl日志-f--all-containers部署/应用程序 (2认同)

小智 6

您可以根据您的要求执行以下任一选项:

  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


小智 5

一种选择是通过Fluentd / ElasticSearch设置集群日志记录,如https://kubernetes.io/docs/user-guide/logging/elasticsearch/中所述。一旦日志进入ES,就可以轻松地在Kibana中应用过滤器以查看来自某些容器的日志。