k8s中容器日志文件日志如何标准输出打印

k8s中,业务容器的日志打印方式一般有2种,一种是标准输出,可以直接kubectl logs查看到日志,还有一种是写到日志文件,如果需要查看日志则需要登陆容器查看,有的时候为了方便,我们希望将容器的日志文件也能标准输出,下面我们说下如何配置。

将容器内日志文件标准输出,首先要了解下容器的标准输出是怎么实现的,其实打印/dev/stdout的内容,我们先测试下,直接往/dev/stdout输入测试日志,看下容器标准输出是否能打印日志。

upload-image

测试往/dev/stdout输出日志,终端会输出,但是logs查看容器标准输出没有打印,这里是怎么回事呢?我们查看下pod里面/dev/stdout是不是有什么特殊设置。

可以发现容器的/dev/stdout是软连接到/proc/self/fd/1这个文件,这里表示stdout输出到控制台

  • 标准输入0:从键盘获得输入 /proc/self/fd/0
  • 标准输出1:输出到屏幕(即控制台)/proc/self/fd/1
  • 错误输出2:输出到屏幕(即控制台)/proc/self/fd/2

linux进程的日志打印是这样的,每个进程对应pid有/proc/pid/fd这样一个子目录,包含了当前进程打开的每一个文件.每一个条目都是一个文件描述符,是一个符号链接,指向的是实际打开的地址0表示标准输入,1表示标准输出,2表示标准错误.在多线程程序中,如果主程序退出了,那么这个文件夹将不能被访问.

如果是需要将日志打印到控制台,需要往进程的fd文件描述符输入日志,这里控制台才能查看到,容器内业务进程默认都是1,也就是往/proc/1/fd/1输入日志,控制台才会打印,下面我们测试下看看。

upload-image

测试发现,往/proc/1/fd/1输入日志是会打印在控制台的,这里如果是要将日志文件控制台打印,只需要想办法将文件内容写到/proc/1/fd/1即可。

这里容器的业务访问日志是输出在/data/go.log这个文件

upload-image

下面我们将/data/go.log先删除,因为软链只能不存在的文件,然后软链到/proc/1/fd/1,然后往日志文件输入内容,看下日志会打印在控制台

1
ln -s /proc/1/fd/1 /data/go.log

upload-image

可以发现,往日志文件输入日志,控制台能正常打印,下面我们只需要将这个软链接操作用dockerfile打到镜像里面,后续镜像启动容器,就可以将容器日志文件日志在控制台打印出来了。

我们只需要将这个命令加到dockerfile即可,具体的目录和日志文件名称以业务实际为准。

1
RUN mkdir /data && ln -s /proc/1/fd/1 /data/go.log

k8s中容器日志文件日志如何标准输出打印
https://www.niewx.cn/2023/01/29/How-to-print-the-container-log-file-to-stdout-in-k8s/
作者
VashonNie
发布于
2023年1月29日
许可协议