当我登入容器 向追踪的文件
echo "123123213" >> /var/log/tac_plus/access/access.log
k8s dashboard 日志并没有输出 但是本地是可以的 如下是我的脚本,是我写错了 还是 k8s 对容器的日志有特别的处理?
Dokerfile
FROM ubuntu:20.04
RUN mkdir -p /var/log/tac_plus/access/
RUN mkdir -p /var/log/tac_plus/accounting/
RUN mkdir -p /var/log/tac_plus/authentication/
RUN mkdir -p /var/log/tac_plus/authorization/
ADD ./access.log /var/log/tac_plus/access/access.log
ADD ./accounting.log /var/log/tac_plus/accounting/accounting.log
ADD ./authentication.log /var/log/tac_plus/authentication/authentication.log
ADD ./authorization.log /var/log/tac_plus/authorization/authorization.log
ADD ./docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
CMD ["bash","-c","/docker-entrypoint.sh"]
docker-entrypoint
#!/bin/sh
echo "Starting server..."
{
tail -f /var/log/tac_plus/access/access.log
}&
{
tail -f /var/log/tac_plus/accounting/accounting.log
}&
{
tail -f /var/log/tac_plus/authentication/authentication.log
}
内核和文件系统的bug
https://github.com/torvalds/linux/commit/f3fbbb079263bd29ae592478de6808db7e708267
这是commit
fsnotify: support overlayfs
When an event occurs direct it to the overlay inode instead of the real
underlying inode.
This will work even if the file was first on the lower layer and then
copied up, while the watch is there. This is because the watch is on the
overlay inode, which stays the same through the copy-up.
For filesystems other than overlayfs this is a no-op, except for the
performance impact of an extra pointer dereferece.
Verified to work correctly with the inotify/fanotify tests in LTP.
Signed-off-by: Aihua Zhang <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Eric Paris <[email protected]>
修复方法: 在cmd 启动脚本里创建要追踪的文件
已结帖
1
julyclyde 2023-11-01 11:57:01 +08:00
啥叫“本地”?
你为什么假定“那个文件”就是 k8s dashboard 读的文件? |
2
Aruforce OP @julyclyde 本地是指 本地 docker 运行
k58s dashboard 日志 读取不是容器的 stdout 么? |
3
Aruforce OP @julyclyde 本地是指 本地 docker 运行
k8s dashboard 日志 读取不是容器的 stdout 么? |
8
seers 2023-11-01 12:26:56 +08:00 via Android
你往 auth 写一条看看,第三个 tail 可能覆盖掉了你的前两个 stdout
|
9
nuII 2023-11-01 12:27:45 +08:00
docker 的日志是抓取 stdout 然后写入到多行 json 格式组成的文件里,k8s 和 docker 的日志查看都是去读这个容器的日志文件,你得看日志文件里有没有,可以用 docker inspect {container id}来看日志文件的位置。另外你这个 dockerfile 用法不太规范,直接 add 可能会有权限问题,你看看你容器是 root 运行的吗,不是的话可能写不进去。
|
12
Aruforce OP @julyclyde fstat(3, 0x7fff7454e7e0) = -1 ENOSYS (Function not implemented)
|
14
julyclyde 2023-11-01 15:14:36 +08:00
@Aruforce 那你在 kubernetes 里运行用的是哪种 container runtime 呢?是 containerD 吗?看看具体用了哪种文件系统?
|
15
Aruforce OP @julyclyde Linux version 3.10.0-1160.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Mon Oct 19 16:18:59 UTC 2020
|
17
Aruforce OP @Aruforce 10
@julyclyde 文件系统 ``` root@demo-f996b8cff-g45rr:/# df -T Filesystem Type 1K-blocks Used Available Use% Mounted on overlay overlay 314418180 75916068 238502112 25% / tmpfs tmpfs 65536 0 65536 0% /dev tmpfs tmpfs 8128524 0 8128524 0% /sys/fs/cgroup /dev/mapper/centos-root xfs 17811456 14392760 3418696 81% /etc/hosts /dev/vdb1 xfs 314418180 75916068 238502112 25% /etc/hostname shm tmpfs 65536 0 65536 0% /dev/shm tmpfs tmpfs 15949852 12 15949840 1% /run/secrets/kubernetes.io/serviceaccount tmpfs tmpfs 8128524 0 8128524 0% /proc/acpi tmpfs tmpfs 8128524 0 8128524 0% /proc/scsi tmpfs tmpfs 8128524 0 8128524 0% /sys/firmware ``` |
18
julyclyde 2023-11-01 17:11:02 +08:00
对比一下正常的 docker 呢?是什么版本、什么文件系统?
|
19
julyclyde 2023-11-01 17:13:33 +08:00
看一下出错的机器的 dmesg
有没有文件系统相关的错误日志 |
20
Aruforce OP @julyclyde docker 版本都是 24.0.5 系统内核吧版本差别比较大…集群里的还是 3.1.0 找了 4.19 和 5.10 系统跑本地都没啥问题
|
21
Aruforce OP @julyclyde dmesg 里没什么注意的 地方都是这访问其他 ip 不可达的 错误信息…… 打算试试本地 3.10 的 docker 能不能跑……
|
22
julyclyde 2023-11-01 18:59:58 +08:00
@Aruforce 能否核实一下,你的 k8s 真的是和 docker 一起工作的吗?
我记得好几年前就已经去掉了 docker 的支持了,你用的是那之前的版本? |
24
Aruforce OP @julyclyde echo 那段的输出 在
dashboard 日志里是可以看到的 所以我觉的应该不是运行时这些的问题…… |
25
julyclyde 2023-11-01 20:15:25 +08:00
@Aruforce 你刚开始提问的时候不是说 echo 那段在 dashboard 里看不到么?
你要是没权限就算了,这不是你能干的事 |
26
SingeeKing 2023-11-01 23:02:41 +08:00 via iPhone
k8s 权限限制比 docker 严格,打下 $SHELL whoami 看下环境,再 ls 看下你那个 log 文件的所有者和权限,可能是没权限
|
27
julyclyde 2023-11-01 23:08:42 +08:00
@SingeeKing 你这个说法是哪儿来的啊
|
28
billccn 2023-11-02 06:33:10 +08:00
ADD ./access.log /var/log/tac_plus/access/access.log
你这些日志文件是写进 docker 镜像里面去了,加上 strace 显示 `fstat(3, 0x7fff7454e7e0) = -1 ENOSYS`,我怀疑是不是内核版本太旧,不支持在 overlayfs 上面运行 stat 。 你其实可以不必预先生成这些文件,用`tail -F`等待文件创建就可以了。 |
29
Aruforce OP @julyclyde entrypoint 这个脚本里的 echo 可以 文件追加的那个不行
|
30
Aruforce OP @SingeeKing 都是 root 用户
|
34
julyclyde 364 天前
@Aruforce echo "Starting server..."这句去 stdout ,k8s 能正常收集,这个我已经知道了
你现在问的问题不是 tail 出故障么?前面谈了那么多不都是检查 tail 的问题么? |
35
Aruforce OP @julyclyde 我把镜像降到 centos7 和主机保持一致 系统调用没啥问题了但是读不到文件的更新 应该和权限也没啥关系……
|
36
julyclyde 364 天前
@Aruforce 我觉得你最好整理一下思路吧
你现在的环境之间的差异过大了,变量至少有两个: k8s containerd 对比 docker 好几种内核版本 两个变量会有很多组合吧 你至少得把这很多组合都试了,看某个因素和故障现象有没有相关关系 现在是拿个别特例去推理,没什么用吧 |
37
Aruforce OP @julyclyde
这个 是我在追加 字符后 k8s 内的 tail 的 系统调用 ```code nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "", 8192) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "", 8192) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "", 8192) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "", 8192) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "", 8192) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 ``` 这个 是我在追加 字符后 本地 docker 的 tail 的 系统调用 ```code fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 read(3, "123456\n", 8192) = 7 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3fb0879000 read(3, "", 8192) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=7, ...}) = 0 write(1, "123456\n", 7) = 7 nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 ``` st_size 都 0->7 了 但是 本地进行了文件读写 k8s 没有。。。 我觉的基本可以确认是 tail 软件本身的问题了 |
41
Aruforce OP @julyclyde from 改成 Ubuntu 16.04 了 内核 是 3.10.0 的 。。dockerfile 把所有用的软件 都重新安装了一次。。
|
44
julyclyde 364 天前 1
|
45
Aruforce OP @julyclyde 我测试一次也不全是按照你写的东西来测试 。。
不过我解决这个问题了。。 根本原因在于 即使是相同的文件名 在 overlay2 这个文件系统里 在底层 inode 的值也是不一样的 内核的 read 在 overlay2 文件系统的实现友有问题。。这个情况下读取的内容还是 Docker 创建时加入的快照的文件内容 返回的值是空的 如果在脚本 docker-entrypoint 里创建 读取的 inode 就是运行时的 inode 了 可以参考 这个 内核的 commit https://github.com/torvalds/linux/commit/f3fbbb079263bd29ae592478de6808db7e708267 |