无法在 Windows 上启动 ContainerD 容器

Can not start ContainerD container on Windows

我一直在按照 Gentle ContainerD on Windows Guide For You 在我的 Windows 10 机器上安装 ContainerD,但不知何故我无法从本教程开始任何示例。

命令是:crictl.exe runp --runtime runhcs-wcow-process .\pod-config.yaml 错误是:

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}}"

我想我没有正确配置 cni 网络 (?)

以下是我设置网络的步骤:

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

请注意,我无法创建名称为 nat 的网络,因为它已经存在(来自 Docker?)os 我将其命名为 natContainerD

然后我配置 cni 本身(如上面的教程):

@"
{
    "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[=13=]-containerd-nat.conf" -Force

但是,无论我在此文件中更改什么设置,我仍然无法启动任何容器:(

有什么建议吗?

以下是我尝试在 Windows Server 2022 上安装 containerd 的步骤。

  1. 安装Windows 功能

    Add-WindowsFeature Containers,Hyper-V,Hyper-V-Tools,Hyper-V-PowerShell -Restart -IncludeManagementTools
    
  2. 安装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. 配置容器网络

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

    microsoft/windows-container-networking

    下载 windows-container-networking-cni-amd64-v0.2.0.zip 文件
    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.

    正在创建 nat 网络

    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[=14=]-containerd-nat.conf" -Force
    

运行使用 ctr

安装容器
  1. 检查Windows版本

    cmd /c ver
    
    Microsoft Windows [Version 10.0.20348.587]
    
  2. 拉取 mcr.microsoft.com/windows/nanoserver:ltsc2022hello-world 个图像

    ctr.exe image pull mcr.microsoft.com/windows/nanoserver:ltsc2022
    ctr.exe image pull registry.hub.docker.com/library/hello-world:nanoserver-ltsc2022
    
  3. 运行 个容器

    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/
    

运行使用 crictl

设置 Pod 和容器
  1. 安装crictl工具

    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. 配置crictl配置

    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. Pause container image (k8s.gcr.io/pause:3.6)

    crictl pull k8s.gcr.io/pause:3.6
    
  4. 正在创建沙箱/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. 创建容器

    @"
    {
      "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. 启动容器

    crictl start $CONTAINER_ID
    
  7. 检查该容器中的日志

    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. 正在检查 Pods 和容器

    crictl pods
    crictl ps -a
    
  9. 删除容器和 Pod

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