Search code examples
windowscontainerd

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

  • 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