If we create an instance of an image in interactive mode, and run a PowerShell console in it, then we can see inside the container.
In a previous post I used the Nano Server image, because it is small and quick. But Nano Server is a cut down OS so, for the purposes of seeing how a container works, let’s take a look inside a Windows Server Core container. The question of when Nano Server can be used in place of Core is a subject for another time.
The Docker command to do this is:
docker run --rm -it --name core microsoft/windowsservercore powershell
The system information, with systeminfo
, shows a Windows server where some of the properties belong to the container, and some to the host. For example, the language and locale belong to the container, but the BIOS and boot time belong to the host:
The TCP/IP information, with ipconfig /all
shows that the container has its own:
- hostname
- Hyper-V virtual ethernet adapter
- MAC address
- IP address in the private Class B subnet, which we saw previously was allocated to the Hyper-V virtual switch
- gateway, which we saw previously was the Hyper-V virtual ethernet adapter on the host
- DNS server addresses.
I can connect to the outside world, with ping 8.8.8.8
and get a reply:
The running processes, from Get-Process
, show the PowerShell process, as well as what look like typical user processes. If I run Get-Process | Sort-Object SI
I can see that there are two sessions: a system session in Session 0, and a user session in Session 2.
I can start other processes. For example, if I start Notepad, then I see it running as a new process in Session 2.
The services, from Get-Service
, show normal system services. It is easier to see if I filter for running services, with:
Get-Service | Where-Object {$_.Status -eq "Running"} | Sort-Object DisplayName
I have listening ports, shown with Get-NetTCPConnection
, but nothing connected:
There are three local user accounts, shown with Get-LocalUser
:
PowerShell tells me that it is being executed by the user ContainerAdministrator:
In summary, I have something that looks similar to an operating system running a user session. It can start a new process and it can communicate with the outside world.
Let’s see what it looks like from outside. From the host I can ping the container:
I can telnet from the host to port 135 (one of the ports that I saw was listening) in the container, and make a connection:
But I can’t make a connection from outside the host. I already know there is no route to the container subnet. What happens if I supply a route? Still no reply. I am not really surprised. The connection would have to go through the host, and there is nothing in the host firewall to allow a connection to the container.
If I start another container, though, it can ping and get a reply from the first container:
If I look in Task Manager on the host, there is no obvious object that looks like a container. I don’t even know what size I would expect it to be. But I notice that the PowerShell process in the container shows as the same process on the host.
Get-Process PowerShell
in the container:
Get-Process PowerShell
on the host:
The process ID 3632 is the same process. All three PowerShell processes, including the one in the container, are using the same path to the executable. You could say that the container is a virtual bubble (session, namespace or whatever you want to call it) executing processes on the host:
If I look at all the processes on the host, I can see that the container’s Session 2 is also Session 2 on the host. Here are the host processes filtered by session:
Get-Process | Where-Object {$_.SI -eq 0 -or $_.SI -eq 2} | Sort-Object SI
Session 0 (the System session) has a lot more processes than shown inside the container, but Session 2 is the same. Processes like lsass, wininit, csrss are the normal processes associated with a session.
The host does not see the user who is executing the processes. In the container the user is ContainerAdministrator, but there is no such user on the host, and the host does not have the username:
A container is ephemeral. But if I create files inside the container they must be stored somewhere.
In the image folder of the host I can see a new layer has been created:
The layerchain.json file tells me that the layer is chained to the Windows Server Core base image layers. The layer has a virtual hard disk drive called “sandbox”, which sounds like the kind of place that changes would be saved.
If I look in Disk Manager, I can see that a new hard disk drive has been attached to the host:
The disk is the same size as the apparent system drive inside the container. It is shown as Online, but with no drive letter. However, if I give it a drive letter, then I can see the same file system that I was able to see inside the container:
So the file system of the container is created by mounting a Hyper-V virtual hard disk drive. This only exists for the lifetime of the container. When the container is removed, any changes are lost.
In summary:
- From inside, the container appears to have similar properties to a normal virtual machine.
- The container has a network identity, with a host name, virtual Ethernet adapter and IP address.
- It can connect to the outside world, and with other containers, but the outside world cannot (until we change something) connect to it.
- It has a file system, based on the image the container was created from.
- On the host, the container processes are implemented as a distinct session.
- The file system of the container is implemented as a virtual hard disk drive attached to the host.
- Files can be saved to the virtual hard disk drive, but they are discarded when the container is removed.