Hosting A Linux Container On Windows EC2 Instance

Problem statement: Linux Container on Windows EC2 instance in AWS

When we saw this, we thought, "We should be able to do it ... cross-platform, containers ... sounds about right!". Little did we know about the limitations in terms of cross-platform hosting of containers and what needed to be done at the backend to support that kind of setup. So, if you are here, you are in the same boat as me and hopefully, this blog can save a lot of your time and effort to achieve this. 

So, with the problem statement defined, we are basically trying to create a container on top of an already virtualized machine a.k.a Nested Virtualization. Nested virtualization is a feature that allows you to run Hyper-V inside of a Hyper-V virtual machine (VM). If this were a physical server, we would have fewer constraints as we could easily reach the physical server BIOS and make the required configuration to enable Nested Virtualization. Hence, for Windows EC2 configurations, we had to do research and conduct POC to establish what works and what doesn't. So, we are going to go through the steps that worked for us and you could follow the same if you are trying to replicate a similar setup. 

Step 1 - Create the right EC2

Bare Metal EC2 Instances are the only instances that support the nested virtualization feature. If we really want to use Hyper-V on Windows on an EC2 instance, we must use a bare-metal instance type such as c5.metal or m5d.metal, etc. 

AMI: Hyper-V Server on Windows Server 2019 or any other Hyper-V server available in AWS Marketplace

Instance Type: Bare Metal

** All commands from hereon, are executed in PowerShell using the Run As Admin option. 

Step 2 - Validate Hyper-V and Container Features

  • Check if the required Hyper-V features are available and installed
    Get-WindowsFeature Hyper*
  • If features exist, it will show like this below. It means the feature is there but not installed.

  • Install the features and enable if you get a screen as shown above. If you get [ X ] marked against the features, it means that they are already installed and this step can be skipped.
    Enable-WindowsOptionalFeature –Online -FeatureName Microsoft-Hyper-V –All -NoRestart
    Install-WindowsFeature RSAT-Hyper-V-Tools -IncludeAllSubFeature
    Install-WindowsFeature Containers
    Restart-Computer

Step 3 - Install Docker EE

Install-Module "DockerMsftProvider" -Force
Update-Module "DockerMsftProvider"
Install-Package Docker -ProviderName "DockerMsftProvider" -Update -Force

Step 4 - Run Windows Container

Set-Content -Value "`{`"experimental`":true`}" -Path C:\ProgramData\docker\config\daemon.json
restart-service docker
docker pull mcr.microsoft.com/windows/nanoserver:1809
docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe

After executing the last command, you should see a Windows command prompt open up in the container. But we are not interested in this one. We are looking for a Linux container to be operational.

Step 5 - Configure Linux Container

cd 'C:\Program Files\'
mkdir "Linux Containers"
cd '.\Linux Containers\'
curl -OutFile release.zip https://github.com/linuxkit/lcow/releases/download/v4.14.35-v0.3.9/release.zip
Expand-Archive -DestinationPath . .\release.zip
rm release.zip
[Environment]::SetEnvironmentVariable("LCOW_SUPPORTED", "1", "Machine")
docker info

On running the above command, you will see an output similar to the one shown on the below screen. Ensure there is an entry now for LCOW in Storage Driver.

Step 6 - Run Linux Container

docker pull centos
docker run -it --platform=linux centos

Once you run the above command, you should see a Linux session started on the container as shown in the below screenshot,

That's it! If you follow the above steps, you should have a Linux container fully operational on your EC2. You can also create named instances of Linux containers using steps mentioned below,

Get Image Id for the container - docker images

docker container run --name container-01 <image_id>

I hope this blog will save you some time trying to figure out how to make this work on an AWS Windows EC2 instance. 

Happy Building!