Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Fix kubeletConfig for Windows agent nodes #3753

Merged
merged 6 commits into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 48 additions & 26 deletions parts/k8s/kuberneteswindowssetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

.DESCRIPTION
Provisions VM as a Kubernetes agent.


Notes on modifying this file:
- This file extension is PS1, but it is actually used as a template from pkg/acsengine/template_generator.go
- All of the lines that have braces in them will be modified. Please do not change them here, change them in the Go sources
- Single quotes are forbidden, they are reserved to delineate the different members for the ARM template concat() call
#>
[CmdletBinding(DefaultParameterSetName="Standard")]
param(
Expand Down Expand Up @@ -45,8 +51,8 @@ $global:WindowsPackageSASURLBase = "{{WrapAsParameter "windowsPackageSASURLBase"
$global:KubeBinariesVersion = "{{WrapAsParameter "kubeBinariesVersion"}}"
$global:WindowsTelemetryGUID = "{{WrapAsParameter "windowsTelemetryGUID"}}"
$global:KubeletNodeLabels = "{{GetAgentKubernetesLabels . "',variables('labelResourceGroup'),'"}}"
$global:KubeletStartFile = $global:KubeDir + "\kubeletstart.ps1"
$global:KubeProxyStartFile = $global:KubeDir + "\kubeproxystart.ps1"
$global:KubeletStartFile = [io.path]::Combine($global:KubeDir, "kubeletstart.ps1")
$global:KubeProxyStartFile = [io.path]::Combine($global:KubeDir, "kubeproxystart.ps1")
$global:TenantId = "{{WrapAsVariable "tenantID"}}"
$global:SubscriptionId = "{{WrapAsVariable "subscriptionId"}}"
$global:ResourceGroup = "{{WrapAsVariable "resourceGroup"}}"
Expand All @@ -63,6 +69,8 @@ $global:KubeServiceCIDR = "{{WrapAsParameter "kubeServiceCidr"}}"
$global:KubeNetwork = "l2bridge"
$global:KubeDnsSearchPath = "svc.cluster.local"

$global:KubeletConfigArgs = @( {{GetKubeletConfigKeyValsPsh .KubernetesConfig }} )

$global:UseManagedIdentityExtension = "{{WrapAsVariable "useManagedIdentityExtension"}}"
$global:UseInstanceMetadata = "{{WrapAsVariable "useInstanceMetadata"}}"
$global:LoadBalancerSku = "{{WrapAsVariable "loadBalancerSku"}}"
Expand All @@ -72,7 +80,7 @@ $global:CNIPath = [Io.path]::Combine("$global:KubeDir", "cni")
$global:NetworkMode = "L2Bridge"
$global:CNIConfig = [Io.path]::Combine($global:CNIPath, "config", "`$global:NetworkMode.conf")
$global:CNIConfigPath = [Io.path]::Combine("$global:CNIPath", "config")
$global:WindowsCNIKubeletOptions = " --network-plugin=cni --cni-bin-dir=$global:CNIPath --cni-conf-dir=$global:CNIConfigPath"
$global:WindowsCNIKubeletOptions = @("--network-plugin=cni", "--cni-bin-dir=$global:CNIPath", "--cni-conf-dir=$global:CNIConfigPath")
$global:HNSModule = [Io.path]::Combine("$global:KubeDir", "hns.psm1")

$global:VolumePluginDir = [Io.path]::Combine("$global:KubeDir", "volumeplugins")
Expand All @@ -84,7 +92,7 @@ $global:VNetCNIPluginsURL = "{{WrapAsParameter "vnetCniWindowsPluginsURL"}}"
$global:AzureCNIDir = [Io.path]::Combine("$global:KubeDir", "azurecni")
$global:AzureCNIBinDir = [Io.path]::Combine("$global:AzureCNIDir", "bin")
$global:AzureCNIConfDir = [Io.path]::Combine("$global:AzureCNIDir", "netconf")
$global:AzureCNIKubeletOptions = " --network-plugin=cni --cni-bin-dir=$global:AzureCNIBinDir --cni-conf-dir=$global:AzureCNIConfDir"
$global:AzureCNIKubeletOptions = @("--network-plugin=cni", "--cni-bin-dir=$global:AzureCNIBinDir", "--cni-conf-dir=$global:AzureCNIConfDir")
$global:AzureCNIEnabled = $false

filter Timestamp {"$(Get-Date -Format o): $_"}
Expand Down Expand Up @@ -167,7 +175,7 @@ Update-WindowsPackages()
function
Write-AzureConfig()
{
$azureConfigFile = $global:KubeDir + "\azure.json"
$azureConfigFile = [io.path]::Combine($global:KubeDir, "azure.json")

$azureConfig = @"
{
Expand All @@ -194,10 +202,18 @@ Write-AzureConfig()
$azureConfig | Out-File -encoding ASCII -filepath "$azureConfigFile"
}


function
Write-CACert()
{
$caFile = [io.path]::Combine($global:KubeDir, "ca.crt")
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($global:CACertificate)) | Out-File -Encoding ascii $caFile
}

function
Write-KubeConfig()
{
$kubeConfigFile = $global:KubeDir + "\config"
$kubeConfigFile = [io.path]::Combine($global:KubeDir, "config")

$kubeConfig = @"
---
Expand Down Expand Up @@ -311,34 +327,35 @@ Set-NetworkConfig
function
Write-KubernetesStartFiles($podCIDR)
{
mkdir $global:VolumePluginDir
$KubeletArgList = @(" --node-labels=`$global:KubeletNodeLabels --hostname-override=`$global:AzureHostname","--pod-infra-container-image=kubletwin/pause","--resolv-conf=""""""""","--kubeconfig=c:\k\config","--cloud-provider=azure","--cloud-config=c:\k\azure.json")
$KubeletCommandLine = @"
c:\k\kubelet.exe --hostname-override=`$env:computername --pod-infra-container-image=kubletwin/pause --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns=`$global:KubeDnsServiceIp --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --v=2 --azure-container-registry-config=c:\k\azure.json --runtime-request-timeout=10m --cloud-provider=azure --cloud-config=c:\k\azure.json
"@
mkdir $global:VolumePluginDir
$KubeletArgList = $global:KubeletConfigArgs # This is the initial list passed in from acs-engine
$KubeletArgList += "--node-labels=`$global:KubeletNodeLabels"
$KubeletArgList += "--hostname-override=`$global:AzureHostname"
$KubeletArgList += "--cluster-dns=`$global:KubeDnsServiceIp"
$KubeletArgList += "--volume-plugin-dir=`$global:VolumePluginDir"
# If you are thinking about adding another arg here, you should be considering pkg/acsengine/defaults-kubelet.go first
# Only args that need to be calculated or combined with other ones on the Windows agent should be added here.


# Regex to strip version to Major.Minor.Build format such that the following check does not crash for version like x.y.z-alpha
[regex]$regex = "^[0-9.]+"
$KubeBinariesVersionStripped = $regex.Matches($global:KubeBinariesVersion).Value
if ([System.Version]$KubeBinariesVersionStripped -lt [System.Version]"1.8.0")
{
# --api-server deprecates from 1.8.0
$KubeletArgList += "--api-servers=https://`${global:MasterIP}:443"
$KubeletCommandLine += " --api-servers=https://`${global:MasterIP}:443"
}

# more time is needed to pull windows server images
$KubeletCommandLine += " --image-pull-progress-deadline=20m --cgroups-per-qos=false --enforce-node-allocatable=`"`""
$KubeletCommandLine += " --volume-plugin-dir=`$global:VolumePluginDir"
# Configure kubelet to use CNI plugins if enabled.
# Configure kubelet to use CNI plugins if enabled.
if ($global:AzureCNIEnabled) {
$KubeletCommandLine += $global:AzureCNIKubeletOptions
$KubeletArgList += $global:AzureCNIKubeletOptions
} else {
$KubeletCommandLine += $global:WindowsCNIKubeletOptions
$KubeletArgList += $global:WindowsCNIKubeletOptions
}

$KubeletArgListStr = "`"" + ($KubeletArgList -join "`",`"") + "`""
$KubeletArgListStr = $KubeletArgList -join " "

$KubeletArgListStr = "@`($KubeletArgListStr`)"
$KubeletCommandLine = "c:\k\kubelet.exe " + $KubeletArgListStr

$kubeStartStr = @"
`$global:MasterIP = "$MasterIP"
Expand Down Expand Up @@ -392,24 +409,24 @@ if (`$hnsNetwork)
Remove-HnsNetwork `$hnsNetwork
# Kill all cni instances & stale data left by cni
# Cleanup all files related to cni
`$cnijson = "$global:KubeDir" + "\azure-vnet-ipam.json"
`$cnijson = [io.path]::Combine("$global:KubeDir", "azure-vnet-ipam.json")
if ((Test-Path `$cnijson))
{
Remove-Item `$cnijson
}
`$cnilock = "$global:KubeDir" + "\azure-vnet-ipam.lock"
`$cnilock = [io.path]::Combine("$global:KubeDir", "azure-vnet-ipam.lock")
if ((Test-Path `$cnilock))
{
Remove-Item `$cnilock
}
taskkill /IM azure-vnet-ipam.exe /f

`$cnijson = "$global:KubeDir" + "\azure-vnet.json"
`$cnijson = [io.path]::Combine("$global:KubeDir", "azure-vnet.json")
if ((Test-Path `$cnijson))
{
Remove-Item `$cnijson
}
`$cnilock = "$global:KubeDir" + "\azure-vnet.lock"
`$cnilock = [io.path]::Combine("$global:KubeDir", "azure-vnet.lock")
if ((Test-Path `$cnilock))
{
Remove-Item `$cnilock
Expand All @@ -423,7 +440,9 @@ Restart-Service Kubeproxy
$KubeletCommandLine

"@
} else {
}
else # using WinCNI. TODO: If WinCNI support is removed, then delete this as dead code later
{
$kubeStartStr += @"

function
Expand Down Expand Up @@ -561,7 +580,7 @@ catch
}

"@
}
} # end else using WinCNI.

$kubeStartStr | Out-File -encoding ASCII -filepath $global:KubeletStartFile

Expand Down Expand Up @@ -666,6 +685,9 @@ try
Write-Log "Write azure config"
Write-AzureConfig

Write-Log "Write ca root"
Write-CACert

Write-Log "Write kube config"
Write-KubeConfig

Expand Down
15 changes: 14 additions & 1 deletion pkg/acsengine/defaults-kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,24 @@ func setKubeletConfig(cs *api.ContainerService) {
"--keep-terminated-pod-volumes": "false",
}

// Start with copy of Linux config
staticWindowsKubeletConfig := make(map[string]string)
for key, val := range staticLinuxKubeletConfig {
staticWindowsKubeletConfig[key] = val
}

// Add Windows-specific overrides
// Eventually paths should not be hardcoded here. They should be relative to $global:KubeDir in the PowerShell script
staticWindowsKubeletConfig["--azure-container-registry-config"] = "c:\\k\\azure.json"
staticWindowsKubeletConfig["--pod-infra-container-image"] = "kubletwin/pause"
staticWindowsKubeletConfig["--kubeconfig"] = "c:\\k\\config"
staticWindowsKubeletConfig["--cloud-config"] = "c:\\k\\azure.json"
staticWindowsKubeletConfig["--cgroups-per-qos"] = "false"
staticWindowsKubeletConfig["--enforce-node-allocatable"] = "\"\""
staticWindowsKubeletConfig["--enforce-node-allocatable"] = "\"\"\"\""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's like an escape room. You escape one just to find you must escape another.

staticWindowsKubeletConfig["--client-ca-file"] = "c:\\k\\ca.crt"
staticWindowsKubeletConfig["--hairpin-mode"] = "promiscuous-bridge"
staticWindowsKubeletConfig["--image-pull-progress-deadline"] = "20m"
staticWindowsKubeletConfig["--resolv-conf"] = "\"\"\"\""

// Default Kubelet config
defaultKubeletConfig := map[string]string{
Expand Down Expand Up @@ -136,6 +144,11 @@ func setKubeletConfig(cs *api.ContainerService) {
}
setMissingKubeletValues(profile.KubernetesConfig, o.KubernetesConfig.KubeletConfig)

if profile.OSType == "Windows" {
// Remove Linux-specific values
delete(profile.KubernetesConfig.KubeletConfig, "--pod-manifest-path")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha. I wonder if we should do this for Linux as well. Instead of this recent change that @tariq1890 made:

https://github.com/Azure/acs-engine/pull/3744/files

}

// For N Series (GPU) VMs
if strings.Contains(profile.VMSize, "Standard_N") {
if !cs.Properties.IsNVIDIADevicePluginEnabled() && !common.IsKubernetesVersionGe(o.OrchestratorVersion, "1.11.0") {
Expand Down
20 changes: 20 additions & 0 deletions pkg/acsengine/template_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,26 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.ContainerService) templat
}
return buf.String()
},
"GetKubeletConfigKeyValsPsh": func(kc *api.KubernetesConfig) string {
if kc == nil {
return ""
}
kubeletConfig := cs.Properties.OrchestratorProfile.KubernetesConfig.KubeletConfig
if kc.KubeletConfig != nil {
kubeletConfig = kc.KubeletConfig
}
// Order by key for consistency
keys := []string{}
for key := range kubeletConfig {
keys = append(keys, key)
}
sort.Strings(keys)
var buf bytes.Buffer
for _, key := range keys {
buf.WriteString(fmt.Sprintf("\"%s=%s\", ", key, kubeletConfig[key]))
}
return strings.TrimSuffix(buf.String(), ", ")
},
"GetK8sRuntimeConfigKeyVals": func(config map[string]string) string {
// Order by key for consistency
keys := []string{}
Expand Down