1+ <#
2+ . SYNOPSIS
3+ Installs ContainerD on a Windows machines in preperation for joining the node to a Kubernetes cluster.
4+
5+ . DESCRIPTION
6+ This script
7+ - Verifies that Windows Features requried for running contianers are enabled (and enables then if they are not)
8+ - Downloads ContainerD binaries from from at the version specified.
9+ - Downloads Windows SND CNI plugins.
10+ - Sets up a basic nat networking config for ContainerD to use until another CNI is configured
11+ - Registers ContainerD as a windows service.
12+
13+ . PARAMETER ContainerDVersion
14+ ContainerD version to download and use.
15+
16+ . PARAMETER netAdapterName
17+ Name of network adapter to use when configuring basic nat network.
18+
19+ . EXAMPLE
20+ PS> .\Install-Conatinerd.ps1
21+
22+ #>
23+
24+ Param (
25+ [parameter (HelpMessage = " ContainerD version to use" )]
26+ [string ] $ContainerDVersion = " 1.4.1" ,
27+ [parameter (HelpMessage = " Name of network adapter to use when configuring basic nat network" )]
28+ [string ] $netAdapterName = " Ethernet"
29+ )
30+
31+ $ErrorActionPreference = ' Stop'
32+
33+ function DownloadFile ($destination , $source ) {
34+ Write-Host (" Downloading $source to $destination " )
35+ curl.exe -- silent -- fail - Lo $destination $source
36+
37+ if (! $? ) {
38+ Write-Error " Download $source failed"
39+ exit 1
40+ }
41+ }
42+
43+ <#
44+ . DESCRIPTION
45+ Computes a subnet for a gateway from the IPv4 IPAddress and PrefixLength properties
46+ for a given network adapter. This value is used for IPAM in a nat CNI config required for
47+ containerd.
48+
49+ . NOTES
50+ This logic is adapted from
51+ https://github.com/containerd/containerd/blob/4a6b47d470d9f2dfc3d49f2819b968861dfa123e/script/setup/install-cni-windows
52+
53+ . EXAMPLE
54+ PS> CalculateSubNet -gateway 172.16.5.8 -prefixLength 24
55+ 172.16.5.0/8
56+ #>
57+ function CalculateSubNet {
58+ param (
59+ [string ]$gateway ,
60+ [int ]$prefixLength
61+ )
62+ $len = $prefixLength
63+ $parts = $gateway.Split (' .' )
64+ $result = @ ()
65+ for ($i = 0 ; $i -le 3 ; $i ++ ) {
66+ if ($len -ge 8 ) {
67+ $mask = 255
68+
69+ }
70+ elseif ($len -gt 0 ) {
71+ $mask = ((256 - 2 * (8 - $len )))
72+ }
73+ else {
74+ $mask = 0
75+ }
76+ $len -= 8
77+ $result += ([int ]$parts [$i ] -band $mask )
78+ }
79+
80+ $subnetIp = [string ]::Join(' .' , $result )
81+ $cidr = 32 - $prefixLength
82+ return " ${subnetIp} /$cidr "
83+ }
84+
85+ $requiredWindowsFeatures = @ (
86+ " Containers" ,
87+ " Hyper-V" ,
88+ " Hyper-V-PowerShell" )
89+
90+ function ValidateWindowsFeatures {
91+ $allFeaturesInstalled = $true
92+ foreach ($feature in $requiredWindowsFeatures ) {
93+ $f = Get-WindowsFeature - Name $feature
94+ if (-not $f.Installed ) {
95+ Write-Warning " Windows feature: '$feature ' is not installed."
96+ $allFeaturesInstalled = $false
97+ }
98+ }
99+ return $allFeaturesInstalled
100+ }
101+
102+ if (-not (ValidateWindowsFeatures)) {
103+ Write-Output " Installing required windows features..."
104+
105+ foreach ($feature in $requiredWindowsFeatures ) {
106+ Install-WindowsFeature - Name $feature
107+ }
108+
109+ Write-Output " Please reboot and re-run this script."
110+ exit 0
111+ }
112+
113+ Write-Output " Getting ContainerD binaries"
114+ $global :ConainterDPath = " $env: ProgramFiles \containerd"
115+ mkdir - Force $global :ConainterDPath | Out-Null
116+ DownloadFile " $global :ConainterDPath \containerd.tar.gz" https:// github.com / containerd/ containerd/ releases/ download/ v${ContainerDVersion} / containerd- ${ContainerDVersion} - windows- amd64.tar.gz
117+ tar.exe - xvf " $global :ConainterDPath \containerd.tar.gz" -- strip= 1 - C $global :ConainterDPath
118+ $env: Path += " ;$global :ConainterDPath "
119+ [Environment ]::SetEnvironmentVariable(" Path" , $env: Path , [System.EnvironmentVariableTarget ]::Machine)
120+ containerd.exe config default | Out-File " $global :ConainterDPath \config.toml" - Encoding ascii
121+ # config file fixups
122+ $config = Get-Content " $global :ConainterDPath \config.toml"
123+ $config = $config -replace " bin_dir = (.)*$" , " bin_dir = `" c:/opt/cni/bin`" "
124+ $config = $config -replace " conf_dir = (.)*$" , " conf_dir = `" c:/etc/cni/net.d`" "
125+ $config | Set-Content " $global :ConainterDPath \config.toml" - Force
126+
127+ mkdir - Force c:\opt\cni\bin | Out-Null
128+ mkdir - Force c:\etc\cni\net.d | Out-Null
129+
130+ Write-Output " Registering ContainerD as a service"
131+ containerd.exe -- register-service
132+
133+ Write-Output " Starting ContainerD service"
134+ Start-Service containerd
135+
136+ Write-Output " Done - please remember to add '--cri-socket `" npipe:////./pipe/containerd-containerd`" ' to your kubeadm join command"
0 commit comments