diff --git a/cluster/gce/config-default.sh b/cluster/gce/config-default.sh index c38d924529b..0c84b099340 100755 --- a/cluster/gce/config-default.sh +++ b/cluster/gce/config-default.sh @@ -556,3 +556,9 @@ export ETCD_PROGRESS_NOTIFY_INTERVAL="${ETCD_PROGRESS_NOTIFY_INTERVAL:-10m}" # Use host IP instead of localhost in control plane kubeconfig files. export KUBECONFIG_USE_HOST_IP="${KUBECONFIG_USE_HOST_IP:-false}" + +# Optional: Install Pigz on Windows. +# Pigz is a multi-core optimized version of unzip.exe. +# It improves container image pull performance since most time is spent +# unzipping the image layers to disk. +export WINDOWS_ENABLE_PIGZ="${WINDOWS_ENABLE_PIGZ:-true}" diff --git a/cluster/gce/config-test.sh b/cluster/gce/config-test.sh index b70775b5be5..89f3d187a5d 100755 --- a/cluster/gce/config-test.sh +++ b/cluster/gce/config-test.sh @@ -592,3 +592,9 @@ export ETCD_PROGRESS_NOTIFY_INTERVAL="${ETCD_PROGRESS_NOTIFY_INTERVAL:-10m}" # Use host IP instead of localhost in control plane kubeconfig files. export KUBECONFIG_USE_HOST_IP="${KUBECONFIG_USE_HOST_IP:-false}" + +# Optional: Install Pigz on Windows. +# Pigz is a multi-core optimized version of unzip.exe. +# It improves container image pull performance since most time is spent +# unzipping the image layers to disk. +export WINDOWS_ENABLE_PIGZ="${WINDOWS_ENABLE_PIGZ:-true}" diff --git a/cluster/gce/util.sh b/cluster/gce/util.sh index aedae8fed6a..e70a17a208f 100755 --- a/cluster/gce/util.sh +++ b/cluster/gce/util.sh @@ -1565,6 +1565,7 @@ KUBECONFIG_FILE: $(yaml-quote "${WINDOWS_KUBECONFIG_FILE}") BOOTSTRAP_KUBECONFIG_FILE: $(yaml-quote "${WINDOWS_BOOTSTRAP_KUBECONFIG_FILE}") KUBEPROXY_KUBECONFIG_FILE: $(yaml-quote "${WINDOWS_KUBEPROXY_KUBECONFIG_FILE}") WINDOWS_INFRA_CONTAINER: $(yaml-quote "${WINDOWS_INFRA_CONTAINER}") +WINDOWS_ENABLE_PIGZ: $(yaml-quote "${WINDOWS_ENABLE_PIGZ}") EOF } diff --git a/cluster/gce/windows/common.psm1 b/cluster/gce/windows/common.psm1 index 4a292077e86..03b68c23fd7 100644 --- a/cluster/gce/windows/common.psm1 +++ b/cluster/gce/windows/common.psm1 @@ -640,5 +640,25 @@ function Test-NodeUsesAuthPlugin { return $KubeEnv.Contains('EXEC_AUTH_PLUGIN_URL') } +# Permanently adds a directory to the $env:PATH environment variable. +function Add-MachineEnvironmentPath { + param ( + [parameter(Mandatory=$true)] [string]$Path + ) + # Verify that the $Path is not already in the $env:Path variable. + $pathForCompare = $Path.TrimEnd('\').ToLower() + foreach ($p in $env:Path.Split(";")) { + if ($p.TrimEnd('\').ToLower() -eq $pathForCompare) { + return + } + } + + $newMachinePath = $Path + ";" + ` + [System.Environment]::GetEnvironmentVariable("Path","Machine") + [Environment]::SetEnvironmentVariable("Path", $newMachinePath, ` + [System.EnvironmentVariableTarget]::Machine) + $env:Path = $Path + ";" + $env:Path +} + # Export all public functions: Export-ModuleMember -Function *-* diff --git a/cluster/gce/windows/k8s-node-setup.psm1 b/cluster/gce/windows/k8s-node-setup.psm1 index 1ed9d0c3a06..c92056e5b6e 100644 --- a/cluster/gce/windows/k8s-node-setup.psm1 +++ b/cluster/gce/windows/k8s-node-setup.psm1 @@ -273,6 +273,7 @@ function Set-EnvironmentVars { "LOGS_DIR" = ${kube_env}['LOGS_DIR'] "MANIFESTS_DIR" = ${kube_env}['MANIFESTS_DIR'] "INFRA_CONTAINER" = ${kube_env}['WINDOWS_INFRA_CONTAINER'] + "WINDOWS_ENABLE_PIGZ" = ${kube_env}['WINDOWS_ENABLE_PIGZ'] "Path" = ${env:Path} + ";" + ${kube_env}['NODE_DIR'] "KUBE_NETWORK" = "l2bridge".ToLower() @@ -1309,6 +1310,7 @@ function Pull-InfraContainer { # Setup the container runtime on the node. It supports both # Docker and containerd. function Setup-ContainerRuntime { + Install-Pigz if (${env:CONTAINER_RUNTIME} -eq "containerd") { Install_Containerd Configure_Containerd @@ -1529,6 +1531,40 @@ function Start_Containerd { Log-Output "Starting containerd service" Start-Service containerd } + +# Pigz Resources +$PIGZ_ROOT = 'C:\pigz' +$PIGZ_VERSION = '2.3.1' +$PIGZ_TAR_URL = 'https://storage.googleapis.com/gke-release/winnode/pigz/prod/gke_windows/pigz/release/5/20201104-134221/pigz-$PIGZ_VERSION.zip' +$PIGZ_TAR_HASH = '5a6f8f5530acc85ea51797f58c1409e5af6b69e55da243ffc608784cf14fec0cd16f74cc61c564d69e1a267750aecfc1e4c53b5219ff5f893b42a7576306f34c' + +# Install Pigz (https://github.com/madler/pigz) into Windows for improved image +# extraction performance. +function Install-Pigz { + if ("${env:WINDOWS_ENABLE_PIGZ}" -eq "true") { + if (-not (Test-Path $PIGZ_ROOT)) { + Log-Output "Installing Pigz $PIGZ_VERSION" + New-Item -Path $PIGZ_ROOT -ItemType Directory + MustDownload-File ` + -Url $PIGZ_TAR_URL ` + -OutFile "$PIGZ_ROOT\pigz-$PIGZ_VERSION.zip" ` + -Hash $PIGZ_TAR_HASH ` + -Algorithm SHA512 + Expand-Archive -Path "$PIGZ_ROOT\pigz-$PIGZ_VERSION.zip" ` + -DestinationPath $PIGZ_ROOT + Remove-Item -Path "$PIGZ_ROOT\pigz-$PIGZ_VERSION.zip" + # Docker and Containerd search for unpigz.exe on the first container image + # pull request after the service is started. If unpigz.exe is in the + # Windows path it'll use it instead of the default unzipper. + # See: https://github.com/containerd/containerd/issues/1896 + Add-MachineEnvironmentPath -Path $PIGZ_ROOT + Log-Output "Installed Pigz $PIGZ_VERSION" + } else { + Log-Output "Pigz already installed." + } + } +} + # TODO(pjh): move the logging agent code below into a separate # module; it was put here temporarily to avoid disrupting the file layout in # the K8s release machinery.