How to identify processes running inside a Windows container from the container host
Published Jun 01 2022 03:00 AM 6,912 Views

This is another blog post idea coming from discussions on Forums - sometimes, you need to check the processes running on a Windows container so you can troubleshoot your environment, or simply monitor its state. After some testing, I figured out a way to find the processes that are running inside the container – without having to actually open an interactive session to it, which let’s be honest – is such as pain. So, here’s how all this works:

 

Windows containers and Windows container host processes

To get started, it’s important to understand the following concept: When you have a Windows container running in process isolation mode, all processes are isolated between the containers so they have no influence on each other. However, the security boundary between container host and containers is simply the process isolation itself, which means the container host has visibility into the processes running inside the container. Of course, you don’t want to run your multi-tenant, production environment with processes isolation and that’s where Hyper-V isolation comes in. For more details on the isolation methods for Windows containers you can check the documentation that explains its differences and when to use each.

If you want to try this out, you can simply run a Get-Process command on a container host and check the results:

Container_Processes_1.png

Notice on the image above that the container host shows multiple “csrss” processes but with different Session Identifiers. This is because I have 4 Windows containers running, plus the container host with that process instantiated.

 

How do I know which process is from which container?

Let’s say you need to identify a specific process from a specific container, so you can attach a debugger, check the username on which the process was instantiated, or any other troubleshooting process you might need to run. One way to achieve that is to open a interactive session to the container, but that’s not exactly trivial if the container is already running – And let’s be honest, not exactly the simplest way to achieve this.

So, that’s where the trick comes in. Let’s get started by identifying all containers running on the container host:

PS C:\Users\Microsoft> docker ps -a
CONTAINER ID   IMAGE                                                                 COMMAND                   CREATED        STATUS                  PORTS                  NAMES
172cf04a11ca   mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022   "C:\\ServiceMonitor.e…"   8 hours ago    Up 8 hours              0.0.0.0:8081->80/tcp   modest_cartwright
a083dfae22d0   mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022   "C:\\ServiceMonitor.e…"   8 hours ago    Created                                        mystifying_chebyshev
8b2f6493d26e   mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022   "C:\\ServiceMonitor.e…"   10 hours ago   Up 10 hours             0.0.0.0:8080->80/tcp   naughty_blackburn
b9420352be56   inception:v1                                                          "powershell"              8 days ago     Exited (0) 8 days ago                          interesting_colden

The docker ps -a command shows all containers on your container host and their “Container ID”. With that information, we can run:

PS C:\Users\Microsoft> docker inspect -f '{{.State.Pid}}' 8b2f6493d26e
4492

So, now we know the entry point of the container has instantiated the process ID number 4492. With that, we can check the Session Identifier of that process:

PS C:\Users\Microsoft> Get-Process -Id 4492 | select si

SI
--
 6

Now we know the Session Identifier being used to run all the processes of this container is the number 6. With that, we can then see all processes for that specific container:

PS C:\Users\Microsoft> Get-Process | Where-Object {$_.si -eq 6}

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
     83       6      976       4776       0.00   8380   6 CExecSvc
    251      13     2040       6308       0.19   7308   6 csrss
     38       6      792       3176       0.00   3772   6 fontdrvhost
    793      20     3980      27740       0.81   8912   6 lsass
    232      13     2624      10384       0.11   7348   6 msdtc
     75       6      928       4872       0.02   4492   6 ServiceMonitor
    215      11     2452       7072       0.47   8308   6 services
    137       9     1548      15536       0.05    864   6 svchost
    172      12     2652      18336       0.08   2352   6 svchost
    110       7     1240      13824       0.03   2572   6 svchost
    237      14     4620      23228       0.20   5460   6 svchost
    809      30    12312      61900      10.41   6056   6 svchost
    172      12     4088      22276       0.14   6420   6 svchost
    391      15     6892      24584       0.52   6524   6 svchost
    494      22    15336      51652       4.23   7060   6 svchost
    518      38     5772      50752       0.94   7936   6 svchost
    334      13     3056      21372       0.34   8604   6 svchost
    122       8     3100      19776       0.19   8816   6 svchost
    386      15     2660      17656       0.72   9080   6 svchost
    233      36     4984      14184       0.06   5444   6 w3wp
    155      11     1380       7276       0.05   5008   6 wininit

Voilá! Notice the process ID #4492 above is the Service Monitor running inside the IIS container image. Also, notice the w3wp process at the bottom which represents IIS itself. If you want, you can even play with this a little bit:

PS C:\Users\Microsoft> Get-Process | Where-Object {$_.si -eq 6 -and $_.processname -eq "w3wp"}

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    233      36     4984      14184       0.06   5444   6 w3wp

The above command returns only the IIS process from the container. But you can go even further:

PS C:\Users\Microsoft> Get-Process | Where-Object {$_.si -eq 6 -or $_.si -eq 7 -and $_.processname -eq "w3wp"}

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    233      36     4984      14184       0.06   5444   6 w3wp
    233      24     4968      14140       0.06  11056   7 w3wp

This command returns the IIS process from two different containers.

 

Conclusion

It is much easier to check the processes from a running container from its container host. While not possible to do that on Hyper-V isolated containers, you can simply check the process ID for a container and use that information – alongside its Session Identifier – to query all processes on Process isolated Windows containers.

Hopefully this information helps you better troubleshoot your applications on Windows containers! Let us know what you think in the comments section below!

Version history
Last update:
‎Jun 01 2022 03:00 AM
Updated by: