shdsbilling/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/bootstrap.ps1

317 lines
12 KiB
PowerShell

<#
output.ps1 could output the execution commands, and then
pass the content to `Invoke-Expression` via pipe character
#>
$ErrorActionPreference = 'Stop'
$WarningPreference = 'SilentlyContinue'
$VerbosePreference = 'SilentlyContinue'
$DebugPreference = 'SilentlyContinue'
$InformationPreference = 'SilentlyContinue'
Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1"
$CATTLE_PREFIX_PATH = Get-Env -Key "CATTLE_PREFIX_PATH"
# parse arguments
$vals = $null
for ($i = $args.Length; $i -ge 0; $i--)
{
$arg = $args[$i]
switch -regex ($arg)
{
'^(--prefix-path)$' {
$CATTLE_PREFIX_PATH = ($vals | Select-Object -First 1)
$vals = $null
}
default {
if ($vals) {
$vals = ,$arg + $vals
} else {
$vals = @($arg)
}
}
}
}
if ([string]::IsNullOrEmpty($CATTLE_PREFIX_PATH)) {
$CATTLE_PREFIX_PATH = "c:\"
}
if ($CATTLE_PREFIX_PATH.Chars($CATTLE_PREFIX_PATH.Length - 1) -ne '\') {
# confirm trailing slash for path building below
$CATTLE_PREFIX_PATH = ($CATTLE_PREFIX_PATH + '\')
}
$hostPrefixPath = $CATTLE_PREFIX_PATH -Replace "c:\\", "c:\host\"
# create directories on the host
# windows docker can only mount an existing path into containers
try
{
New-Item -Force -ItemType Directory -Path @(
"$($hostPrefixPath)opt"
"$($hostPrefixPath)opt\bin"
"$($hostPrefixPath)opt\cni"
"$($hostPrefixPath)opt\cni\bin"
"$($hostPrefixPath)etc"
"$($hostPrefixPath)etc\rancher"
"$($hostPrefixPath)etc\rancher\wins"
"$($hostPrefixPath)etc\kubernetes"
"$($hostPrefixPath)etc\kubernetes\bin"
"$($hostPrefixPath)etc\cni"
"$($hostPrefixPath)etc\cni\net.d"
"$($hostPrefixPath)etc\nginx"
"$($hostPrefixPath)etc\nginx\logs"
"$($hostPrefixPath)etc\nginx\temp"
"$($hostPrefixPath)etc\nginx\conf"
"$($hostPrefixPath)etc\kube-flannel"
"$($hostPrefixPath)var"
"$($hostPrefixPath)var\run"
"$($hostPrefixPath)var\log"
"$($hostPrefixPath)var\log\pods"
"$($hostPrefixPath)var\log\containers"
"$($hostPrefixPath)var\lib"
"$($hostPrefixPath)var\lib\cni"
"$($hostPrefixPath)var\lib\rancher"
"$($hostPrefixPath)var\lib\rancher\rke"
"$($hostPrefixPath)var\lib\rancher\rke\log"
"$($hostPrefixPath)var\lib\kubelet"
"$($hostPrefixPath)var\lib\kubelet\volumeplugins"
"$($hostPrefixPath)run"
"c:\host\ProgramData\docker\certs.d"
) | Out-Null
} catch { }
# copy cleanup.ps1 & wins.exe to the host
# wins needs to run as a service on the host to accept requests from container
try
{
Copy-Item -Force -Destination "$($hostPrefixPath)etc\rancher" -Path @(
"c:\etc\rancher\utils.psm1"
"c:\Windows\wins.exe"
)
} catch { }
$verification = @"
Log-Info "Detecting running permission ..."
if (-not (Is-Administrator))
{
Log-Fatal "You need elevated Administrator privileges in order to run this script, start Windows PowerShell by using the Run as Administrator option"
}
Log-Info "Detecting host CPU reservation ..."
try
{
`$cpuLogicalProccessors = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty NumberOfLogicalProcessors
if (`$cpuLogicalProccessors -le 1) {
Log-Fatal "The CPU resource could not satisfy the default reservation for both Windows system and Kuberentes components, please increase the CPU resource to more than 2 logic processors"
} elseif (`$cpuLogicalProccessors -lt 2) {
Log-Warn "The CPU resource only satisfies the lowest limit for running Kubernetes components"
Log-Warn "Please increase the CPU resource to more than 2 logic processors if you are unable to schedule Pods on this Node"
}
}
catch
{
Log-Warn "Could not detect the CPU resource: `$(`$_.Exception.Message)"
}
Log-Info "Detecting host RAM reservation ..."
try
{
`$lowestLimitGB = 2.5
`$systemType = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty PCSystemType
if (`$systemType -eq 1) {
# system with GUI
`$lowestLimitGB = 4.5
}
`$ramTotalGB = `$(Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty TotalPhysicalMemory)/1GB
if (`$ramTotalGB -lt `$lowestLimitGB) {
Log-Fatal "The RAM resource could not satisfy the default reservation for both Windows system and Kubernetes components, please increase the RAM resource to more than `$lowestLimitGB GB"
}
`$ramAvailableMB = `$(Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Memory | Measure-Object -Sum -Property AvailableBytes | Select-Object -ExpandProperty Sum)/1MB
if (`$ramAvailableMB -le 500) {
Log-Fatal "The RAM resource could not satisfy the default reservation for Kuberentes components, please increase the RAM resource to more than `$lowestLimitGB GB"
} elseif (`$ramAvailableMB -le 600) {
Log-Warn "The RAM resource only satisfies the lowest limit for running Kubernetes components"
Log-Warn "Please increase the RAM resource to more than `$lowestLimitGB GB if you are unable to schedule Pods on this Node"
}
}
catch
{
Log-Warn "Could not detect the RAM resource: `$(`$_.Exception.Message)"
}
Log-Info "Detecting host DISK reservation ..."
try
{
`$diskAvaliableGB = `$(Get-WmiObject -Class Win32_LogicalDisk | Where-Object {`$_.DeviceID -eq "C:"} | Select-Object -ExpandProperty Size)/1GB
if (`$diskAvaliableGB -lt 29.5) {
Log-Fatal "The DISK resource could not satisfy the default reservation for both Windows system and Kubernetes components, please increase the DISK resource to more than 30 GB"
} elseif (`$diskAvaliableGB -lt 49.5) {
Log-Warn "The DISK resource only satisfies the lowest limit for running Kubernetes components"
Log-Warn "Please increase the DISK resource to more than 50 GB if you are unable to schedule Pods on this Node"
}
}
catch
{
Log-Warn "Could not detect the DISK resource: `$(`$_.Exception.Message)"
}
Log-Info "Detecting host Docker named pipe existing ..."
`$dockerNPipe = Get-ChildItem //./pipe/ -ErrorAction Ignore | ? Name -eq "docker_engine"
if (-not `$dockerNPipe)
{
Log-Warn "Default Docker named pipe is not available"
Log-Warn "Please create '//./pipe/docker_engine' named pipe to access docker daemon if docker errors occur"
}
Log-Info "Detecting host Docker platform name..."
try
{
`$dockerPlatform = docker.exe version -f "{{.Server.Platform.Name}}"
if (-not (`$dockerPlatform -like '*Enterprise*') -AND -not (`$dockerPlatform -eq 'Mirantis Container Runtime'))
{
Log-Fatal "Only Docker EE or Mirantis Container Runtime supported"
}
}
catch
{
Log-Fatal "Could not find Docker service: `$(`$_.Exception.Message)"
}
Log-Info "Detecting host network interface ..."
`$vNetAdapters = Get-HnsNetwork | Select-Object -ExpandProperty "Subnets" | Select-Object -ExpandProperty "GatewayAddress"
`$allNetAdapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True" | Sort-Object Index | ForEach-Object { `$_.IPAddress[0] } | Where-Object { -not (`$vNetAdapters -contains `$_) }
`$networkCount = `$allNetAdapters | Measure-Object | Select-Object -ExpandProperty "Count"
if (`$networkCount -gt 1)
{
Log-Warn "More than 1 network interface was found: `$(`$allNetAdapters -join ", ")"
Log-Warn "Please indicate --internal-address when adding failed"
}
Log-Info "Configuring host Docker Service to start automatically..."
try
{
Get-Service -Name "docker" -ErrorAction Ignore | Where-Object {`$_.StartType -ne "Automatic"} | Set-Service -StartupType Automatic
}
catch
{
Log-Warn "Could not configure the Docker service to start automatically: `$(`$_.Exception.Message)"
Log-Warn "Please change the Docker service 'StartupType' to 'Automatic'"
}
Log-Info "Enabling host msiscsi service to support iscsi storage ..."
`$svcMsiscsi = Get-Service -Name "msiscsi" -ErrorAction Ignore
if (`$svcMsiscsi -and (`$svcMsiscsi.Status -ne "Running"))
{
Set-Service -Name "msiscsi" -StartupType Automatic -WarningAction Ignore
Start-Service -Name "msiscsi" -ErrorAction Ignore -WarningAction Ignore
if (-not `$?) {
Log-Warn "Failed to start msiscsi service, you may not be able to use the iSCSI flexvolume properly"
}
}
"@
# allow user to disable the verification
if ($env:WITHOUT_VERIFICATION -eq "true") {
$verification = ""
}
Out-File -Encoding ascii -FilePath "$($hostPrefixPath)etc\rancher\bootstrap.ps1" -InputObject @"
`$ErrorActionPreference = 'Stop'
`$WarningPreference = 'SilentlyContinue'
`$VerbosePreference = 'SilentlyContinue'
`$DebugPreference = 'SilentlyContinue'
`$InformationPreference = 'SilentlyContinue'
# import modules
Import-Module -WarningAction Ignore -Name "`$PSScriptRoot\utils.psm1"
# remove script
Remove-Item -Force -Path "`$PSScriptRoot\bootstrap.ps1" -ErrorAction Ignore
$verification
# repair Get-GcePdName method
# this is a stopgap, we could drop this after https://github.com/kubernetes/kubernetes/issues/74674 fixed
# related: rke-tools container
`$getGcePodNameCommand = Get-Command -Name "Get-GcePdName" -ErrorAction Ignore
if (-not `$getGcePodNameCommand)
{
`$profilePath = "`$PsHome\profile.ps1"
if (-not (Test-Path `$profilePath)) {
New-Item -ItemType File -Path `$profilePath -ErrorAction Ignore | Out-Null
}
`$appendProfile = @'
Unblock-File -Path DLLPATH -ErrorAction Ignore
Import-Module -Name DLLPATH -ErrorAction Ignore
'@
Add-Content -Path `$profilePath -Value `$appendProfile.replace('DLLPATH', "$($CATTLE_PREFIX_PATH)run\GetGcePdName.dll") -ErrorAction Ignore
}
# clean up the stale HNS network if required
try
{
# warm up HNS network
1..5 | ForEach-Object { Invoke-HNSRequest -Method "GET" -Type "networks" | Out-Null }
# remove the HNS networks
Invoke-HNSRequest -Method "GET" -Type "networks" | Where-Object {@('cbr0', 'vxlan0') -contains `$_.Name} | ForEach-Object {
Log-Info "Cleaning up stale HNSNetwork `$(`$_.Name) ..."
Invoke-HNSRequest -Method "DELETE" -Type "networks" -Id `$_.Id
}
# remove the HNS policies
Invoke-HNSRequest -Method "GET" -Type "policylists" | Where-Object {-not [string]::IsNullOrEmpty(`$_.Id)} | ForEach-Object {
Log-Info "Cleaning up HNSPolicyList `$(`$_.Id) ..."
Invoke-HNSRequest -Method "DELETE" -Type "policylists" -Id `$_.Id
}
}
catch
{
Log-Warn "Could not clean: `$(`$_.Exception.Message)"
}
# make a powershell copy for wins to use
Copy-Item $($(Get-Command powershell).Source) $($CATTLE_PREFIX_PATH)etc\rancher\powershell.exe
# output wins config
@{
whiteList = @{
processPaths = @(
"$($CATTLE_PREFIX_PATH)etc\wmi-exporter\wmi-exporter.exe"
"$($CATTLE_PREFIX_PATH)etc\kubernetes\bin\kube-proxy.exe"
"$($CATTLE_PREFIX_PATH)etc\kubernetes\bin\kubelet.exe"
"$($CATTLE_PREFIX_PATH)etc\nginx\nginx.exe"
"$($CATTLE_PREFIX_PATH)opt\bin\flanneld.exe"
"$($CATTLE_PREFIX_PATH)etc\rancher\wins\wins-upgrade.exe"
"$($CATTLE_PREFIX_PATH)etc\rancher\powershell.exe"
"$($CATTLE_PREFIX_PATH)etc\windows-exporter\windows-exporter.exe"
)
proxyPorts = @(
9796
)
}
} | ConvertTo-Json -Compress -Depth 32 | Out-File -NoNewline -Encoding utf8 -Force -FilePath "$($CATTLE_PREFIX_PATH)etc\rancher\wins\config"
# register wins
Start-Process -NoNewWindow -Wait ``
-FilePath "$($CATTLE_PREFIX_PATH)etc\rancher\wins.exe" ``
-ArgumentList "srv app run --register"
# start wins
Start-Service -Name "rancher-wins" -ErrorAction Ignore
# run agent
Start-Process -NoNewWindow -Wait ``
-FilePath "docker.exe" ``
-ArgumentList "run -d --restart=unless-stopped -e CATTLE_PREFIX_PATH=$CATTLE_PREFIX_PATH -v \\.\pipe\docker_engine:\\.\pipe\docker_engine -v c:\ProgramData\docker\certs.d:c:\etc\docker\certs.d -v $($CATTLE_PREFIX_PATH)etc\kubernetes:c:\etc\kubernetes -v \\.\pipe\rancher_wins:\\.\pipe\rancher_wins -v $($CATTLE_PREFIX_PATH)etc\rancher\wins:c:\etc\rancher\wins $($env:AGENT_IMAGE) execute $($args -join " ")"
"@
Write-Output -InputObject "$($CATTLE_PREFIX_PATH)etc\rancher\bootstrap.ps1"