docker top now takes ps_args as optional arguments. There is a bug in docker where when ps args are provided, the return of docker top will differ. To replicate, run two containers: # docker run -d centos /usr/bin/vi b753f4832fb11d260ab39c68ae6d6376d75cfbe20392b553b0d5a9679e7d483d # docker run -it --rm centos /bin/bash [root@01a2e3db9f7d /]# Now, execute docker top for each without ps args. The results are accurate: $ docker top b753f4832fb UID PID PPID C STIME TTY TIME CMD root 6103 3848 0 13:12 ? 00:00:00 /usr/bin/vi $ docker top 01a2e3db9f7d UID PID PPID C STIME TTY TIME CMD root 6025 3848 0 13:12 pts/3 00:00:00 /bin/bash Now execute the same commands but pass ps args with -o. $ docker top b753f4832fb -o pid,cmd PID CMD 6103 /usr/bin/vi $ docker top 01a2e3db9f7d -o pid,cmd PID CMD Note how the second command issue returned no results. Now execute the same commands but pass ps args with only 'o' $ docker top b753f4832fb o pid,cmd PID CMD $ docker top 01a2e3db9f7d o pid,cmd PID CMD 6025 /bin/bash Note how the results are not inverse of before, where we didn't get results, we now do and visa versa.
This is not a docker bug. Rather this is the way "ps" works wrt processes that have (or have not) a TTY. Let me explain. I'll work out a patch to the docker top man page after this. You are running two containers, one with a TTY and one without. When doing "docker top", docker shells out to the "ps" binary to find information about the pid the container is running with. It does so by first listing all processes and then selectively filtering out all pids except the container's one. When "docker top" runs without ps arguments it will default to shell out to "ps -ef" (note the dash) which selects all processes (-e) and does full-format listing (-f). But, "-ef" is UNIX style. If you run "ps ef" you'll get a totally different result because without the dash ps is interpreting the options as BSD style options. If you want to list all process using the BSD style (the same way "ps -ef") you have to do, instead, "ps axu" So this is why "docker top" without ps args works fine for both containers - because it's listing all processes (both with and w/o ttys) Enough with this. Now let's get to TTYs. --- If you provide ps arguments to "docker top", then Docker drops the default "-ef" argument in favor of just using the ones you provided. Let's interpret your commands. === A. using "-o" which is UNIX style 1. you run a contianer WITH a TTY 1a. you run "docker top CONTAINERTTY -o pid,cmd" 1b. you are explicitly using the UNIX style ps options. The -o flag means use the UNIX style "-o" option which is a shorthand for "--format" to select fields. 1c. Docker will run "ps -o pid,cmd" to get a list of all processes 1d. from man ps: "ps selects all processes with the same effective user ID (euid=EUID) as the current user and associated with the same terminal as the invoker." 1e. so when docker runs "ps -o pid,cmd" it won't get anything because your container is running with another TTY (/dev/pts/3 for instance) This is why you'll get no output when running with "-o" and a container WITH a TTY 2. you run a container WITHOUT a TTY 2a. on the other end, when you run "docker top CONTAINERNOTTY -o pid,cmd" the container do not get a TTY (that's why the TTY colum of just "docker top ID" shows "?") 2b. Docker will run "ps o pid,cmd" 2c. This time we'll get the correct process because the container runs with the same EUID + the calling process has not TTY (like the container) This is why you'll get output when running with "-o" and a container WITHOUT a TTY === B. using "o" which is BSD style 1. you run a contianer WITH a TTY 1a. you run "docker top CONTAINERTTY o pid,cmd" 1b. you are explicitly using the BSD style ps options. The o flag means use the BSD style "o" option (same as UNIX -o and --format to select fields). 1c. Docker will run "ps o pid,cmd" to get a list of all processes 1d. when ps runs w/o BSD args it enforces processes to have a TTY! 1e. so when docker runs "ps o pid,cmd" it will get the correct pid because your container pid is listed because it has a TTY (/dev/pts/3 for instance) This is why you'll get output when running with "o" and a container WITH a TTY 2. you run a container WITHOUT a TTY 2a. on the other end, when you run "docker top CONTAINERNOTTY o pid,cmd" the container do not get a TTY (that's why the TTY colum of just "docker top ID" shows "?") 2b. Docker will run "ps o pid,cmd" 2c. This time we won't get the correct process because the container runs w/o a TTY and ps with BSD style args do not list processes w/o a TTY This is why you'll get no output when running with "o" and a container WITHOUT a TTY === All of that said, the correct args to give to "docker top" to achieve consistency with and w/o a TTY are either: BSD-style: "docker top CONTAINER axo pid,cmd" or: UNIX-style: "docker top CONTAINER -eo pid,cmd" Both will firstly show all processes and then docker filters out to the pid the containers are running with.
Sorry for the long explanation. I'll work out a patch for the "docker top" man page upstream.
Great explaination, thanks! Want me to close this as not-a-bug ?