cloud-init: fix k8s node bootstrap snippet (multi-line interp + containerd v2 quotes)
Two bugs found while rebuilding k8s-node4 (2026-05-26):
1. **runcmd YAML breakage**: `- $${containerd_config_update_command}`
interpolated a multi-line heredoc as bare list-item content. The
trailing lines lost their list-item prefix, breaking cloud-config
parsing. Cloud-init silently fell back to the minimal default
(hostname + package_upgrade only) — kubeadm join, containerd config,
kubelet tuning, iSCSI hardening, swap, ALL skipped. No error visible
in `cloud-init status`.
Fix: wrap the interpolation in `- |` literal block with `indent(4, ...)`.
2. **containerd v2 single-quote mismatch**: `containerd config default`
in v2 writes `config_path = ''` (single quotes), v1 writes `""` (double).
The sed pattern matched only double quotes → silent no-op on fresh
containerd 2.x nodes → registry-mirror hosts.toml ignored → all image
pulls hit upstream registries → DNS-to-MetalLB chicken-and-egg loop.
Fix: match any value with `config_path = .*`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
445feb118f
commit
9b75b2817b
2 changed files with 12 additions and 3 deletions
|
|
@ -107,7 +107,12 @@ runcmd:
|
|||
- apt-mark hold containerd containerd.io runc 2>/dev/null || true
|
||||
- systemctl stop kubelet
|
||||
- containerd config default | sudo tee /etc/containerd/config.toml
|
||||
- ${containerd_config_update_command}
|
||||
# Multi-line containerd config update — wrapped in `- |` literal block so the
|
||||
# heredoc content survives YAML rendering. Without this, the multi-line var
|
||||
# gets inserted as bare top-level lines and breaks the cloud-config parser
|
||||
# (silent fallback to default — observed 2026-05-26 during node4 rebuild).
|
||||
- |
|
||||
${indent(4, containerd_config_update_command)}
|
||||
- systemctl restart containerd
|
||||
- systemctl enable --now iscsid
|
||||
# Harden iSCSI: increase recovery timeout (300s vs 120s default) and enable
|
||||
|
|
|
|||
|
|
@ -64,8 +64,12 @@ module "k8s-node-template" {
|
|||
snippet_name = local.k8s_cloud_init_snippet_name
|
||||
# Add mirror registry
|
||||
containerd_config_update_command = <<-EOF
|
||||
# Set up config_path for per-registry mirror configuration
|
||||
sed -i 's|config_path = ""|config_path = "/etc/containerd/certs.d"|' /etc/containerd/config.toml
|
||||
# Set up config_path for per-registry mirror configuration.
|
||||
# NOTE: containerd v2 writes `config_path = ''` (single quotes) on
|
||||
# `config default`; v1 writes `config_path = ""`. Match both forms so this
|
||||
# is idempotent across versions. Without the v2 match, hosts.toml mirror
|
||||
# config is silently ignored — observed 2026-05-26 on node4 (containerd v2.2.4).
|
||||
sed -i 's|config_path = .*|config_path = "/etc/containerd/certs.d"|' /etc/containerd/config.toml
|
||||
|
||||
# Create hosts.toml for docker.io (Docker Hub) — high traffic, rate-limited
|
||||
mkdir -p /etc/containerd/certs.d/docker.io
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue