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
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!