docker - 无法从 Pod Kubernetes 获取应用程序日志
问题描述
我在三个不同的容器中运行三个服务。这些服务的日志被发送到系统,所以如果我在 Linux 服务器上运行这些服务,我可以使用 journalctl 查看日志。
此外,如果我在 Docker 容器中运行服务,我可以使用 docker logs <container_name> 或 /var/lib/docker/containers 目录收集日志。但是当我迁移到 Kubernetes (Microk8s) 时,我无法使用 kubectl logs 命令检索它们,并且 /var/log/containers 或 /var/log/pods 中也没有日志。
如果我登录到 pod,我可以看到进程正在运行,但是如果没有日志,我就不能说它们是否正确运行。另外,我尝试将 microk8s kubelet 的运行时从 containerd 更改为 docker,但仍然无法获取任何日志。
# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
amf-deployment-7785db9758-h24kz 1/1 Running 0 72s 10.1.243.237 ubuntu <none>
# kubectl describe po amf-deployment-7785db9758-h24kz
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 87s default-scheduler Successfully assigned default/amf-deployment-7785db9758-h24kz to ubuntu
Normal AddedInterface 86s multus Add eth0 [10.1.243.237/32]
Normal Pulled 86s kubelet Container image "amf:latest" already present on machine
Normal Created 86s kubelet Created container amf
Normal Started 86s kubelet Started container amf
# kubectl logs amf-deployment-7785db9758-h24kz
# kubectl logs -f amf-deployment-7785db9758-h24kz
^C
您可以在以下屏幕截图中看到使用 Docker 运行同一个容器和使用 Kubernetes 运行它的区别。这种行为看起来很奇怪,因为如果应用程序作为独立的 Docker 容器运行,则可以收集日志,但在与 Kubernetes 一起运行时则不能。在此处输入图像描述
解决方案
在传统的服务器环境中,应用程序日志被写入一个文件,例如/var/log/app.log
. 但是,在使用 Kubernetes 时,您需要跨集群中的多个节点收集多个临时 pod(应用程序)的日志,这使得这种日志收集方法不是最佳的。相反,默认的 Kubernetes 日志框架建议将节点上每个容器的标准输出 ( stdout
) 和标准错误输出 ( ) 捕获到日志文件中。stderr
如果您在使用命令时看不到您的应用程序日志,kubectl logs
则很可能意味着您的应用程序没有在正确的位置写入日志。官方Logging Architecture文档更详细地解释了这个主题。还有一个Kubernetes 中的基本日志记录示例:
此示例使用带有容器的 Pod 规范以每秒一次将文本写入标准输出流。
apiVersion: v1 kind: Pod metadata: name: counter spec: containers: - name: count image: busybox args: [/bin/sh, -c, 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
要运行此 pod,请使用以下命令:
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
输出是:
pod/counter created
要获取日志,请使用 kubectl logs 命令,如下所示:
kubectl logs counter
输出是:
0: Mon Jan 1 00:00:00 UTC 2001 1: Mon Jan 1 00:00:01 UTC 2001 2: Mon Jan 1 00:00:02 UTC 2001 ...
您可以使用
kubectl logs --previous
从容器的先前实例中检索日志。如果您的 pod 有多个容器,请通过将容器名称附加到命令来指定要访问哪个容器的日志。有关更多详细信息,请参阅kubectl 日志文档 。
您可以将其与您的Pod
/app 配置进行比较,以查看是否有任何错误。
考虑到这些知识,您现在有几个选项来调试正在运行的 Pod,例如:
通过执行
kubectl describe pods ${POD_NAME}
和检查失败背后的原因来调试 Pod 。检查 pod 日志:使用
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
或kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
使用容器 exec 进行调试:通过在特定容器内运行命令
kubectl exec
使用临时调试容器进行调试
kubectl exec
:当容器崩溃或容器映像不包含调试实用程序(例如distroless 映像)不足时,临时容器可用于交互式故障排除。通过节点上的 shell 进行调试:如果这些方法都不起作用,您可以找到运行 pod 的主机并通过 SSH 连接到该主机
总结一下:
确保您的日志记录到位
使用上面列出的选项进行调试
推荐阅读
- javascript - 如果我不使用 Ajax - MVC 选择任何内容,如何避免下拉列表不修改数据
- javascript - 输入类型日期以设置从数据库中获取的日期
- microsoft-teams - Office365 连接到 Office 按钮不适用于 Microsoft Teams。收到 500 错误
- git - `git pull --rebase` 如何正确拉取修改后的提交?
- android - 有什么方法可以删除 AlertDialog 的背景?
- django - mysql-python安装错误
- solr - Solr 服务器突然停止而没有任何错误
- javascript - google.language API 不再可用
- java - 取消 GWT 重复定时器
- javascript - 如何在所有具有相同 id 的 td 上输出值?