317 lines
12 KiB
PowerShell
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"
|
|
|