如何从 Kubernetes 复制控制器的所有 pods 获取日志?
How do I get logs from all pods of a Kubernetes replication controller?
运行 kubectl logs
向我展示了一个 Kubernetes 容器的 stderr/stdout。
如何获得一组 pods 的聚合 stderr/stdout,最好是由某个复制控制器创建的那些?
一种选择是通过 Fluentd/ElasticSearch 设置集群日志记录,如 https://kubernetes.io/docs/user-guide/logging/elasticsearch/ 中所述。一旦日志在 ES 中,就可以很容易地在 Kibana 中应用过滤器来查看来自特定容器的日志。
我创建了一个名为 kubetail
的小 bash 脚本,使这成为可能。例如,要跟踪名为 "app1" 的 pods 的所有日志,您可以执行以下操作:
kubetail app1
您可以找到脚本 here。
我使用这个简单的脚本从部署的 pods 中获取日志:
#!/usr/bin/env bash
DEPLOYMENT=
for p in $(kubectl get pods | grep ^${DEPLOYMENT}- | cut -f 1 -d ' '); do
echo ---------------------------
echo $p
echo ---------------------------
kubectl logs $p
done
用法:log_deployment.sh "deployment-name".
脚本随后将显示以 "deployment-name".
开头的所有 pods 的日志
您可以使用标签
kubectl logs -l app=elasticsearch
您可能想要指定 --all-containers --ignore-errors
以便:
- 包含来自 pods 的多个容器的日志
- 出现致命错误时继续下一个 pod(例如,无法检索日志)
如果 pods 的命名有意义,可以使用简单的 Plain Old Bash:
keyword=nodejs
command="cat <("
for line in $(kubectl get pods | \
grep $keyword | grep Running | awk '{print }'); do
command="$command (kubectl logs --tail=2 -f $line &) && "
done
command="$command echo)"
eval $command
解释:循环遍历 运行ning pods,名称包含 "nodejs"。并行跟踪它们中的每一个的日志(背景中的单符号 运行s)确保如果任何 pods 失败,整个命令退出(双符号)。将来自每个尾部命令的流分类为一个唯一的流。 运行 这个动态构建的命令需要 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}}'
...输出类似于
map[app:yourappname controller-revision-hash:598302898 pod-template-generation:1]
请注意,某些标签可能不会被其他 pods 共享 - 选择 "app" 似乎是最简单的
之前提供的解决方案并不是最优的。 kubernetes团队自己前段时间也提供了一个解决方案,叫stern。
stern app1
它也匹配正则表达式,默认执行 tail 和 -f(跟随)。一个很好的好处是,它还会向您显示生成日志的 pod。
app1-12381266dad-3233c foobar log
app1-99348234asd-959cc foobar log2
为 linux 获取 go-binary 或为 OSX 通过 brew 安装。
https://kubernetes.io/blog/2016/10/tail-kubernetes-with-stern/
如果您添加 -f
可以在之前的答案的基础上添加日志。
kubectl logs -f deployment/app
你可以从kubectl logs -h
那里得到帮助,根据信息,
kubectl logs -f deployment/myapp -c myapp --tail 100
-c
是容器名称,--tail
会显示最新的num行,但是这样会选择一个部署的pod,而不是全部pods。这是你必须牢记的。
kubectl logs -l app=myapp -c myapp --tail 100
如果要显示所有pods的日志,可以使用-l
并指定一个标签,但同时-f
不会被使用。
在这个例子中,当一个Pod中定义了多个容器时,您可以替换<namespace>
和<app-name>
来获取日志。
kubectl -n <namespace> logs -f deployment/<app-name> \
--all-containers=true --since=10m
您也可以通过服务名称执行此操作。
首先尝试找到对应多个pods同一个服务的各个pod的服务名。 kubectl get svc
.
接下来,运行以下命令显示每个容器的日志。
kubectl logs -f service/<service-name>
我用这个命令。
kubectl -n <namespace> logs -f deployment/<app-name> --all-containers=true --since=10m
我会考虑的另一个解决方案是使用 K9S,这是一个很棒的 kube 管理工具。
安装后,使用非常简单:
k9s -n my-namespace --context the_context_name_in_kubeconfig
(如果 kubeconfig 不在默认位置添加 KUBECONFIG=path/to/kubeconfig
前缀)。
默认视图将所有pods列为列表:
我们可以通过输入冒号 :
并开始输入所需的控制器——正如我们所见,K9S 为我们提供了自动完成功能:
并且我们可以看到当前命名空间中的所有副本集:
我们可以通过单击 enter 选择所需的副本集,然后我们将看到与该副本集相关的所有 pods 的列表 - 然后我们可以 按 'l' 查看每个 pod 的日志。
因此,与 stern 的情况不同,我们仍然需要继续查看每个 pod 并查看其日志,但我认为使用 K9S 非常方便 - 我们首先查看所有 pods一个相关的控制器,然后通过简单地导航 enter
、l
和 escape
.
来调查每个 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
您可以根据自己的要求执行以下任一操作:
kubectl -n my_namespace logs deployment/my_deployment --all-containers=true --since 10m
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
这个答案试图提供一个简明的例子和解释。为了获得一组 pods 中所有容器的所有输出,您必须使用标签(选择器),除非您计划执行一些额外的脚本。
kubectl logs \
--namespace my-namespace \
-l app=my-app-label \
--tail=-1 \
--timestamps=true \
--prefix=true \
--all-containers=true
此示例 returns 来自 pods 中由标签 app=my-app-label
定义的所有容器的完整快照日志。
可选选项
添加 --timestamps=true
和 --prefix=true
标志可能会有所帮助,以便时间戳和日志源在输出中可见,但这不是必需的。
资源日志
如果指定了诸如部署之类的资源并且该部署具有
多个 pods 例如 ReplicaSet,那么只有一个 pods 日志将被 returned。这就是为什么使用选择器来标识 pods.
尽管指定了 --all-containers
,但未成功 return 使用 kubectl
v1 的所有 pods 中所有容器的日志 return 以服务或部署等资源为目标.22.5 撰写此回复时。这就是必须使用选择器的原因。
容器名称
根据 kubectl logs --help
的输出
Print the logs for a container in a pod or specified resource.
If the pod has only one container, the container name is optional.
这意味着如果有多个容器,则必须执行以下操作之一:
- 让命令为您选择一个容器
- 使用
--all-containers=true
选项
跟随和尾随
如果您像上面的示例那样指定标签,那么 tail
将设置为 10,return 仅为每个容器的最后 10 个日志。要获取所有日志,请将 tail
设置为 -1
。
在示例中添加 -f
或 --follow
以跟踪日志。如果不需要所有日志,请更改 --tail
选项的值。拖尾日志时,您可能希望确保默认选项 --max-log-requests=5
足够。如果有 20 个容器,则需要 --max-log-requests=20
。
运行 kubectl logs
向我展示了一个 Kubernetes 容器的 stderr/stdout。
如何获得一组 pods 的聚合 stderr/stdout,最好是由某个复制控制器创建的那些?
一种选择是通过 Fluentd/ElasticSearch 设置集群日志记录,如 https://kubernetes.io/docs/user-guide/logging/elasticsearch/ 中所述。一旦日志在 ES 中,就可以很容易地在 Kibana 中应用过滤器来查看来自特定容器的日志。
我创建了一个名为 kubetail
的小 bash 脚本,使这成为可能。例如,要跟踪名为 "app1" 的 pods 的所有日志,您可以执行以下操作:
kubetail app1
您可以找到脚本 here。
我使用这个简单的脚本从部署的 pods 中获取日志:
#!/usr/bin/env bash
DEPLOYMENT=
for p in $(kubectl get pods | grep ^${DEPLOYMENT}- | cut -f 1 -d ' '); do
echo ---------------------------
echo $p
echo ---------------------------
kubectl logs $p
done
用法:log_deployment.sh "deployment-name".
脚本随后将显示以 "deployment-name".
开头的所有 pods 的日志您可以使用标签
kubectl logs -l app=elasticsearch
您可能想要指定 --all-containers --ignore-errors
以便:
- 包含来自 pods 的多个容器的日志
- 出现致命错误时继续下一个 pod(例如,无法检索日志)
如果 pods 的命名有意义,可以使用简单的 Plain Old Bash:
keyword=nodejs
command="cat <("
for line in $(kubectl get pods | \
grep $keyword | grep Running | awk '{print }'); do
command="$command (kubectl logs --tail=2 -f $line &) && "
done
command="$command echo)"
eval $command
解释:循环遍历 运行ning pods,名称包含 "nodejs"。并行跟踪它们中的每一个的日志(背景中的单符号 运行s)确保如果任何 pods 失败,整个命令退出(双符号)。将来自每个尾部命令的流分类为一个唯一的流。 运行 这个动态构建的命令需要 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}}'
...输出类似于
map[app:yourappname controller-revision-hash:598302898 pod-template-generation:1]
请注意,某些标签可能不会被其他 pods 共享 - 选择 "app" 似乎是最简单的
之前提供的解决方案并不是最优的。 kubernetes团队自己前段时间也提供了一个解决方案,叫stern。
stern app1
它也匹配正则表达式,默认执行 tail 和 -f(跟随)。一个很好的好处是,它还会向您显示生成日志的 pod。
app1-12381266dad-3233c foobar log
app1-99348234asd-959cc foobar log2
为 linux 获取 go-binary 或为 OSX 通过 brew 安装。
https://kubernetes.io/blog/2016/10/tail-kubernetes-with-stern/
如果您添加 -f
可以在之前的答案的基础上添加日志。
kubectl logs -f deployment/app
你可以从kubectl logs -h
那里得到帮助,根据信息,
kubectl logs -f deployment/myapp -c myapp --tail 100
-c
是容器名称,--tail
会显示最新的num行,但是这样会选择一个部署的pod,而不是全部pods。这是你必须牢记的。
kubectl logs -l app=myapp -c myapp --tail 100
如果要显示所有pods的日志,可以使用-l
并指定一个标签,但同时-f
不会被使用。
在这个例子中,当一个Pod中定义了多个容器时,您可以替换<namespace>
和<app-name>
来获取日志。
kubectl -n <namespace> logs -f deployment/<app-name> \
--all-containers=true --since=10m
您也可以通过服务名称执行此操作。
首先尝试找到对应多个pods同一个服务的各个pod的服务名。 kubectl get svc
.
接下来,运行以下命令显示每个容器的日志。
kubectl logs -f service/<service-name>
我用这个命令。
kubectl -n <namespace> logs -f deployment/<app-name> --all-containers=true --since=10m
我会考虑的另一个解决方案是使用 K9S,这是一个很棒的 kube 管理工具。
安装后,使用非常简单:
k9s -n my-namespace --context the_context_name_in_kubeconfig
(如果 kubeconfig 不在默认位置添加 KUBECONFIG=path/to/kubeconfig
前缀)。
默认视图将所有pods列为列表:
我们可以通过输入冒号 :
并开始输入所需的控制器——正如我们所见,K9S 为我们提供了自动完成功能:
并且我们可以看到当前命名空间中的所有副本集:
我们可以通过单击 enter 选择所需的副本集,然后我们将看到与该副本集相关的所有 pods 的列表 - 然后我们可以 按 'l' 查看每个 pod 的日志。
因此,与 stern 的情况不同,我们仍然需要继续查看每个 pod 并查看其日志,但我认为使用 K9S 非常方便 - 我们首先查看所有 pods一个相关的控制器,然后通过简单地导航 enter
、l
和 escape
.
为我工作:
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
您可以根据自己的要求执行以下任一操作:
kubectl -n my_namespace logs deployment/my_deployment --all-containers=true --since 10m
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
这个答案试图提供一个简明的例子和解释。为了获得一组 pods 中所有容器的所有输出,您必须使用标签(选择器),除非您计划执行一些额外的脚本。
kubectl logs \
--namespace my-namespace \
-l app=my-app-label \
--tail=-1 \
--timestamps=true \
--prefix=true \
--all-containers=true
此示例 returns 来自 pods 中由标签 app=my-app-label
定义的所有容器的完整快照日志。
可选选项
添加 --timestamps=true
和 --prefix=true
标志可能会有所帮助,以便时间戳和日志源在输出中可见,但这不是必需的。
资源日志
如果指定了诸如部署之类的资源并且该部署具有 多个 pods 例如 ReplicaSet,那么只有一个 pods 日志将被 returned。这就是为什么使用选择器来标识 pods.
尽管指定了 --all-containers
,但未成功 return 使用 kubectl
v1 的所有 pods 中所有容器的日志 return 以服务或部署等资源为目标.22.5 撰写此回复时。这就是必须使用选择器的原因。
容器名称
根据 kubectl logs --help
Print the logs for a container in a pod or specified resource. If the pod has only one container, the container name is optional.
这意味着如果有多个容器,则必须执行以下操作之一:
- 让命令为您选择一个容器
- 使用
--all-containers=true
选项
跟随和尾随
如果您像上面的示例那样指定标签,那么 tail
将设置为 10,return 仅为每个容器的最后 10 个日志。要获取所有日志,请将 tail
设置为 -1
。
在示例中添加 -f
或 --follow
以跟踪日志。如果不需要所有日志,请更改 --tail
选项的值。拖尾日志时,您可能希望确保默认选项 --max-log-requests=5
足够。如果有 20 个容器,则需要 --max-log-requests=20
。