Tuesday, October 18, 2016

First steps with Microsoft Containers - part 2

As I said in the previous post, Docker is required in order to work with Windows containers. The source can be downloaded and installed in a couple simple steps:
Invoke-WebRequest "https://get.docker.com/builds/Windows/x86_64/docker-latest.zip" -OutFile "$env:TEMP\docker-latest.zip" -UseBasicParsing

Expand-Archive $env:TEMP\docker-latest.zip -DestinationPath $env:ProgramFiles

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", [EnvironmentVariableTarget]::Machine)
Closed and reopen PowerShell, then:
& $env:ProgramFiles\docker\dockerd.exe --register-service

Start-Service docker
There you are.


Once you have installed Docker on Windows, you can explore the possible parameters:

Usage: docker [OPTIONS] COMMAND [arg...]
       docker [ --help | -v | --version ]

A self-sufficient runtime for containers.


  --config=%USERPROFILE%\.docker              Location of client config files
  -D, --debug                                 Enable debug mode
  -H, --host=[]                               Daemon socket(s) to connect to
  -h, --help                                  Print usage
  -l, --log-level=info                        Set the logging level
  --tls                                       Use TLS; implied by --tlsverify
  --tlscacert=%USERPROFILE%\.docker\ca.pem    Trust certs signed only by this CA
  --tlscert=%USERPROFILE%\.docker\cert.pem    Path to TLS certificate file
  --tlskey=%USERPROFILE%\.docker\key.pem      Path to TLS key file
  --tlsverify                                 Use TLS and verify the remote
  -v, --version                               Print version information and quit

    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Export a container's filesystem as a tar archive
    history   Show the history of an image
    images    List images
    import    Import the contents from a tarball to create a filesystem image
    info      Display system-wide information
    inspect   Return low-level information on a container, image or task
    kill      Kill one or more running containers
    load      Load an image from a tar archive or STDIN
    login     Log in to a Docker registry.
    logout    Log out from a Docker registry.
    logs      Fetch the logs of a container
    network   Manage Docker networks
    node      Manage Docker Swarm nodes
    pause     Pause all processes within one or more containers
    port      List port mappings or a specific mapping for the container
    ps        List containers
    pull      Pull an image or a repository from a registry
    push      Push an image or a repository to a registry
    rename    Rename a container
    restart   Restart a container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save one or more images to a tar archive (streamed to STDOUT by default)
    search    Search the Docker Hub for images
    service   Manage Docker services
    start     Start one or more stopped containers
    stats     Display a live stream of container(s) resource usage statistics
    stop      Stop one or more running containers
    swarm     Manage Docker Swarm
    tag       Tag an image into a repository
    top       Display the running processes of a container
    unpause   Unpause all processes within one or more containers
    update    Update configuration of one or more containers
    version   Show the Docker version information
    volume    Manage Docker volumes
    wait      Block until a container stops, then print its exit code

Run 'docker COMMAND --help' for more information on a command.

Have a look at each parameter, they are easily understood. The key commands to start with are 'pull' and 'run'. The first one is used to pull an image from the Docker public registry, which is basically a repo of all the images found on the Docker Hub (https://hub.docker.com/):

The second one is used to bring up the Container, and is often used in conjunction with the -it switches, where 'i' makes it interactive and 't' opens a pseudo terminal. You can also directly start a Container with run without pulling it from the registry first: the Docker client will do it for you.


If, like me, you are behind a corporate proxy, and aren't able to connect directly to the internet, you have two alternatives: either downloading the two classical Microsoft Containers from https://aka.ms/tp5/6b/docker/nanoserver or https://aka.ms/tp5/6b/docker/windowsservercore or use the Start-BitsTransfer cmdlet, which is used to replace Install-ContainerOSImage (this has been removed, as I said in the previous post).

Start-BitsTransfer https://aka.ms/tp5/6b/docker/nanoserver -Destination nanoserver_10.0.14300.1030_4.tar.gz

docker load -i .\nanoserver_10.0.14300.1030_4.tar.gz
Once you get the message 'Loaded image: microsoft/nanoserver:10.0.14300.1030' you are good to use the NanoServer image:
docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
microsoft/nanoserver   10.0.14300.1030     3a703c6e97a2        4 months ago        969.8 MB
The tag here is important, because, in case of multiple images, you can refer to it by the tag.


Nothing simpler:

docker run -it microsoft/nanoserver:10.0.14300.1030 powershell


Now, a common beginner mistake, if you try to run the NanoServer Container on a full Windows 2016 Server, you get:

docker run -it microsoft/nanoserver:10.0.14300.1030 powershell
C:\Program Files\Docker\docker.exe: Error response from daemon: container 379f187cf37ff65df4ffbc4cc2dc98441a7e932443f155596f17f4e066c1585c encountered an error during CreateContainer failed in Win32: The operating system of the container does not match the operating system of the host.
(0xc0370101) extra info:{"SystemType":"Container","Name":"379f187cf37ff65df4ffbc4cc2dc98441a7e932443f155596f17f4e066c1585c","Owner":"docker","IsDummy":false,"VolumePath":"\\\\?\\Volume{4d073ac2-946711e6ae0a005056836799}","IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\docker\\windowsfilter\\379f187cf37ff65df4ffbc4cc2dc98441a7e932443f155596f17f4e066c1585c","Layers"[{"ID":"115df3f3089b5f51ba901cf50b70e57a","Path":"C:\\ProgramData\\docker\\windowsfilter\\15d854d2cf0ddc892b511b920988221ff68e683df8c71c858d72fe151117b027"}],"HostName":"379f187cf37f","MappedDirectories":[],"SandboxPath":"","HvPartition":false,"EndpointList":["5f95dbcb-2bcc-44e8-a13d-2a91b97ec0ac"],"HvRuntime":null,"Servicing":false}.
As you remember from the previous post, containers are operating system level virtualization, so Nano Server core can only run as a Hyper-V container if the Container host is a full Windows 2016, or as a Windows Container, if the Container host is a NanoServer. Simple matching of kernels.

docker run -it --isolation hyperv microsoft/nanoserver:10.0.14300.1030 powershell
The second common mistake is that, if you don't have the Hyper-V feature installed and try to install a Hyper-V Container, you'll get the following error:

docker run -it --isolation hyperv microsoft/nanoserver:10.0.14300.1030 powershell
C:\Program Files\Docker\docker.exe: Error response from daemon: container cd93f27118a2e80964e4162b8d107a39fd78b7c0de3e2f
6e5377c4f998118c36 encountered an error during CreateContainer failed in Win32: No hypervisor is present on this system.
(0xc0351000) extra info: {"SystemType":"Container","Name":"cd93f27118a2e80964e4162b8d107a39fd78b7c0de3e2f6e5377c4f998118c36","Owner":"docker","IsDummy":false,"VolumePath":"","IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\docker\\windowsfilter\\cd93f27118a2e80964e4162b8d107a39fd78b7c0de3e2f6e5377c4f998118c36","Layers":[{"ID":"115df3f3-089b-5f51ba901cf50b70e57a","Path":"C:\\ProgramData\\docker\\windowsfilter\\15d854d2cf0ddc892b511b920988221ff68e683df8c71c858d72fe151117b027"}],"HostName":"cd93f27118a2","MappedDirectories"[],"SandboxPath":"C:\\ProgramData\\docker\\windowsfilter","HvPartition":true,"EndpointList"["977f140941694fb786ff4abb20316975"],"HvRuntime"{"ImagePath":"C:\\ProgramData\\docker\\windowsfilter\\15d854d2cf0ddc892b511b920988221ff68e683df8c71c858d72fe151117b027\\UtilityVM"},"Servicing":false}.
Installing Hyper-V will solve this in a breeze.


Docker relies on the microsoft/hccshim package to call the Host Compute Service (vmcompute.dll) to run Windows Containers. When the service starts (dockerd.exe) a network setup occurs and a vmswitch is configured. This vmswitch is managed by the Host Network Service (HNS) subsytem which is in charge of the IPAM role.

In my labs I have often encoutered a bug that prevent the Docker service from starting because the HNS subsytem is unable to do all the network setup:

time="2016-10-18T02:21:35.312426300+02:00" level=info msg="Windows default isolation mode: process"
time="2016-10-18T02:21:35.339425700+02:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
time="2016-10-18T02:21:35.339425700+02:00" level=info msg="Loading containers: start."
time="2016-10-18T02:21:35.393424100+02:00" level=error msg="Resolver Setup/Start failed for container none, \"json: cann ot unmarshal array into Go value of type hcsshim.HNSNetwork\""
Error starting daemon: Error initializing network controller: Error creating default network: HNS failed with error : Unspecified error
It looks like this issue should be solved installing a cumulative update for Windows 10 Version 1607 and Windows Server 2016: October 11, 2016 (aka 9D).

In my case installing this patch, as well all the others in the standard channel, did not solve my issue:


Source         Description      HotFixID      InstalledBy          InstalledOn
------         -----------      --------      -----------          -----------
SRV1           Update           KB3176936     NT AUTHORITY\SYSTEM  18/10/2016 00:00:00
SRV1           Update           KB3192137     NT AUTHORITY\SYSTEM  12/09/2016 00:00:00
SRV1           Update           KB3199209     NT AUTHORITY\SYSTEM  18/10/2016 00:00:00
SRV1           Security Update  KB3194798     NT AUTHORITY\SYSTEM  18/10/2016 00:00:00
I will post un update as soon as I find out more, but in the mean time you can check the open issue on GitHub.
More on Docker in the next post.

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...