'Can not start ContainerD container on Windows

I've been following Gentle ContainerD on Windows Guide For You to setup ContainerD on my Windows 10 machine but somehow I can not start any example from this tutorial.

Command is: crictl.exe runp --runtime runhcs-wcow-process .\pod-config.yaml Error is:

crictl.exe runp --runtime runhcs-wcow-process .\pod-config.yaml
time="2022-03-18T19:39:38+02:00" level=fatal msg="run pod sandbox: 
rpc error: code = Unknown desc = failed to setup network for sandbox \"7db0b08199861ffc0a68b869990c2ce1e2cee29df2579f9502ec584fbd5d2913\": plugin type=\"nat\" name=\"natContainerD\" failed (add): 
error creating endpoint hcnCreateEndpoint failed in Win32: IP address is either invalid or not part of any configured subnet(s). (0x803b001e) {\"Success\":false,\"Error\":\"IP address is either invalid or not part of any configured subnet(s). \",\"ErrorCode\":2151350302} : 
endpoint config &{ 7db0b08199861ffc0a68b869990c2ce1e2cee29df2579f9502ec584fbd5d2913_natContainerD 6160b2e0-4525-4bbc-b725-135c55fc741b  [] [{ 0}] { [] [] []} [{172.22.208.1 0.0.0.0/0 0}]  0 {2 0}}"

I guess I didn't configured my cni network right (?)

Here are steps what I did to setup network:

$subnet='10.0.0.0/16'
$gateway='10.0.0.1'
New-HnsNetwork -Type NAT -AddressPrefix $subnet -Gateway $gateway -Name "natContainerD"

Please note that I can not create network with name nat because it was already exist (from Docker ?) os I named this one as natContainerD

Then I configure the cni itself (as in tutorial above):

@"
{
    "cniVersion": "0.2.0",
    "name": "nat",
    "type": "nat",
    "master": "Internet",
    "ipam": {
        "subnet": "$subnet",
        "routes": [
            {
                "gateway": "$gateway"
            }
        ]
    },
    "capabilities": {
        "portMappings": true,
        "dns": true
    }
}
"@ | Set-Content "$env:ProgramFiles\containerd\cni\conf\0-containerd-nat.conf" -Force

However, no matter what settings I change in this file, I am still unable to start any containers :(

Any suggestion ?



Solution 1:[1]

Here are the steps I tried to install containerd on Windows Server 2022.

  1. Install Windows Features

    Add-WindowsFeature Containers,Hyper-V,Hyper-V-Tools,Hyper-V-PowerShell -Restart -IncludeManagementTools
    
  2. Install containerd 1.6.1

    # Download containerd 1.6.1
    curl.exe -LO https://github.com/containerd/containerd/releases/download/v1.6.1/containerd-1.6.1-windows-amd64.tar.gz
    
    tar xvf containerd-1.6.1-windows-amd64.tar.gz
    mkdir -force "C:\Program Files\containerd"
    mv ./bin/* "C:\Program Files\containerd"
    Remove-Item bin
    
    . "C:\Program Files\containerd\containerd.exe" config default | Out-File "C:\Program Files\containerd\config.toml" -Encoding ascii
    
    Add-MpPreference -ExclusionProcess "$Env:ProgramFiles\containerd\containerd.exe"
    
    . "$Env:ProgramFiles\containerd\containerd.exe" --register-service
    
    Start-Service containerd
    
    $env:PATH = "C:\Program Files\containerd;" + $env:PATH
    
  3. Configure container networking

    mkdir -force "C:\Program Files\containerd\cni\bin"
    mkdir -force "C:\Program Files\containerd\cni\conf"
    

    Download windows-container-networking-cni-amd64-v0.2.0.zip file from microsoft/windows-container-networking

    curl.exe -LO https://github.com/microsoft/windows-container-networking/releases/download/v0.2.0/windows-container-networking-cni-amd64-v0.2.0.zip
    Expand-Archive windows-container-networking-cni-amd64-v0.2.0.zip -DestinationPath "C:\Program Files\containerd\cni\bin" -Force
    Remove-Item windows-container-networking-cni-amd64-v0.2.0.zip
    

    You have to download the source code from microsoft/windows-container-networking repo and build your own nat.exe from the source. It because the binary version in the Releases are outdated. It will not working in WS2022. I created an issue here.

    Creating a nat network

    curl.exe -LO https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/windows/hns.psm1
    Import-Module ./hns.psm1
    
    $subnet="10.0.0.0/16"
    $gateway="10.0.0.1"
    New-HNSNetwork -Type NAT -AddressPrefix $subnet -Gateway $gateway -Name "nat"
    
    @"
    {
        "cniVersion": "0.2.0",
        "name": "nat",
        "type": "nat",
        "master": "Ethernet",
        "ipam": {
            "subnet": "$subnet",
            "routes": [
                {
                    "gateway": "$gateway"
                }
            ]
        },
        "capabilities": {
            "portMappings": true,
            "dns": true
        }
    }
    "@ | Set-Content "C:\Program Files\containerd\cni\conf\0-containerd-nat.conf" -Force
    

Running a container using ctr

  1. Check Windows version

    cmd /c ver
    
    Microsoft Windows [Version 10.0.20348.587]
    
  2. Pull mcr.microsoft.com/windows/nanoserver:ltsc2022 and hello-world images

    ctr.exe image pull mcr.microsoft.com/windows/nanoserver:ltsc2022
    ctr.exe image pull registry.hub.docker.com/library/hello-world:nanoserver-ltsc2022
    
  3. Run containers

    ctr.exe run mcr.microsoft.com/windows/nanoserver:ltsc2022 hello cmd /c echo Hello World
    ctr container rm hello
    
    ctr.exe run --rm registry.hub.docker.com/library/hello-world:nanoserver-ltsc2022 hello-world
    
    ctr run --cni --rm mcr.microsoft.com/windows/nanoserver:ltsc2022 test curl.exe -s https://ifconfig.co/
    

Running a Pod and Container using crictl

  1. Install crictl tool

    curl.exe -LO https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.23.0/crictl-v1.23.0-windows-amd64.tar.gz
    tar xvf crictl-v1.23.0-windows-amd64.tar.gz
    mv crictl.exe "C:\Program Files\containerd"
    
  2. Configure crictl config

    mkdir -Force "$home\.crictl"
    
    @"
    runtime-endpoint: npipe://./pipe/containerd-containerd
    image-endpoint: npipe://./pipe/containerd-containerd
    timeout: 10
    #debug: true
    "@ | Set-Content "$home\.crictl\crictl.yaml" -Force
    
    crictl.exe info
    
  3. Pull Pause container image (k8s.gcr.io/pause:3.6)

    crictl pull k8s.gcr.io/pause:3.6
    
  4. Creating a sandbox / Pod

    @"
    {
        "metadata": {
            "name": "hello-world-sandbox",
            "namespace": "default",
            "attempt": 1,
            "uid": "hdishd83djaidwnduwk28bcsb"
        },
        "log_directory": "/tmp"
    }
    "@ | Set-Content "pod-config.json" -Force
    
    mkdir C:\tmp
    
    $POD_ID=(crictl runp .\pod-config.json)
    
  5. Creating a container

    @"
    {
      "metadata": {
          "name": "hello-world:nanoserver-ltsc2022"
      },
      "image":{
          "image": "hello-world:nanoserver-ltsc2022"
      },
      "log_path":"hello-world.0.log"
    }
    "@ | Set-Content "container-config.json" -Force
    
    $CONTAINER_ID=(crictl create $POD_ID .\container-config.json .\pod-config.json)
    
  6. Start container

    crictl start $CONTAINER_ID
    
  7. Check logs in that container

    crictl logs $CONTAINER_ID
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (windows-amd64, nanoserver-ltsc2022)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run a Windows Server container with:
     PS C:\> docker run -it mcr.microsoft.com/windows/servercore:ltsc2022 powershell
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/get-started/
    
  8. Checking Pods and Containers

    crictl pods
    crictl ps -a
    
  9. Delete Container and Pod

    crictl rm $CONTAINER_ID
    crictl stopp $POD_ID
    crictl rmp $POD_ID
    

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Will Huang