From f81e280ca96c0bf8037d4bf041ac810d168e838d Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Tue, 3 Feb 2026 15:41:09 -0500 Subject: [PATCH 1/2] fix install-containerd-ubuntu to skip apt when both versions specified when both UBUNTU_INSTALL_CONTAINERD_VERSION and UBUNTU_INSTALL_RUNC_VERSION are set, skip apt entirely and download binaries directly from GitHub. this avoids installing apt packages that get immediately overwritten. Signed-off-by: Davanum Srinivas --- cluster/gce/gci/configure.sh | 132 +++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 52 deletions(-) diff --git a/cluster/gce/gci/configure.sh b/cluster/gce/gci/configure.sh index a5cb3506ee1..3a268a9d34f 100644 --- a/cluster/gce/gci/configure.sh +++ b/cluster/gce/gci/configure.sh @@ -510,70 +510,98 @@ function load-docker-images { fi } -# If we are on ubuntu we can try to install containerd +# Create containerd systemd service (needed when skipping apt install) +function ensure-containerd-systemd-service { + local -r svc="/etc/systemd/system/containerd.service" + [[ -f "${svc}" ]] && return 0 + cat > "${svc}" <<'EOF' +[Unit] +Description=containerd container runtime +Documentation=https://containerd.io +After=network.target local-fs.target +[Service] +ExecStartPre=-/sbin/modprobe overlay +ExecStart=/usr/bin/containerd +Type=notify +Delegate=yes +KillMode=process +Restart=always +RestartSec=5 +LimitNPROC=infinity +LimitCORE=infinity +LimitNOFILE=infinity +TasksMax=infinity +OOMScoreAdjust=-999 +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload && systemctl enable containerd +} + +# Download and install containerd binary from GitHub +function install-containerd-binary { + local -r version="$1" temp_dir="$(mktemp -d)" + local -r url="https://github.com/containerd/containerd/releases/download/${version}/containerd-${version#v}-${HOST_PLATFORM}-${HOST_ARCH}.tar.gz" + if download-robust "containerd ${version}" "${temp_dir}" "${url}"; then + tar --overwrite -xzf "${temp_dir}"/containerd-*.tar.gz -C /usr/ + rm -rf "${temp_dir}"; return 0 + fi + rm -rf "${temp_dir}"; return 1 +} + +# Download and install runc binary from GitHub +function install-runc-binary { + local -r version="$1" temp_dir="$(mktemp -d)" + local -r url="https://github.com/opencontainers/runc/releases/download/${version}/runc.${HOST_ARCH}" + if download-robust "runc ${version}" "${temp_dir}" "${url}"; then + cp "${temp_dir}/runc.${HOST_ARCH}" /usr/sbin/runc && chmod 755 /usr/sbin/runc + rm -rf "${temp_dir}"; return 0 + fi + rm -rf "${temp_dir}"; return 1 +} + +# Install containerd on Ubuntu. When both UBUNTU_INSTALL_CONTAINERD_VERSION and +# UBUNTU_INSTALL_RUNC_VERSION are set, skips apt and downloads binaries directly. function install-containerd-ubuntu { - # bailout if we are not on ubuntu if [[ -z "$(command -v lsb_release)" || $(lsb_release -si) != "Ubuntu" ]]; then - echo "Unable to automatically install containerd in non-ubuntu image. Bailing out..." - exit 2 + echo "Unable to automatically install containerd in non-ubuntu image. Bailing out..."; exit 2 fi - # Install dependencies, some of these are already installed in the image but - # that's fine since they won't re-install and we can reuse the code below - # for another image someday. + local -r custom_containerd="${UBUNTU_INSTALL_CONTAINERD_VERSION:-}" + local -r custom_runc="${UBUNTU_INSTALL_RUNC_VERSION:-}" + apt-get update - apt-get install -y --no-install-recommends \ - apt-transport-https \ - ca-certificates \ - socat \ - curl \ - gnupg2 \ - nfs-common \ - software-properties-common \ - lsb-release + apt-get install -y --no-install-recommends apt-transport-https ca-certificates \ + socat curl gnupg2 nfs-common software-properties-common lsb-release - release=$(lsb_release -cs) + # Both versions specified: skip apt, install binaries directly + if [[ -n "${custom_containerd}" && -n "${custom_runc}" ]]; then + echo "Installing containerd ${custom_containerd} and runc ${custom_runc} (skipping apt)" + ensure-containerd-systemd-service + install-containerd-binary "${custom_containerd}" || { echo "ERROR: containerd download failed"; exit 1; } + install-runc-binary "${custom_runc}" || { echo "ERROR: runc download failed"; exit 1; } + systemctl start containerd + return + fi - # Add the Docker apt-repository (as we install containerd from there) + # Install from Docker apt repo, optionally override binaries + local -r release="$(lsb_release -cs)" + local -r keyring="/etc/apt/keyrings/docker.gpg" + mkdir -p "$(dirname "${keyring}")" # shellcheck disable=SC2086 - curl ${CURL_FLAGS} \ - --location \ - "https://download.docker.com/${HOST_PLATFORM}/$(. /etc/os-release; echo "$ID")/gpg" \ - | apt-key add - - add-apt-repository \ - "deb [arch=${HOST_ARCH}] https://download.docker.com/${HOST_PLATFORM}/$(. /etc/os-release; echo "$ID") \ - $release stable" + curl ${CURL_FLAGS} -fsSL "https://download.docker.com/${HOST_PLATFORM}/$(. /etc/os-release; echo "$ID")/gpg" \ + | gpg --batch --dearmor -o "${keyring}" + chmod a+r "${keyring}" + echo "deb [arch=${HOST_ARCH} signed-by=${keyring}] https://download.docker.com/${HOST_PLATFORM}/$(. /etc/os-release; echo "$ID") ${release} stable" \ + > /etc/apt/sources.list.d/docker.list - # Install containerd from Docker repo - apt-get update && \ - apt-get install -y --no-install-recommends containerd + apt-get update && apt-get install -y --no-install-recommends containerd.io rm -rf /var/lib/apt/lists/* - # Override to latest versions of containerd and runc systemctl stop containerd - if [[ -n "${UBUNTU_INSTALL_CONTAINERD_VERSION:-}" ]]; then - local temp_dir - temp_dir=$(mktemp -d) - - # Download containerd - if download-robust "containerd ${UBUNTU_INSTALL_CONTAINERD_VERSION}" "${temp_dir}" \ - "https://github.com/containerd/containerd/releases/download/${UBUNTU_INSTALL_CONTAINERD_VERSION}/containerd-${UBUNTU_INSTALL_CONTAINERD_VERSION:1}-${HOST_PLATFORM}-${HOST_ARCH}.tar.gz"; then - tar --overwrite -xzv -C /usr/ -f "${temp_dir}"/containerd-*.tar.gz - fi - rm -rf "${temp_dir}" - fi - if [[ -n "${UBUNTU_INSTALL_RUNC_VERSION:-}" ]]; then - local temp_dir - temp_dir=$(mktemp -d) - - # Download and install runc - if download-robust "runc ${UBUNTU_INSTALL_RUNC_VERSION}" "${temp_dir}" \ - "https://github.com/opencontainers/runc/releases/download/${UBUNTU_INSTALL_RUNC_VERSION}/runc.${HOST_ARCH}"; then - cp "${temp_dir}/runc.${HOST_ARCH}" /usr/sbin/runc && chmod 755 /usr/sbin/runc - fi - rm -rf "${temp_dir}" - fi - sudo systemctl start containerd + [[ -n "${custom_containerd}" ]] && install-containerd-binary "${custom_containerd}" + [[ -n "${custom_runc}" ]] && install-runc-binary "${custom_runc}" + systemctl start containerd } # If we are on cos we can try to install containerd From 67043dca9fb6e5a50c0a0bc27433057f73ae2ad1 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Tue, 3 Feb 2026 16:48:22 -0500 Subject: [PATCH 2/2] disable unnecessary Ubuntu services during node bootstrap Mask and stop services that compete with apt operations or are not needed for Kubernetes nodes: - apt-news.service/timer: fetches APT news, holds apt lock - esm-cache.service: Ubuntu Pro cache updates - snapd.service/socket: Snap package manager - lxd-installer.socket: LXD container helper - ubuntu-advantage.service: Ubuntu Pro auto-attach - unattended-upgrades.service: automatic security updates - motd-news.timer: MOTD news fetching - update-notifier-motd.timer: "new Ubuntu version" checks - update-notifier-download.timer: failed package retry This addresses CI timeouts where apt-news.service running concurrently with apt-get update caused the master node to take ~5 minutes for package index downloads (vs ~5-9 seconds on worker nodes). Signed-off-by: Davanum Srinivas --- cluster/gce/gci/master.yaml | 2 ++ cluster/gce/gci/node.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cluster/gce/gci/master.yaml b/cluster/gce/gci/master.yaml index 75cf541c98f..adde05a3570 100644 --- a/cluster/gce/gci/master.yaml +++ b/cluster/gce/gci/master.yaml @@ -129,6 +129,8 @@ write_files: WantedBy=multi-user.target runcmd: + - systemctl mask apt-news.service apt-news.timer esm-cache.service snapd.service snapd.socket lxd-installer.socket ubuntu-advantage.service unattended-upgrades.service motd-news.timer update-notifier-motd.timer update-notifier-download.timer || true + - systemctl stop unattended-upgrades.service || true - systemctl daemon-reload - systemctl enable kube-bootstrap-logs-forwarder.service - systemctl enable kube-master-installation.service diff --git a/cluster/gce/gci/node.yaml b/cluster/gce/gci/node.yaml index 3d03df211b7..dabaf9145bf 100644 --- a/cluster/gce/gci/node.yaml +++ b/cluster/gce/gci/node.yaml @@ -87,6 +87,8 @@ write_files: options sunrpc max_resvport=986 runcmd: + - systemctl mask apt-news.service apt-news.timer esm-cache.service snapd.service snapd.socket lxd-installer.socket ubuntu-advantage.service unattended-upgrades.service motd-news.timer update-notifier-motd.timer update-notifier-download.timer || true + - systemctl stop unattended-upgrades.service || true - systemctl daemon-reload - systemctl enable kube-node-installation.service - systemctl enable kube-node-configuration.service