Skip to content

Cache versioned kubelet kubectl package binaries#8287

Open
awesomenix wants to merge 1 commit intomainfrom
nishp/fastkubeletfrompkg
Open

Cache versioned kubelet kubectl package binaries#8287
awesomenix wants to merge 1 commit intomainfrom
nishp/fastkubeletfrompkg

Conversation

@awesomenix
Copy link
Copy Markdown
Contributor

What this does

This change avoids unnecessary kubelet/kubectl package installation work during CSE when the corresponding binaries are already
available on the VHD.

Today, Ubuntu and Mariner/Azure Linux cache the kubelet/kubectl PMC packages on the VHD, but CSE still installs them via the package
manager/runtime package flow. That has a few downsides:

  • it re-runs package installation logic during provisioning
  • on Ubuntu, dpkg -i triggers package postinst behavior for kubelet.service
  • we pay extra provisioning latency even though AKS already owns kubelet service configuration and startup

This PR changes the flow so VHD build materializes versioned kubelet/kubectl binaries from the cached package artifacts into:

  • /opt/bin/kubelet-<k8sVersion>
  • /opt/bin/kubectl-<k8sVersion>

Then, during CSE, if the requested version is already present in /opt/bin, we reuse the existing cache-first path and do the final
rename into place instead of reinstalling from the package.

Changes

VHD build

  • extend vhdbuilder/packer/install-dependencies.sh so cached kubelet/kubectl package artifacts also produce versioned binaries
    under /opt/bin
  • support both:
    • Ubuntu: extract /usr/bin/<tool> from cached .deb
    • Mariner/Azure Linux: extract /usr/bin/<tool> from cached .rpm

CSE

  • add a shared helper to detect whether versioned kubelet/kubectl binaries already exist in /opt/bin
  • update Ubuntu and Mariner package-based install paths to:
    • use the cached versioned binaries when available
    • fall back to existing package install behavior when the cache is not present
    • continue respecting SHOULD_ENFORCE_KUBE_PMC_INSTALL=true

Tests

  • add/extend coverage for the cache-first kubelet/kubectl flow
  • extend Linux VHD content validation to verify package-backed kubelet/kubectl versions also materialize versioned binaries in
    /opt/bin

Why

This keeps kubelet/kubectl aligned with the existing kubernetes-binaries flow:

  • cache versioned binaries on the image
  • do a cheap final move during provisioning

Expected benefits:

  • lower CSE latency
  • avoid unnecessary package-manager work during provisioning
  • avoid Ubuntu kubelet package postinst side effects when the VHD already has the requested binary

Notes

  • this does not remove the existing package fallback path
  • if the versioned binary is missing, CSE still falls back to the current package installation behavior
  • SHOULD_ENFORCE_KUBE_PMC_INSTALL=true still forces the package path for validation / test scenarios

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

PR Title Lint Failed ❌

Current Title: Cache versioned kubelet kubectl package binaries

Your PR title doesn't follow the expected format. Please update your PR title to follow one of these patterns:

Conventional Commits Format:

  • feat: add new feature - for new features
  • fix: resolve bug in component - for bug fixes
  • docs: update README - for documentation changes
  • refactor: improve code structure - for refactoring
  • test: add unit tests - for test additions
  • chore: remove dead code - for maintenance tasks
  • chore(deps): update dependencies - for updating dependencies
  • ci: update build pipeline - for CI/CD changes

Guidelines:

  • Use lowercase for the type and description
  • Keep the description concise but descriptive
  • Use imperative mood (e.g., "add" not "adds" or "added")
  • Don't end with a period

Examples:

  • feat(windows): add secure TLS bootstrapping for Windows nodes
  • fix: resolve kubelet certificate rotation issue
  • docs: update installation guide
  • Added new feature
  • Fix bug.
  • Update docs

Please update your PR title and the lint check will run again automatically.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes Linux node provisioning by reusing kubelet/kubectl binaries already cached on the VHD (materialized as versioned files under /opt/bin) instead of reinstalling via the package manager during CSE.

Changes:

  • VHD build: extract kubelet/kubectl binaries from cached .deb/.rpm artifacts into /opt/bin/<tool>-<k8sVersion>.
  • CSE: add shared helpers to detect/move cached versioned kube binaries; update Ubuntu and Mariner package-based kubelet/kubectl install paths to prefer cache unless SHOULD_ENFORCE_KUBE_PMC_INSTALL=true.
  • Tests: extend VHD content validation and add/extend ShellSpec coverage for the cache-first behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
vhdbuilder/packer/install-dependencies.sh Adds VHD-build extraction of kubelet/kubectl binaries from cached package artifacts into versioned /opt/bin paths.
vhdbuilder/packer/test/linux-vhd-content-test.sh Extends VHD content tests to validate versioned package-backed kubelet/kubectl binaries exist and match expected versions.
parts/linux/cloud-init/artifacts/cse_install.sh Adds shared helpers to detect and move cached versioned kubelet/kubectl binaries; reuses them in the URL-based install flow.
parts/linux/cloud-init/artifacts/ubuntu/cse_install_ubuntu.sh Updates Ubuntu package-based kubelet/kubectl install path to prefer cached versioned binaries.
parts/linux/cloud-init/artifacts/mariner/cse_install_mariner.sh Updates Mariner/AzureLinux package-based kubelet/kubectl install path to prefer cached versioned binaries.
spec/parts/linux/cloud-init/artifacts/cse_install_ubuntu_spec.sh Adds ShellSpec coverage for Ubuntu cache-first kubelet/kubectl install behavior.
spec/parts/linux/cloud-init/artifacts/cse_install_mariner_spec.sh Adds ShellSpec coverage for Mariner cache-first kubelet/kubectl install behavior.

Comment on lines +14 to +31
installKubeletKubectlFromURL() {
echo "installKubeletKubectlFromURL"
}

installPkgWithAptGet() {
echo "installPkgWithAptGet $*"
}

It 'uses cached kubernetes-binaries when both versioned binaries are already present'
hasCachedKubeBinariesForVersion() {
return 0
}

When call installKubeletKubectlFromPkg "1.34.4"
The output should include "Found cached kubernetes-binaries for 1.34.4; installing from /opt/bin cache"
The output should include "installKubeletKubectlFromURL"
The output should not include "installPkgWithAptGet"
End
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

These tests stub installKubeletKubectlFromURL and assert it is called when cached binaries are present, but installKubeletKubectlFromPkg now calls moveCachedKubeBinariesForVersion directly. Without stubbing moveCachedKubeBinariesForVersion, the spec will execute the real mv/rm operations and likely fail. Update the spec to stub/assert moveCachedKubeBinariesForVersion instead of installKubeletKubectlFromURL.

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +127
Describe 'installKubeletKubectlFromPkg'
installKubeletKubectlFromURL() {
echo "installKubeletKubectlFromURL"
}

installRPMPackageFromFile() {
echo "installRPMPackageFromFile $*"
}

It 'uses cached versioned kube binaries when available'
SHOULD_ENFORCE_KUBE_PMC_INSTALL=""
hasCachedKubeBinariesForVersion() {
return 0
}

When call installKubeletKubectlFromPkg "1.34.4"
The output should include "Found cached kubernetes-binaries for 1.34.4; installing from /opt/bin cache"
The output should include "installKubeletKubectlFromURL"
The output should not include "installRPMPackageFromFile"
End
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

These tests stub installKubeletKubectlFromURL and assert it is called on cache hit, but installKubeletKubectlFromPkg now calls moveCachedKubeBinariesForVersion directly. Without stubbing moveCachedKubeBinariesForVersion, the spec will run the real mv/rm and fail. Update the spec to stub/assert moveCachedKubeBinariesForVersion instead.

Copilot uses AI. Check for mistakes.
k8sVersion="${1}"
local k8sVersion="${1}"
if [ "${SHOULD_ENFORCE_KUBE_PMC_INSTALL}" != "true" ] && hasCachedKubeBinariesForVersion "${k8sVersion}"; then
echo "Found cached kubernetes-binaries for ${k8sVersion}; installing from /opt/bin cache"
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

The log line says "Found cached kubernetes-binaries..." but this path now also covers versioned kubelet/kubectl extracted from cached PMC packages (not just the kubernetes-binaries tarball). Consider changing the message to something source-agnostic (e.g., "Found cached kubelet/kubectl binaries for in /opt/bin").

Suggested change
echo "Found cached kubernetes-binaries for ${k8sVersion}; installing from /opt/bin cache"
echo "Found cached kubelet/kubectl binaries for ${k8sVersion} in /opt/bin"

Copilot uses AI. Check for mistakes.
installKubeletKubectlFromPkg() {
local desiredVersion="${1}"
if [ "${SHOULD_ENFORCE_KUBE_PMC_INSTALL}" != "true" ] && hasCachedKubeBinariesForVersion "${desiredVersion}"; then
echo "Found cached kubernetes-binaries for ${desiredVersion}; installing from /opt/bin cache"
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

The log line says "Found cached kubernetes-binaries..." but this path now also covers versioned kubelet/kubectl extracted from cached RPM/DEB packages (not just the kubernetes-binaries tarball). Consider changing the message to something source-agnostic (e.g., "Found cached kubelet/kubectl binaries for in /opt/bin").

Suggested change
echo "Found cached kubernetes-binaries for ${desiredVersion}; installing from /opt/bin cache"
echo "Found cached kubelet/kubectl binaries for ${desiredVersion} in /opt/bin"

Copilot uses AI. Check for mistakes.
Comment on lines +309 to +313
return 1
fi

rpm2cpio "${rpm_file}" | cpio -i --to-stdout "./usr/bin/${package_name}" "./usr/local/bin/${package_name}" | install -m0755 /dev/stdin "${binary_path}"
else
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

rpm2cpio | cpio -i --to-stdout is passed two possible binary paths (./usr/bin/${package_name} and ./usr/local/bin/${package_name}) and pipes stdout into install. With set -o pipefail enabled for this script, any non-zero from cpio will fail the VHD build, and if both paths ever exist in the RPM, cpio will emit both files to stdout sequentially, corrupting the cached binary. To make this robust, extract exactly one path (e.g., inspect the RPM file list first and then extract that single entry, or try /usr/bin/... and only fall back to /usr/local/bin/... if needed).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants