8

It's simple. I would like to detect with code if my process is running inside a windows container. There are examples but they are all for linux based containers.

I'm looking for something unique and explicit to docker that can be used to make a safe conclusion whether a process is executing inside a container hosted windows operating system and not otherwise.

My preferred language is PowerShell but if someone points out the how to detect, I'll port it to PowerShell.

Alex Sarafian
  • 634
  • 6
  • 17
  • This question definitely needs some improvements. Did you try something to achieve your goal? What are these linux examples and what do you mean with windows container? Looking at the tags I guess you want to see whether your script runs on linux or on a windows docker image. But its just a guess... – Clijsters Mar 24 '17 at 16:05
  • Thank you for the feedback but my point is that when searching for this subject you get Linux only specific answers. I'm looking for the method that can detect if a piece of cigs is running inside a container. I haven't tried anything because I don't know where to even begin as I can't find a good reference. For this reason my question was indeed "empty". – Alex Sarafian Mar 24 '17 at 19:56

4 Answers4

6

New readers can skip ahead to the part marked with "Update" which contains the accepted solution.

A quick check with whoami on the command prompt showed that the combination of domain and username that is used inside a container seems to be rather unusual. So I used this code to solve the problem:

function Test-IsInsideContainer {
  if( ($env:UserName -eq "ContainerAdministrator") -and ($env:UserDomain -eq "User Manager") ) {
    $true
  }
  else {
    $false
  }
}

Update: Another option is to check if the service cexecsvc exist. An internet search did not yield much information about this service, but its name (Container Execution Agent) suggests that it only exists inside of containers (which I verified with some quick test on Win10 and a Server2016 Docker-host). So maybe this code meets your requirements (I am a newbie in Powershell):

function Test-IsInsideContainer {
  $foundService = Get-Service -Name cexecsvc -ErrorAction SilentlyContinue
  if( $foundService -eq $null ) {
    $false
  }
  else {
    $true
  }
}
frank koch
  • 1,138
  • 2
  • 14
  • 27
  • This is indeed a possible solution, but I'm still looking for something that is independent for values that could possibly result into conflicts. In amazon for example you can try a specific metadata endpoint, similar to what @dominique suggested in his own answer. – Alex Sarafian Oct 19 '17 at 12:53
  • The service idea falls under the category of unique. I'm now curious to what the service does. I'll do some checks and come back to you. I need to check this both on nano and core base images. Thank you for now. – Alex Sarafian Oct 21 '17 at 08:06
  • 1
    I checked your conditions and I agree that this is a good solution. I've also compacted your code into `(Get-Service -Name cexecsvc -ErrorAction SilentlyContinue) -ne $null` that can be used inside your function or directly inside a condition. Thank you! – Alex Sarafian Oct 24 '17 at 13:20
  • Happy to hear that this solves your problem - you might want to consider marking this as accepted answer. – frank koch Oct 24 '17 at 15:48
  • I voted up and I forgot to mark it as answered. I believe your first suggestion with the username to be semi-correct, or at least not that powerful as the one with the service. If you can adjust your answer to reflect this, that would great for others also. Thank you again. – Alex Sarafian Oct 24 '17 at 16:19
  • Does this work for Hyper-V containers as well? – Swapan Pramanick Jul 31 '21 at 21:07
5

There's a "ContainerType" registry value under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control.

So:

function Test-IsInsideContainer {
  $containerType = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control").ContainerType
  $containerType -ne $null
}
pharring
  • 1,991
  • 1
  • 14
  • 10
  • FWIW - if you actually want to detect "Docker" it seems safer to compare the value to `2` instead of `null`. The key is also being set for applications running in the Windows Sandbox (with a value of `4` in that case). As none of these values is actually documented, it's a bit voodoo to rely on this setting. – JBartlau Jul 07 '22 at 09:58
-1

Will below work? PS C:\> (Get-NetAdapter).Name -match "container" True

Gregory Suvalian
  • 3,566
  • 7
  • 37
  • 66
  • I'm going to check but I was thinking something more robust. The advice just checks for the network adapter name and this can lead to false positives depending on the name of an adapter. Isn't there something more unique and explicit that is a acts as docker marker? – Alex Sarafian Mar 24 '17 at 20:00
  • I guess you can piece together bunch of things to find out if it's in container. For example server service will be stopped, there will user called ContainerAdmin etc. Put && between each of those and if all are true you have very high chance that it's in fact container. Remember the whole point is for OS to think it's running it's own OS – Gregory Suvalian Mar 24 '17 at 22:48
  • I think below will provide 99.9999% that you are inside container `PS C:\> (invoke-webrequest http://172.17.208.1:2375/containers/json -usebasicparsing).Rawcontent -match $env:computername` – Gregory Suvalian Mar 24 '17 at 23:00
  • We are getting somewhere. Nice. What is serverservice and what is the 172.17.208.1 up? – Alex Sarafian Mar 25 '17 at 21:06
  • Regarding server service I tried looking into it to understand what it is and what it does but the most relevant information I found on this link https://technet.microsoft.com/en-us/library/cc958790.aspx. still did understand it's purpose and why it is defacto stopped within a container. – Alex Sarafian Mar 25 '17 at 21:14
  • 172.x is gateway IP address of container. You can get it by `(get-netroute -DestinationPrefix "0.0.0.0/0").Nexthop`, docker by default will expose it's API on default GW of container and this request asks to enumerate all containers running on a system. Last part just checks if current machine is in that list by matching it's name to return of container list. – Gregory Suvalian Mar 25 '17 at 21:15
  • I've started a container like this `docker run -it microsoft/windowsservercore powershell`. `(Get-NetAdapter).Name` returns only one value of `Ethernet 2` and not container as suggested. `(get-netroute -DestinationPrefix "0.0.0.0/0").Nexthop` return indeed a 172.18.* address that is the same as the gateway when executing `ipconfig`. The address `172.18.160.1:2375` doesn't respond either with the `Invoke-WebRequest` or by simply `Test-NetConnection 172.18.160.1 -Port 2375`. – Alex Sarafian Mar 26 '17 at 19:02
  • From the above suggestion only the first part of the gateway seems to match the expectation. I've expected that the mechanism would a bit different from Linux based images and that's why I've created this question. – Alex Sarafian Mar 26 '17 at 19:04
-2

As of Docker 17.06 onward you could use the DNS entry docker.for.mac.localhost and docker.for.mac.localhost to determine if the container runs on a mac or windows host. if none of these host names can be pinged you might safely assume its a linux host. This will probably not work for Swarms.

I am not an expert in Bash but an example could look like this.

#!/bin/bash

ping -c 1 docker.for.mac.localhost &>/dev/null
if [ $? -eq 0 ]; then
    echo "Mac Host"
fi

ping -c 1 docker.for.win.localhost &>/dev/null
if [ $? -eq 0 ]; then
    echo "Windows Host"
fi;

I hope this helps you writing the script in PowerShell and please do share for whenever I need something like this in Windows.