Instalando ContainerD, Nerdctl e WCN n Windows Container

Ola Pessoal,

Neste post vou mostrar como instalar e preparar uma maquina windows rodar um windows container.
Entretanto, não iremos utilizar o Docker. Nos iremos utilizar um combo com ContainerD, Nerdctl e CNI com windows container networking.

No primeiro momento, você vai pensar, Leandro por que você esta fazendo essa mistura com muitas soluções para poder rodar um container no windows?

Primeiro,  a Microsoft ao poucos esta se desvinculando do Docker para rodar containers e depois que o Docker foi comprado pela Mirantis, a Microsoft começou a foca no containerD para seus produtos.

No presente momento, enquanto estou escrevendo isso em 2023, não foi disponibilidade uma forma oficial de instalar o containerd no Windows como um instalador ou usando alguma fonte de repositório como winget ou chocolatey.
Com isso, decide, criar esse scrip para fazer a instalacao e configuração para sua operação básica.

Nerdctl: Software para gerenciar os container que irão rodar no containerD
WCN (windows container networking): Sofware responsável pela conectividade de rede, conhecido como CNI.

Versões utilizadas para testar o script, que foram utilizadas em 2023:

Nerdctl: 1.4.0
ContainerD: 1.7.2
WCN: 0.3.0
Windows Server: 2022 com atualizações de junho de 2023 instaladas.
PowerShell: 5.1
Powershell Module: HNS


Neste post, irei explicar o que o script faz, e que vai além do que os scritps disponibilizados pela Microsoft e ContainerD não faz.

0- Baixar os script: curl.exe -LO https://raw.githubusercontent.com/leandroscardua/Windows-Containerd/master/install_containerd.ps1 , para executar roda o script com esse comando: .\install_containerd.ps1

1- O script abaixo, verifica as ultimas versões disponíveis, do nerdctl, containerd e windows container networking, se você quiser você pode selecionar uma versão especifica para cada um deste componentes.

2- Verificar se a função container esta instalada, se não, a execução do script sera interrompida, sendo necessário manualmente rodar o comando: Install-WindowsFeature -Name Containers

3- O script ira baixar a versao do containerD e ire executa algumas funcoes para instalar e configurar o containerD corretamente, isso vai executar essa mesma funcoes para o Nerdctl e windows container networking.

4- Para parte de rede, como temos que escolher um CNI compatível com windows, vamos utilizar o windows container networking, que e compatível com nerdctl e containerD, isso vai baixar um module me Powershell para poder adicionar um rede virtual dentro do windows, para criar um adaptador para funcionar em modo NAT, no momento o único suportado.

5- Com isso, se ambiente esta pronto para utilizar o containerD, voce ja pode baixar as imagens rodando por exemplo: ./nerdctl.exe pull mcr.microsoft.com/windows/nanoserver:ltsc2022 e para criar o container com a imagem que voce criou conectado na rede virtual criada anteriormente rode o comando: ./nerdctl.exe run -it –net nat mcr.microsoft.com/windows/nanoserver:ltsc2022

Fica a vontade, para usar o script abaixo e se tiver duvidas ou sugestões, pode abrir um issue no github.

<#
.SYNOPSIS
Script to install and configure windows container with containerD, nerdctl and WCN for CNI

.DESCRIPTION
Installs the prerequisites for creating Windows containers with containerd, nerdctl and windows-container-networking, using the latest available version

.LINK
https://raw.githubusercontent.com/leandroscardua/Windows-Containerd/master/install_containerd.ps1

.EXAMPLE
curl.exe -LO https://raw.githubusercontent.com/leandroscardua/Windows-Containerd/master/install_containerd.ps1
.\install_containerd.ps1
#>

#Requires -RunAsAdministrator

[CmdletBinding()]
param(

[ValidateNotNullOrEmpty()]
[String]$tagcd = ((Invoke-WebRequest -UseBasicParsing "https://api.github.com/repos/containerd/containerd/releases/latest" | ConvertFrom-Json)[0].tag_name -replace "v",""),

[ValidateNotNullOrEmpty()]
[String]$tagcni = ((Invoke-WebRequest -UseBasicParsing "https://api.github.com/repos/microsoft/windows-container-networking/releases/latest" | ConvertFrom-Json)[0].tag_name -replace "v",""),

[ValidateNotNullOrEmpty()]
[String]$tagnerdctl = ((Invoke-WebRequest -UseBasicParsing "https://api.github.com/repos/containerd/nerdctl/releases/latest" | ConvertFrom-Json)[0].tag_name -replace "v",""),

[ValidateNotNullOrEmpty()]
[String]$subnet='10.0.0.0/24',

[ValidateNotNullOrEmpty()]
[String]$gateway='10.0.0.1'

)


Write-Host "Checking the latest version of containerd and Windows CNI" -ForegroundColor DarkCyan
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Write-Host "Checking for the Windows Feature is already installed" -ForegroundColor DarkCyan

$feature = Get-WindowsFeature -Name Containers

if($feature.Installed -eq 'True') {
Write-Host "Installed" -ForegroundColor DarkGreen
}else{
Write-Host "Please, Install Windows Feature and run the script again. (Install-WindowsFeature -Name Containers)" -ForegroundColor DarkRed
exit
}


function DownloadFile {

param (
[String]$source,
[String]$outfile
)

Invoke-WebRequest $source -UseBasicParsing -OutFile $outfile

}

$destination="$Env:ProgramFiles\containerd"
Write-Host "Creating folder on $destination" -ForegroundColor DarkCyan
mkdir -force $destination | Out-Null
Set-Location $destination


Write-Host "Downloading ContainerD to $destination" -ForegroundColor DarkCyan
DownloadFile "https://github.com/containerd/containerd/releases/download/v$tagcd/containerd-$tagcd-windows-amd64.tar.gz" "$destination\containerd-$tagcd-windows-amd64.tar.gz"
Write-Host "Saving containerd on $destination" -ForegroundColor DarkCyan

tar.exe -xf .\containerd-$tagcd-windows-amd64.tar.gz

Copy-Item -Path "$destination\bin\*" -Destination $destination -Recurse -Force

Write-Host "Creating containerd config file" -ForegroundColor DarkCyan

.\containerd.exe config default | Out-File config.toml -Encoding ascii

Write-Host "Registering containerd as a service" -ForegroundColor DarkCyan

.\containerd.exe --register-service

Write-Host "Starting containerd service" -ForegroundColor DarkCyan

Start-Service containerd

Write-Host "Downloading Windows CNI to $destination\cni\bin" -ForegroundColor DarkCyan

mkdir -force $destination\cni\bin | Out-Null
Set-Location $destination\cni\bin
DownloadFile "https://github.com/microsoft/windows-container-networking/releases/download/v$tagcni/windows-container-networking-cni-amd64-v$tagcni.zip" "$destination\cni\bin\windows-container-networking-cni-amd64-v$tagcni.zip"

Write-Host "Saving Windows CNI on $destination" -ForegroundColor DarkCyan

tar.exe -xf $destination\cni\bin\windows-container-networking-cni-amd64-v$tagcni.zip

Write-Host "Downloading nerdctl to $destination" -ForegroundColor DarkCyan

Set-Location $destination
Invoke-WebRequest "https://github.com/containerd/nerdctl/releases/download/v$tagnerdctl/nerdctl-$tagnerdctl-windows-amd64.tar.gz" -UseBasicParsing -OutFile $destination\nerdctl-$tagnerdctl-windows-amd64.tar.gz

Write-Host "Saving nerdctl on $destination" -ForegroundColor DarkCya

tar.exe -xf $destination\nerdctl-$tagnerdctl-windows-amd64.tar.gz

Write-Host "Downloading HNS Powershell Module" -ForegroundColor DarkCyan

DownloadFile "https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/windows/hns.psm1" $destination\hns.psm1
Import-Module .\hns.psm1

Write-Host "Creating New NAT Network" -ForegroundColor DarkCyan

New-HnsNetwork -Type NAT -AddressPrefix $subnet -Gateway $gateway -Name "nat"

Write-Host "Configuring network on nerdctl using NAT Network" -ForegroundColor DarkCyan

mkdir -Force "$env:ProgramFiles\containerd\cni\conf\"| Out-Null

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


# Download nanoserver version ltsc2022 image

# .\nerdctl.exe pull mcr.microsoft.com/windows/nanoserver:ltsc2022

# Run a test container using the nanoserver version ltsc2022 image

# .\nerdctl.exe run -it --net nat mcr.microsoft.com/windows/nanoserver:ltsc2022

 

 


Referencias:

– https://learn.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=containerd#install-the-container-runtime
– https://github.com/containerd/containerd/blob/main/docs/getting-started.md#installing-containerd-on-windows
– https://blog.devgenius.io/gentle-containerd-on-windows-guide-for-you-50d4a46daccf
– https://lippertmarkus.com/2022/01/22/containerd-ctr-windows/