parts/k8s/windowskubeletfunc.ps1 (285 lines of code) (raw):
function
Write-AzureConfig {
Param(
[Parameter(Mandatory = $true)][string]
$AADClientId,
[Parameter(Mandatory = $true)][string]
$AADClientSecret,
[Parameter(Mandatory = $true)][string]
$TenantId,
[Parameter(Mandatory = $true)][string]
$SubscriptionId,
[Parameter(Mandatory = $true)][string]
$ResourceGroup,
[Parameter(Mandatory = $true)][string]
$Location,
[Parameter(Mandatory = $true)][string]
$VmType,
[Parameter(Mandatory = $true)][string]
$SubnetName,
[Parameter(Mandatory = $true)][string]
$SecurityGroupName,
[Parameter(Mandatory = $true)][string]
$VNetName,
[Parameter(Mandatory = $true)][string]
$RouteTableName,
[Parameter(Mandatory = $false)][string] # Need one of these configured
$PrimaryAvailabilitySetName,
[Parameter(Mandatory = $false)][string] # Need one of these configured
$PrimaryScaleSetName,
[Parameter(Mandatory = $true)][string]
$UseManagedIdentityExtension,
[string]
$UserAssignedClientID,
[Parameter(Mandatory = $true)][string]
$UseInstanceMetadata,
[Parameter(Mandatory = $true)][string]
$LoadBalancerSku,
[Parameter(Mandatory = $true)][string]
$ExcludeMasterFromStandardLB,
[Parameter(Mandatory = $true)][string]
$KubeDir,
[Parameter(Mandatory = $true)][string]
$TargetEnvironment
)
if ( -Not $PrimaryAvailabilitySetName -And -Not $PrimaryScaleSetName ) {
throw "Either PrimaryAvailabilitySetName or PrimaryScaleSetName must be set"
}
$azureConfigFile = [io.path]::Combine($KubeDir, "azure.json")
$azureConfig = @"
{
"cloud": "$TargetEnvironment",
"tenantId": "$TenantId",
"subscriptionId": "$SubscriptionId",
"aadClientId": "$AADClientId",
"aadClientSecret": "$AADClientSecret",
"resourceGroup": "$ResourceGroup",
"location": "$Location",
"vmType": "$VmType",
"subnetName": "$SubnetName",
"securityGroupName": "$SecurityGroupName",
"vnetName": "$VNetName",
"routeTableName": "$RouteTableName",
"primaryAvailabilitySetName": "$PrimaryAvailabilitySetName",
"primaryScaleSetName": "$PrimaryScaleSetName",
"useManagedIdentityExtension": $UseManagedIdentityExtension,
"userAssignedIdentityID": "$UserAssignedClientID",
"useInstanceMetadata": $UseInstanceMetadata,
"loadBalancerSku": "$LoadBalancerSku",
"excludeMasterFromStandardLB": $ExcludeMasterFromStandardLB
}
"@
$azureConfig | Out-File -encoding ASCII -filepath "$azureConfigFile"
}
function
Write-CACert {
Param(
[Parameter(Mandatory = $true)][string]
$CACertificate,
[Parameter(Mandatory = $true)][string]
$KubeDir
)
$caFile = [io.path]::Combine($KubeDir, "ca.crt")
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($CACertificate)) | Out-File -Encoding ascii $caFile
}
function
Write-KubeConfig {
Param(
[Parameter(Mandatory = $true)][string]
$CACertificate,
[Parameter(Mandatory = $true)][string]
$MasterFQDNPrefix,
[Parameter(Mandatory = $true)][string]
$MasterIP,
[Parameter(Mandatory = $true)][string]
$AgentKey,
[Parameter(Mandatory = $true)][string]
$AgentCertificate,
[Parameter(Mandatory = $true)][string]
$KubeDir
)
$kubeConfigFile = [io.path]::Combine($KubeDir, "config")
$kubeConfig = @"
---
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: "$CACertificate"
server: https://${MasterIP}:443
name: "$MasterFQDNPrefix"
contexts:
- context:
cluster: "$MasterFQDNPrefix"
user: "$MasterFQDNPrefix-admin"
name: "$MasterFQDNPrefix"
current-context: "$MasterFQDNPrefix"
kind: Config
users:
- name: "$MasterFQDNPrefix-admin"
user:
client-certificate-data: "$AgentCertificate"
client-key-data: "$AgentKey"
"@
$kubeConfig | Out-File -encoding ASCII -filepath "$kubeConfigFile"
}
function
Test-ContainerImageExists {
Param(
[Parameter(Mandatory = $true)][string]
$Image,
[Parameter(Mandatory = $false)][string]
$Tag
)
$target = $Image
if ($Tag) {
$target += ":$Tag"
}
return ( (ctr.exe -n k8s.io images list) | Select-String $target) -ne $Null
}
function
New-InfraContainer {
Param(
[Parameter(Mandatory = $true)][string]
$KubeDir,
$DestinationTag = "kubletwin/pause"
)
cd $KubeDir
$windowsVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
# Reference for these tags: curl -L https://mcr.microsoft.com/v2/k8s/core/pause/tags/list
# Then docker run --rm mplatform/manifest-tool inspect mcr.microsoft.com/k8s/core/pause:<tag>
$clusterConfig = ConvertFrom-Json ((Get-Content $global:KubeClusterConfigPath -ErrorAction Stop) | Out-String)
$defaultPauseImage = $clusterConfig.Cri.Images.Pause
$pauseImageVersions = @("1809", "1903", "1909", "2004", "2009", "20h2", "ltsc2022")
if ($pauseImageVersions -icontains $windowsVersion) {
# containerd
if (-not (Test-ContainerImageExists -Image $defaultPauseImage) -or $global:AlwaysPullWindowsPauseImage) {
Invoke-Executable -Executable "ctr" -ArgList @("-n", "k8s.io", "image", "pull", "$defaultPauseImage") -Retries 5 -RetryDelaySeconds 30
}
Invoke-Executable -Executable "ctr" -ArgList @("-n", "k8s.io", "image", "tag", "$defaultPauseImage", "$DestinationTag")
}
}
# TODO: Deprecate this and replace with methods that get individual components instead of zip containing everything
# This expects the ZIP file created by Azure Pipelines.
function
Get-KubePackage {
Param(
[Parameter(Mandatory = $true)][string]
$KubeBinariesSASURL
)
$zipfile = "c:\k.zip"
for ($i = 0; $i -le 10; $i++) {
DownloadFileOverHttp -Url $KubeBinariesSASURL -DestinationPath $zipfile
if ($?) {
break
}
else {
Write-Log $Error[0].Exception.Message
}
}
Expand-Archive -path $zipfile -DestinationPath C:\
Remove-Item $zipfile
}
function
Get-KubeBinaries {
Param(
[Parameter(Mandatory = $true)][string]
$KubeBinariesURL
)
$tempdir = New-TemporaryDirectory
$binaryPackage = "$tempdir\k.tar.gz"
for ($i = 0; $i -le 10; $i++) {
DownloadFileOverHttp -Url $KubeBinariesURL -DestinationPath $binaryPackage
if ($?) {
break
}
else {
Write-Log $Error[0].Exception.Message
}
}
# using tar to minimize dependencies
# tar should be avalible on 1803+
tar -xzf $binaryPackage -C $tempdir
# copy binaries over to kube folder
$windowsbinariespath = "c:\k\"
if (!(Test-path $windowsbinariespath)) {
mkdir $windowsbinariespath
}
cp $tempdir\kubernetes\node\bin\* $windowsbinariespath -Recurse
#remove temp folder created when unzipping
del $tempdir -Recurse
}
# TODO: replace KubeletStartFile with a Kubelet config, remove NSSM, and use built-in service integration
function
New-NSSMService {
Param(
[string]
[Parameter(Mandatory = $true)]
$KubeDir,
[string]
[Parameter(Mandatory = $true)]
$KubeletStartFile,
[string]
[Parameter(Mandatory = $true)]
$KubeProxyStartFile
)
$kubeletDependOnServices = "containerd"
if ($global:EnableCsiProxy) {
$kubeletDependOnServices += " csi-proxy"
}
if ($global:EnableHostsConfigAgent) {
$kubeletDependOnServices += " hosts-config-agent"
}
# setup kubelet
& "$KubeDir\nssm.exe" install Kubelet C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppDirectory $KubeDir | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppParameters $KubeletStartFile | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet DisplayName Kubelet | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppRestartDelay 5000 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet Description Kubelet | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet Start SERVICE_DEMAND_START | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet ObjectName LocalSystem | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet Type SERVICE_WIN32_OWN_PROCESS | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppThrottle 1500 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppStdout C:\k\kubelet.log | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppStderr C:\k\kubelet.err.log | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppStdoutCreationDisposition 4 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppStderrCreationDisposition 4 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppRotateFiles 1 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppRotateOnline 1 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppRotateSeconds 86400 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubelet AppRotateBytes 10485760 | RemoveNulls
# Do not use & when calling DependOnService since 'docker csi-proxy'
# is parsed as a single string instead of two separate strings
Invoke-Expression "$KubeDir\nssm.exe set Kubelet DependOnService $kubeletDependOnServices | RemoveNulls"
# setup kubeproxy
& "$KubeDir\nssm.exe" install Kubeproxy C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppDirectory $KubeDir | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppParameters $KubeProxyStartFile | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy DisplayName Kubeproxy | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy DependOnService Kubelet | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy Description Kubeproxy | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy Start SERVICE_DEMAND_START | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy ObjectName LocalSystem | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy Type SERVICE_WIN32_OWN_PROCESS | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppThrottle 1500 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppStdout C:\k\kubeproxy.log | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppStderr C:\k\kubeproxy.err.log | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppRotateFiles 1 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppRotateOnline 1 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppRotateSeconds 86400 | RemoveNulls
& "$KubeDir\nssm.exe" set Kubeproxy AppRotateBytes 10485760 | RemoveNulls
}
# Renamed from Write-KubernetesStartFiles
function
Install-KubernetesServices {
param(
[Parameter(Mandatory = $true)][string]
$KubeDir
)
# TODO ksbrmnn fix callers to this function
$KubeletStartFile = [io.path]::Combine($KubeDir, "kubeletstart.ps1")
$KubeProxyStartFile = [io.path]::Combine($KubeDir, "kubeproxystart.ps1")
New-NSSMService -KubeDir $KubeDir `
-KubeletStartFile $KubeletStartFile `
-KubeProxyStartFile $KubeProxyStartFile
}