如何在 docker 容器中使用 lsof?

如何在 docker 容器中使用 lsof?
$ docker run --rm nginx:alpine
$ docker exec --privileged -it `docker ps -q | head -1` sh
/ # apk add strace lsof
/ # strace -fp1 lsof
strace: Process 1 attached
[pid     1] rt_sigsuspend([], 8 <unfinished ...>
[pid   100] execve("/usr/bin/lsof", ["lsof"], 0x7fff9ca1d308 /* 9 vars */) = 0
[pid   100] arch_prctl(ARCH_SET_FS, 0x7f19d2cc8b48) = 0
[pid   100] set_tid_address(0x7f19d2cc8fb0) = 100
[pid   100] brk(NULL)                   = 0x55791ae48000
[pid   100] brk(0x55791ae4a000)         = 0x55791ae4a000
[pid   100] mmap(0x55791ae48000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x55791ae48000
[pid   100] mprotect(0x7f19d2cc5000, 4096, PROT_READ) = 0
[pid   100] mprotect(0x557919b6d000, 4096, PROT_READ) = 0
[pid   100] prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1073741816, rlim_max=1073741816}) = 0
[pid   100] close_range(3, 1073741815, 0) = 0
[pid   100] open("/dev/null", O_RDWR|O_LARGEFILE) = 3
[pid   100] close(3)                    = 0
[pid   100] umask(000)                  = 022
[pid   100] getpid()                    = 100
[pid   100] getgid()                    = 0
[pid   100] getegid()                   = 0
[pid   100] geteuid()                   = 0
[pid   100] getuid()                    = 0
[pid   100] mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f19d2c2b000
[pid   100] stat("/dev", {st_mode=S_IFDIR|0755, st_size=340, ...}) = 0
[pid   100] open("/", O_RDONLY|O_LARGEFILE) = 3
[pid   100] lseek(3, 1, SEEK_SET)       = 1
[pid   100] lstat("/proc/100/fd/3", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
[pid   100] open("/proc/100/fdinfo/3", O_RDONLY|O_LARGEFILE) = 4
[pid   100] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f19d2c2a000
[pid   100] read(4, "pos:\t1\nflags:\t0100000\nmnt_id:\t35"..., 1024) = 47
[pid   100] lseek(4, -40, SEEK_CUR)     = 7
[pid   100] close(4)                    = 0
[pid   100] munmap(0x7f19d2c2a000, 4096) = 0
[pid   100] close(3)                    = 0
[pid   100] open("/proc/mounts", O_RDONLY|O_LARGEFILE) = 3
[pid   100] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f19d2c2a000
[pid   100] read(3, "overlay / overlay rw,relatime,lo"..., 4088) = 2115
[pid   100] pipe([4, 5])                = 0
[pid   100] pipe([6, 7])                = 0
[pid   100] rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1 RT_2], [], 8) = 0
[pid   100] rt_sigprocmask(SIG_BLOCK, ~[], ~[KILL STOP RTMIN RT_1 RT_2], 8) = 0
[pid   100] fork(strace: Process 101 attached
)                      = 101
[pid   101] gettid()                    = 101
[pid   100] rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1 RT_2],  <unfinished ...>
[pid   101] rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1 RT_2],  <unfinished ...>
[pid   100] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid   101] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid   100] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid   101] rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[pid   100] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid   101] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid   100] close(4 <unfinished ...>
[pid   101] close(0 <unfinished ...>
[pid   100] <... close resumed>)        = 0
[pid   101] <... close resumed>)        = 0
[pid   100] close(7 <unfinished ...>
[pid   101] close(1 <unfinished ...>
[pid   100] <... close resumed>)        = 0
[pid   101] <... close resumed>)        = 0
[pid   100] rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2],  <unfinished ...>
[pid   101] close(2 <unfinished ...>
[pid   100] <... rt_sigprocmask resumed>NULL, 8) = 0
[pid   101] <... close resumed>)        = 0
[pid   100] rt_sigaction(SIGALRM, {sa_handler=0x557919b5f4b6, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f19d2c78acd},  <unfinished ...>
[pid   101] close(3 <unfinished ...>
[pid   100] <... rt_sigaction resumed>{sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
[pid   101] <... close resumed>)        = 0
[pid   100] setitimer(ITIMER_REAL, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=15, tv_usec=0}},  <unfinished ...>
[pid   101] close(5 <unfinished ...>
[pid   100] <... setitimer resumed>{it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}) = 0
[pid   101] <... close resumed>)        = 0
[pid   100] write(5, "\315\364\265\31yU\0\0", 8 <unfinished ...>
[pid   101] close(6 <unfinished ...>
[pid   100] <... write resumed>)        = 8
[pid   101] <... close resumed>)        = 0
[pid   100] write(5, "\2\0\0\0", 4 <unfinished ...>
[pid   101] close(8 <unfinished ...>
[pid   100] <... write resumed>)        = 4
[pid   101] <... close resumed>)        = -1 EBADF (Bad file descriptor)
[pid   100] write(5, "/\0", 2 <unfinished ...>
[pid   101] close(9 <unfinished ...>
[pid   100] <... write resumed>)        = 2
[pid   101] <... close resumed>)        = -1 EBADF (Bad file descriptor)
[pid   100] write(5, "\0\20\0\0", 4 <unfinished ...>
[pid   101] close(10 <unfinished ...>
[pid   100] <... write resumed>)        = 4
[pid   101] <... close resumed>)        = -1 EBADF (Bad file descriptor)
[pid   100] read(6,  <unfinished ...>
[pid   101] close(11)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(12)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(13)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(14)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(15)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(16)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(17)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(18)                   = -1 EBADF (Bad file descriptor)
[pid   101] close(19)                   = -1 EBADF (Bad file descriptor)
...
[pid   101] close(1141630)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141631)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141632)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141633)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141634)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141635)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141636)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141637)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141638)              = -1 EBADF (Bad file descriptor)
[pid   101] close(1141639strace: Process 1 detached
strace: Process 100 detached
strace: Process 101 detached
 <detached ...>

有办法让它发挥作用吗?

答案1

这也发生在我身上,不知道为什么lsof需要关闭文件描述符。可以通过FILENO为容器或每个进程设置资源限制来解决此问题。

$ docker run -d --rm --name nginx --ulimit nofile=1024 nginx:alpine

或者

$ docker run -d --rm --name nginx nginx:alpine
$ docker exec -it -u root /bin/sh nginx
# ulimit -Sn 1024
# apk add lsof
# lsof

您还可以在 Docker 守护程序配置文件/etc/docker/daemon.json或命令行中设置默认资源限制。

{
  "default-ulimits": {
    "default-nofile": {
      "Name": "nofile",
      "Soft": 1024,
      "Hard": 65535
    }
  }
}

有关ulimit选项,请参阅getrlimit(2)ulimit是一个内置的 shell,请参见ash(1)

相关内容