Software containers are a convenient way to run your applications in multiple isolated user-space instances. You can run containers on Linux or Windows Server public VM images, or on a Container-Optimized OS image. Containers allow your applications to run with fewer dependencies on the host virtual machine and run independently from other containerized applications that you deploy to the same virtual machine instance. These characteristics make containerized applications more portable, easier to deploy, and easier to maintain at scale.
This document describes some of the more common container technologies that you can use to run containers on Compute Engine instances. You can use these technologies on most of the public VM images that Google Compute Engine provides.
Run containers on Compute Engine when you need complete control over your container environment and your container orchestration tools. Alternatively, you can use Google Kubernetes Engine to simplify cluster management and container orchestration tasks so that you do not need to manage the underlying virtual machine instances.
Container technologies that run on Compute Engine
In general, Compute Engine instances can run almost any container technology or tool. You can run several different types of containers on modern Linux operating systems and you can also run Docker on Windows Server 2016 or later. The following list includes several common tools that you can use to run and manage containerized applications:
- Docker and rkt are two popular container technologies that allow you to easily run containerized applications.
- Kubernetes is a container orchestration platform that you can use to manage and scale your running containers across multiple instances or within a hybrid-cloud environment.
- Containers on Compute Engine is an easy way to deploy containers to Compute Engine VM instances or managed instance groups.
- You can convert your existing systems into LXD images and run them within Compute Engine virtual machine instances for a simple lift-and-shift migration solution. LXD runs on Ubuntu images.
Additionally, you can use Container Registry to manage container image versions. Container Registry serves as a central location to store and manage your container images before you deploy those images to Kubernetes on Compute Engine or to Google Kubernetes Engine clusters.
Container-optimized VM images
Compute Engine provides several public VM images that you can use to create instances and run your container workloads. Some of these public VM images have a minimalistic container-optimized operating system that includes newer versions of Docker, rkt, or Kubernetes preinstalled. The following public image families are designed specifically to run containers:
- Container-Optimized OS from Google
- Includes: Docker, Kubernetes
- Image project:
cos-cloud - Image family:
cos-stable
- CoreOS
- Includes: Docker, rkt, Kubernetes
- Image project:
coreos-cloud - Image family:
coreos-stable
- Ubuntu
- Includes: LXD
- Image project:
ubuntu-os-cloud - Image family:
ubuntu-1604-lts
- Windows
- Includes: Docker
- Image project:
windows-cloud - Image family:
windows-1809-core-for-containers
If you need to run specific container tools and technologies on images that do not include them by default, install those technologies manually.
Installing container technologies on your instances
To launch a single container on an instance, you can specify a container image when you create an instance. Compute Engine automatically supplies an up-to-date Container-Optimized OS image with Docker installed and launches your container when the VM starts up. See Deploying Containers on VMs for more information.
Alternatively, you can run your container workloads on Compute Engine using whatever container technologies and orchestration tools that you need. You can create an instance from a public VM image and then install the container technologies that you want. For example:
- Install Docker on Compute Engine instances so that you can run your Docker container images on those instances.
- Install rkt on Compute Engine instances as an alternative to the Docker container runtime.
- Install Kubernetes on your instances to provide container orchestration for both Docker and rkt containers.
In some situations, you might require specific versions of these technologies to ensure that they operate together correctly. For example, Kubernetes usually runs best with specific versions of Docker. Typically, you can install the latest versions of these technologies for the best result.
Installing Docker on Windows Server images
Windows Server 2016 and later versions include container support. If you plan to run Docker containers on a Windows Server instance, Google recommends starting with the Windows Server for Containers public image. This image has the following components installed:
Microsoft's
servercoreandnanoservercontainer images.All required fixes for known issues.
If you want to install Docker on the Windows Server base image and run containerized applications, instead of using the Windows Server for Containers image, then follow the steps outlined below.
Start by creating a Windows Server instance using a Windows Server 2016 or later public image. For the best container support Google recommends that you use the most recent semi-annual release of Windows Server, such as Windows Server, version 1809.
Install Docker
Open a PowerShell terminal as an administrator.
Install Docker from the Microsoft repositories:
PS C:\> Install-Module -Name DockerMsftProvider -Repository PSGallery -ForcePS C:\> Install-Package -Name docker -ProviderName DockerMsftProviderRun the following commands to work around known issues with Windows containers on Compute Engine:
Disable Receive Segment Coalescing:
PS C:\> netsh netkvm setparam 0 *RscIPv4 0Enable IPv6:
PS C:\> reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters ` /v DisabledComponents /t REG_DWORD /d 0x0 /f
Restart the instance:
PS C:\> Restart-Computer -Force
Additional setup steps
At this point you can use Docker to run containers in the instance. For example,
the following command downloads the Windows nanoserver container image and
runs a command prompt inside a nanoserver container:
PS C:\> docker run -it mcr.microsoft.com/windows/nanoserver:1809 cmd.exe
Note that there is a known issue with Docker's default network MTU that affects
connectivity to the instance and connectivity from containers to the Internet.
To work around this issue, first run the following commands in a PowerShell
terminal on the instance to set the MTU for all network interfaces (both
Ethernet and vEthernet) to 1460:
PS C:\> Get-NetAdapter | Where-Object Name -like "*Ethernet*" | ForEach-Object {
& netsh interface ipv4 set subinterface $_.InterfaceIndex mtu=1460 store=persistent
}
PS C:\> netsh interface ipv4 show subinterfaces MTU MediaSenseState Bytes In Bytes Out Interface ------ --------------- --------- --------- ------------- 4294967295 1 0 0 Loopback Pseudo-Interface 1 1460 1 306804 668688 Ethernet 1460 1 0 1282 vEthernet (nat)
Even after repairing the instance's MTU, connectivity from containers to the
Internet may be unstable because the container's network interface will also use
an MTU of 1500 by default. Read the container MTU section
for commands to set the MTU correctly for every container.
You may need to periodically re-execute these MTU commands as you configure Docker networking. Read the known issues section for full details.
Running Windows containers
There are many resources available for getting started with Windows containers:
- The Running Windows Containers on Compute Engine codelab provides an introduction to Windows containers on Compute Engine.
- Microsoft provides extensive Windows Containers Documentation.
- Docker Hub can be used as a repository for storing and pulling Windows containers.
Known issues with Windows containers
Containers are incompatible across Windows versions
Containers built on older versions of Windows will not work in Compute Engine instances running more recent versions of Windows. Docker pulls the Windows Server 2016 version of a container by default. This means that running the following command in an instance running Windows Server, version 1709 or newer will result in an error:
PS C:\> docker run -it microsoft/nanoserver cmd.exe docker: Error response from daemon: container 9a1eb8bbcba4e91792be65f3c40b5a1aee062f02fbc60a78444b47d043438069 encountered an error during CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101)
Microsoft's Windows Container Version
Compatibility
page contains more information. To work around Windows container version
incompatibilities, be sure to specify the tag corresponding to your Windows
version when pulling and running containers. For example, in a Windows Server,
version 1809 instance use the following command to run a command prompt in the
version 1809 nanoserver container instead of the default 2016 container:
PS C:\> docker run -it microsoft/nanoserver:1809 cmd.exe
MTU incompatibilities affect instance and container connectivity
When you create a container network on a Windows instance using the docker
network create or New-VMSwitch commands, the MTU of the instance's network
interface is typically forced to
1500. The default network
interface inside of a new Docker container also typically uses an MTU of
1500. Google Cloud Platform supports an
MTU of only 1460, so when the MTU is forced to 1500 you might experience the
following issues:
The RDP session can stop and you might be unable to reconnect. This is known to happen when creating a transparent container network.
DNS resolution inside the container might fail.
DNS resolution is successful, but establishing an HTTP connection from the container to the Internet might fail.
Working around these limitations requires two steps: setting the MTU for the instance's network interfaces and setting the MTU for the container network interfaces.
1. Setting the MTU for the Windows instance's network interfaces
Run the following command in a PowerShell terminal on the Windows instance to set the MTU for all network interfaces (both Ethernet and vEthernet):
PS C:\> Get-NetAdapter | Where-Object Name -like "*Ethernet*" | ForEach-Object {
& netsh interface ipv4 set subinterface $_.InterfaceIndex mtu=1460 store=persistent
}
Check that the instance's Ethernet and vEthernet interface MTUs are set to
1460 using this command:
PS C:\> netsh interface ipv4 show subinterfaces MTU MediaSenseState Bytes In Bytes Out Interface ------ --------------- --------- --------- ------------- 4294967295 1 0 0 Loopback Pseudo-Interface 1 1460 1 628295912 2613170 Ethernet 1460 1 37793 223909 vEthernet (nat)
If you are unable to run these commands because you can no longer connect to
an instance via RDP, you can can connect to the instance through the serial
console, start a cmd
prompt and run the netsh commands there to repair the MTU. To avoid having to
do this we recommend executing any docker network ... or New-VMSwitch
commands as part of a script that also executes the MTU repair command.
2. Setting the MTU for the Windows container network interfaces
The MTU for a Windows container must be set while the container is running, either from inside the container or from the instance hosting the container. If PowerShell is available in your container, you can run this command interactively or from a script in the container to correctly set the MTU:
PS C:\> Get-NetAdapter | Where-Object Name -like "vEthernet*" | ForEach-Object {
& netsh interface ipv4 set subinterface $_.InterfaceIndex mtu=1460 store=persistent
}
Or, you can run this command on the Windows instance to set the MTU for all running containers:
PS C:\> Get-NetIPInterface -IncludeAllCompartments |
Where-Object InterfaceAlias -like "vEthernet*" |
Set-NetIPInterface -IncludeAllCompartments -NlMtuBytes 1460
Docker containers fail to start
Starting a container with docker run can fail with the following error:
C:\Program Files\Docker\docker.exe: Error response from daemon: container ... encountered an error during CreateContainer: failure in a Windows system call: Element not found. (0x490)
This issue occurs on Windows Server 2016 instances with Windows Update KB4015217 installed. To work around the problem, enable IPv6 on the instance using the following PowerShell command:
PS C:\> reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters `
/v DisabledComponents /t REG_DWORD /d 0x0 /f
After you enable IPv6, restart the instance:
PS C:\> Restart-Computer -Force
If this issue is corrected in future operating system updates, you can restore the original IPv6 setting:
PS C:\> reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters `
/v DisabledComponents /t REG_DWORD /d 0xff /f
Hyper-V containers fail to start
Hyper-V containers are not supported on Compute Engine at this time.
What's next
- Create and start an instance that you can use to run container applications.
- Learn about Compute Engine instances.
- Learn more about Google Kubernetes Engine, which you can use to easily run your containers on Google Cloud Platform without managing Compute Engine instances yourself.
- Learn more about Kubernetes.
- Learn how to use Container Registry to store your container images privately within Google Cloud Platform.


