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:
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!
Published Jun 01, 2022
Version 1.0ViniciusApolinario
Microsoft
Joined October 26, 2016
ITOps Talk Blog
Follow this blog board to get notified when there's new activity