V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Aruforce
V2EX  ›  Kubernetes

k8s 对容器的日志有什么特殊的处理么?dashboad 日志输出和本地 docker 运行 表现不一致

  •  
  •   Aruforce · 168 天前 · 1895 次点击
    这是一个创建于 168 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当我登入容器 向追踪的文件

    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
    }
    
    第 1 条附言  ·  166 天前

    内核和文件系统的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 启动脚本里创建要追踪的文件

    已结帖

    49 条回复    2023-11-03 18:07:45 +08:00
    julyclyde
        1
    julyclyde  
       168 天前
    啥叫“本地”?

    你为什么假定“那个文件”就是 k8s dashboard 读的文件?
    Aruforce
        2
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde 本地是指 本地 docker 运行
    k58s dashboard 日志 读取不是容器的 stdout 么?
    Aruforce
        3
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde 本地是指 本地 docker 运行
    k8s dashboard 日志 读取不是容器的 stdout 么?
    julyclyde
        4
    julyclyde  
       168 天前
    @Aruforce 你既然知道是 stdout ,为什么想着往 access.log 里加内容呢?
    Aruforce
        5
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde 我用 tail 输出到 stdout 的啊
    Aruforce
        6
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde 你看启动的 shell 脚本
    julyclyde
        7
    julyclyde  
       168 天前
    @Aruforce 那你试试用 strace 验证一下,tail 有没有读到这一行,有没有把这一行输出到 stdout
    seers
        8
    seers  
       168 天前 via Android
    你往 auth 写一条看看,第三个 tail 可能覆盖掉了你的前两个 stdout
    nuII
        9
    nuII  
       168 天前
    docker 的日志是抓取 stdout 然后写入到多行 json 格式组成的文件里,k8s 和 docker 的日志查看都是去读这个容器的日志文件,你得看日志文件里有没有,可以用 docker inspect {container id}来看日志文件的位置。另外你这个 dockerfile 用法不太规范,直接 add 可能会有权限问题,你看看你容器是 root 运行的吗,不是的话可能写不进去。
    Aruforce
        10
    Aruforce  
    OP
       168 天前 via Android
    @seers k8s 上都不行 本地 docker 都可以输出…
    julyclyde
        11
    julyclyde  
       168 天前
    @seers 为什么第三个会覆盖前两个呢?不明白
    Aruforce
        12
    Aruforce  
    OP
       168 天前
    @julyclyde fstat(3, 0x7fff7454e7e0) = -1 ENOSYS (Function not implemented)
    Aruforce
        13
    Aruforce  
    OP
       168 天前
    @julyclyde 你好 我追了下 tail 似乎是 对 stat read 两个方法没有实现?
    julyclyde
        14
    julyclyde  
       168 天前
    @Aruforce 那你在 kubernetes 里运行用的是哪种 container runtime 呢?是 containerD 吗?看看具体用了哪种文件系统?
    Aruforce
        15
    Aruforce  
    OP
       168 天前
    @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
    Aruforce
        16
    Aruforce  
    OP
       168 天前
    @julyclyde 内核版本太低了么?
    Aruforce
        17
    Aruforce  
    OP
       168 天前
    @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
    ```
    julyclyde
        18
    julyclyde  
       168 天前
    对比一下正常的 docker 呢?是什么版本、什么文件系统?
    julyclyde
        19
    julyclyde  
       168 天前
    看一下出错的机器的 dmesg
    有没有文件系统相关的错误日志
    Aruforce
        20
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde docker 版本都是 24.0.5 系统内核吧版本差别比较大…集群里的还是 3.1.0 找了 4.19 和 5.10 系统跑本地都没啥问题
    Aruforce
        21
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde dmesg 里没什么注意的 地方都是这访问其他 ip 不可达的 错误信息…… 打算试试本地 3.10 的 docker 能不能跑……
    julyclyde
        22
    julyclyde  
       168 天前
    @Aruforce 能否核实一下,你的 k8s 真的是和 docker 一起工作的吗?
    我记得好几年前就已经去掉了 docker 的支持了,你用的是那之前的版本?
    Aruforce
        23
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde 应该是 containerd 上不了物理机 看不到
    Aruforce
        24
    Aruforce  
    OP
       168 天前 via Android
    @julyclyde echo 那段的输出 在
    dashboard 日志里是可以看到的 所以我觉的应该不是运行时这些的问题……
    julyclyde
        25
    julyclyde  
       168 天前
    @Aruforce 你刚开始提问的时候不是说 echo 那段在 dashboard 里看不到么?
    你要是没权限就算了,这不是你能干的事
    SingeeKing
        26
    SingeeKing  
       167 天前 via iPhone
    k8s 权限限制比 docker 严格,打下 $SHELL whoami 看下环境,再 ls 看下你那个 log 文件的所有者和权限,可能是没权限
    julyclyde
        27
    julyclyde  
       167 天前
    @SingeeKing 你这个说法是哪儿来的啊
    billccn
        28
    billccn  
       167 天前
    ADD ./access.log /var/log/tac_plus/access/access.log

    你这些日志文件是写进 docker 镜像里面去了,加上 strace 显示 `fstat(3, 0x7fff7454e7e0) = -1 ENOSYS`,我怀疑是不是内核版本太旧,不支持在 overlayfs 上面运行 stat 。

    你其实可以不必预先生成这些文件,用`tail -F`等待文件创建就可以了。
    Aruforce
        29
    Aruforce  
    OP
       167 天前 via Android
    @julyclyde entrypoint 这个脚本里的 echo 可以 文件追加的那个不行
    Aruforce
        30
    Aruforce  
    OP
       167 天前 via Android
    @SingeeKing 都是 root 用户
    julyclyde
        31
    julyclyde  
       167 天前
    @Aruforce 你说的“可以”是指 echo "Starting server..."这句可以吗?
    那不是废话么……
    这都不涉及到日志文件的问题
    julyclyde
        32
    julyclyde  
       167 天前
    @billccn 我也觉得是 overlayfs 或者内核版本太低的问题。不过既然他没有 node 的 root 权限那就啥都别说了
    Aruforce
        33
    Aruforce  
    OP
       167 天前
    @julyclyde 这也是写到 stdout 的啊
    julyclyde
        34
    julyclyde  
       167 天前
    @Aruforce echo "Starting server..."这句去 stdout ,k8s 能正常收集,这个我已经知道了
    你现在问的问题不是 tail 出故障么?前面谈了那么多不都是检查 tail 的问题么?
    Aruforce
        35
    Aruforce  
    OP
       167 天前 via Android
    @julyclyde 我把镜像降到 centos7 和主机保持一致 系统调用没啥问题了但是读不到文件的更新 应该和权限也没啥关系……
    julyclyde
        36
    julyclyde  
       167 天前
    @Aruforce 我觉得你最好整理一下思路吧
    你现在的环境之间的差异过大了,变量至少有两个:
    k8s containerd 对比 docker
    好几种内核版本

    两个变量会有很多组合吧
    你至少得把这很多组合都试了,看某个因素和故障现象有没有相关关系

    现在是拿个别特例去推理,没什么用吧
    Aruforce
        37
    Aruforce  
    OP
       167 天前
    @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 软件本身的问题了
    julyclyde
        38
    julyclyde  
       167 天前
    @Aruforce 之前提到的 ENOSYS 好像这次没出现?
    也就是出现了第三种情况( fstat 不出 ENOSYS 错误但也不干活)?
    Aruforce
        39
    Aruforce  
    OP
       167 天前 via Android
    @julyclyde enosys 可以确定是内核的问题 我把镜像切到 3.10.0 的内核了
    julyclyde
        40
    julyclyde  
       167 天前
    @Aruforce 什么叫“把镜像”切换到某版本内核了?
    容器里没有内核啊
    Aruforce
        41
    Aruforce  
    OP
       167 天前
    @julyclyde from 改成 Ubuntu 16.04 了 内核 是 3.10.0 的 。。dockerfile 把所有用的软件 都重新安装了一次。。
    Aruforce
        42
    Aruforce  
    OP
       167 天前
    @julyclyde #41 然后 tail 不再出 enosys 的问题了 但是 变成了只读取到了文件变化 不读和输出 了
    Aruforce
        43
    Aruforce  
    OP
       167 天前
    julyclyde
        44
    julyclyde  
       166 天前   ❤️ 1
    @Aruforce 你换了底也没在这里说明啊,非要“打一棍子才放一个屁”这样啊?
    以及,再次强调,容器没有内核!!

    我猜还是和 kube node 的内核版本有关系
    Aruforce
        45
    Aruforce  
    OP
       166 天前
    @julyclyde 我测试一次也不全是按照你写的东西来测试 。。
    不过我解决这个问题了。。
    根本原因在于 即使是相同的文件名 在 overlay2 这个文件系统里 在底层 inode 的值也是不一样的
    内核的 read 在 overlay2 文件系统的实现友有问题。。这个情况下读取的内容还是 Docker 创建时加入的快照的文件内容
    返回的值是空的
    如果在脚本 docker-entrypoint 里创建 读取的 inode 就是运行时的 inode 了
    可以参考 这个 内核的 commit
    https://github.com/torvalds/linux/commit/f3fbbb079263bd29ae592478de6808db7e708267
    Aruforce
        46
    Aruforce  
    OP
       166 天前
    @julyclyde 感谢你给的提示 文件系统错误
    julyclyde
        47
    julyclyde  
       166 天前
    @Aruforce 这个 commit 是 2016 年的……
    所以这个故事教导我们:别用旧软件
    julyclyde
        48
    julyclyde  
       166 天前
    @Aruforce 最后应该是确保了 kube node 在高版本内核运行才解决的吧?
    Aruforce
        49
    Aruforce  
    OP
       166 天前
    @julyclyde 不是 。。还是原来的 环境
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3289 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 470ms · UTC 12:29 · PVG 20:29 · LAX 05:29 · JFK 08:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.