日志

Pod的stdout日志

在讲Pod的stdout日志前,请先阅读docker容器stdout日志

在k8s中,我们可以通过命令kubectl logs <pod> -c <container>命令来查看Pod标准输出日志。其实,该命令最终是通过kubelet调用docker-daemon的API,去拿容器的标准输出日志。

接下来,我们来介绍一下,如何根据Pod的名字去主机上找到它stdout日志的文件。

我们知道,一个Pod里可以编排多个容器,至少都会有两个容器(工作容器与pause容器),比如如下Pod编排了两个工作容器,一个叫nginx,一个叫tomcat

那么这个Pod被调度到节点上后,最终会由docker起三个docker容器。而Pod中的工作容器对应的docker容器的名字为:

k8s_<container>_<pod>_<namespace>_<podID>_0

比如nginx与tomcat对应到的docker容器为

k8s_nginx_peng_default_<podID>_0
k8s_tomcat_peng_default_<podID>_0

而pause容器对应的docker容器为

k8s_POD_peng_default_<podID>_0

上面的podID可以通过命令kubectl get pod peng -o yaml | grep uid来查看。

弄清楚了上述规则后,我们便可以按照以下的方式去找kubectl logs <pod> -c <container>对应的日志文件。

首先第一步,执行以下命令找到Pod所在的主机

$ kubectl get pod -o wide | grep <podName>

然后,我们去到目标主机上,我们先要找到Pod所在宿主机上对应的容器的containerID。在Pod所在主机上执行如下命令,第一列就是Pod对应的docker容器的containerID

$ docker ps --no-trunc | grep <containerName>_<podName>

得到containerID后,就可以找到日志文件/var/lib/docker/containers/<containerID>/<containerID>-json.log

其实,kubelet还会为Pod的每个Container的stdout日志创建一个符号链接文件,指向上面的这个日志文件,其符号链接文件的路径为:

/var/log/pods/<namespace>_<podName>_<podID>/<container>/0.log

比如nginx与tomcat的stdout文件符号链接就是

/var/log/pods/default_peng_<podID>/nginx/0.log
/var/log/pods/default_peng_<podID>/tomcat/0.log

小结:在节点上查看Pod的Container的stdout日志文件的路径为/var/log/pods/<namespace>_<podName>_<podID>/<container>/0.log

日志文件挂载与采集

我们希望把Pod的日志文件挂载到宿主机上,然后通过ELK的方法采集与查询。我们希望每个Pod的日志目录挂载到宿主机的目录为/host/log/<deployment>/<pod>/。举个例子,假设Deployment在容器内的日志目录为/container/log/,该目录下有很多.log文件,那么我们希望这个Deployment的每个Pod的/container/log/目录挂载到宿主机的目录为/host/log/<deployment>/<pod>/

为了达到上面的效果,我们在发布Deployment的时候,需要使用到kubernetes的Downward API,如下:

经过验证,上面的方法是不可行的。因为volume1是属于Pod的,而POD_NAME这个环境变量是定义在Container里面的。

另外,DownwardAPI的理念是把Pod与Container的信息注入到容器当中,两种常见的注入方式为“环境变量”与“文件”。而上面我们的需求是:kubelet在主机上自动地创建目录;与DownwardAPI的理念不一致,所以无法实现。

Reference

Last updated

Was this helpful?