【问题标题】:Where are Kubernetes' pods logfiles?Kubernetes 的 Pod 日志文件在哪里?
【发布时间】:2018-06-03 13:26:12
【问题描述】:

当我跑步时

$ kubectl logs <container>

我得到了我的 pod 的日志。

但是这些日志的文件在哪里?

一些消息来源说 /var/log/containers/ 其他人说 /var/lib/docker/containers/ 但我找不到我的实际应用程序或 pod 的日志。

【问题讨论】:

    标签: logging kubernetes kubectl kubelet


    【解决方案1】:

    简答:

    如果您使用 Docker,则每个容器中的 stdout 存储在 /var/lib/docker/containers 中。但是 Kubernetes 也创建了一个目录结构来帮助你找到基于 Pod 的日志,所以你可以在 /var/log/pods/<namespace>_<pod_name>_<pod_id>/<container_name>/ 的一个节点上找到每个 Pod 的容器日志。


    更长的答案:

    Docker 从每个容器中捕获stdout 日志并将它们存储在主机上的/var/lib/docker/containers 中。如果 Kubernetes 使用 Docker 作为容器运行时,Docker 也会将容器日志存储在 Kubernetes 节点上的那个位置。但由于我们不直接在 Kubernetes 中运行容器(我们运行 Pods),因此 Kubernetes 还创建了 /var/log/pods//var/log/containers 目录来帮助我们更好地基于 Pods 组织日志文件。

    /var/log/pods/ 中的每个目录都存储单个 Pod 的日志,每个目录都使用 <namespace>_<pod_name>_<pod_id> 结构命名。

    您可以通过运行kubectl get pod -n core gloo-76dffbd956-rmvdz -o jsonpath='{.metadata.uid}' 来获取 Pod 的 ID。如果您习惯使用yq,您可能会发现运行kubectl get pod <pod_name> -o yaml | yq r - metadata.uid 更直接。

    在每个/var/log/pods/<namespace>_<pod_name>_<pod_id>/ 目录中都有多个目录,每个目录代表 Pod 中的一个容器。这些目录的名称与容器的名称相同。最后,当我们查看/var/log/pods/<namespace>_<pod_name>_<pod_id>/<container_name>/ 目录时,我们会在/var/lib/docker/containers 中找到指向Docker 存储的日志文件的符号链接。

    同样,/var/log/containers/ 目录中包含指向/var/log/pods/<namespace>_<pod_name>_<pod_id>/<container_name>/ 目录的符号链接。这些符号链接使用<pod_name>_<namespace>_<container_id> 结构命名。

    【讨论】:

      【解决方案2】:

      你在这些目录中看到什么了吗?

      在我的集群中,来自每个 pod 的 stdout/stderr 日志位于 /var/log/containers,但是有一些链接/重定向:

      /var/log/containers/<pod-name>_<namespace>_<container-name-container-id>.log -> /var/log/pods/<some-uuid>/<container-name>_0.log
      

      该日志实际上链接到/var/lib/docker

      <container-name>_0.log -> /var/lib/docker/containers/<container-id>/<container-id>-json.log
      

      【讨论】:

      • 嗨@erk,我的应用程序日志文件不在您指出的目录中。 :(
      【解决方案3】:

      磁盘文件名来自

      docker inspect $pod_name_or_sha | jq -r '.[0].LogPath'
      

      假设 docker daemon 的配置是默认的 {"log-driver": "json-file"},如果 kubectl logs 行为正确,则几乎可以保证为真。

      这也是不言而喻的,但是您必须在为 docker inspect 安排 Pod 的节点上,或者在磁盘上四处寻找日志文件的存在,以做任何有用的事情。 kubectl describe pod $pod_name 将呈现节点名称,或者您可能怀疑它会在 kubectl get -o json pod $pod_name 中,如果您希望以编程方式获取它。

      【讨论】:

      • 嘿,马修。非常感谢您的回答!但在我的检查中,LogPath 是空的。你知道我是否缺少一些配置吗?如何正确设置LogPath
      • 这太奇怪了;你能看到那个容器的日志配置是什么吗? docker inspect pod-or-sha | jq '.[0].HostConfig.LogConfig';另外,知道那个是否与其他的不同甚至可能会很有趣,所以:docker inspect $(docker ps -aq) | jq '.[].HostConfig.LogConfig'
      • .[0].HostConfig.LogConfig 设置为 {"Type": "journald","Config": {}}
      • 啊,这样就行了。太棒了,我不知道 kubelet 足够聪明,可以从磁盘以外的任何地方获取日志。无论如何,在这种情况下,您的问题的答案是 files (可能)在/var/log/journal/$(cat /etc/machine-id) 中,但这只是迂腐的答案,因为这些文件是二进制文件;日志内容可通过journalctl -u ${container_unit} 访问,但我没有经验知道${container_unit} 是什么。 systemctl list-units 应提供容器单元名称。
      • 嗨,马修。我设法通过将 docker 的日志驱动程序从日志更改为 json 来使其工作。现在我可以看到我的应用程序日志文件。非常感谢您的支持!
      【解决方案4】:

      这取决于k8s版本:

      • 1.14 之前/var/log/pods/&lt;pod_id&gt;/&lt;name&gt;/&lt;num&gt;.log
      • 1.14 或更高版本/var/log/pods/&lt;namespace&gt;_&lt;pod_name&gt;_&lt;pod_id&gt;/&lt;container_name&gt;/&lt;num&gt;.log(请参阅此PR

      上面两个符号链接到 docker 文件的文件,例如/var/lib/docker/containers/&lt;container-id&gt;/&lt;container-id&gt;-json.log.

      例如:

      【讨论】:

      • @philraj 是的,我上传了另一张照片~~
      【解决方案5】:

      日志由每个节点上的 kubelet 管理。当您运行 kubectl logs &lt;pod&gt; 时,它会将请求传递给您的 pod 正在运行的节点上的 kubelet,并读取关联的日志文件。

      可以看到架构here

      【讨论】:

      • 无论是您的答案还是您的链接都没有说明文件路径或其文件名的任何内容。
      • 日志不由 kubelet 管理,而是 json 驱动程序(这是默认设置)读取标准输出流并将其转储到代理将拾取的位置。对于 kubectl logs ,kubelet 会从转储位置读取日志并将其显示在终端上。
      猜你喜欢
      • 1970-01-01
      • 2016-03-10
      • 2020-03-02
      • 2018-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多