The Invisible Rewrite: Modernizing the Kubernetes Image Promoter

Bài tóm tắt Kubernetes 2026 4. Điều chỉnh Độ khó: Trung bình

Kubernetes · 2026 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc

Bài của SIG Release. Phần chữ ký số (cosign, SLSA, SBOM) chỉ tóm tắt ngắn; lõi của bài là viết lại một công cụ hạ tầng mà mọi bản phát hành phụ thuộc, theo từng pha, không ai nhận ra.

Bối cảnh

  • Mọi image trên registry.k8s.io đi qua kpromo: chép image từ registry staging sang production, ký bằng cosign, nhân bản chữ ký ra hơn 20 mirror theo vùng, sinh attestation SLSA. Công cụ này hỏng thì không bản Kubernetes nào phát hành được.
  • Lịch sử: bắt đầu cuối 2018 ở Google để thay quy trình chép image thủ công (chỉ nhân viên Google làm được) bằng quy trình GitOps của cộng đồng: đẩy lên staging, mở PR với manifest YAML, merge xong thì automation lo phần còn lại. Bảy năm, 42 người đóng góp, khoảng 3.500 commit, hơn 60 release; README tự nhận có code trùng lặp, nhiều cách làm cùng một việc.
  • Đến 2025: job promote image lõi thường mất hơn 30 phút và hay lỗi vì rate limit; phần lõi là một khối khó mở rộng, khó test.

Thay đổi chính

  • Tháng 2/2026 mở một issue theo dõi, trả lời cả tám câu hỏi nghiên cứu còn treo, rồi viết lại theo chín pha, mỗi pha review, merge, kiểm chứng độc lập: rate limiting với backoff thích ứng → đưa registry/auth sau interface → pipeline engine chạy promote thành chuỗi pha riêng → kiểm tra provenance → quét lỗ hổng, SBOM, bật engine mới làm mặc định (cắt v4.2.0, cho chạy thử ở production) → tách ký khỏi nhân bản chữ ký → xoá đường cũ → xoá phụ thuộc cũ → xoá khối lõi cũ (v4.3.0 ngay hôm sau).
  • Pipeline mới bảy pha chạy tuần tự (Setup → Plan → Provenance → Validate → Promote → Sign → Attest), mỗi pha có trọn ngân sách rate limit, hết tranh chấp. Nhân bản chữ ký ra mirror chuyển thành job định kỳ riêng.
  • Tăng tốc sau khi có kiến trúc mới:
    • Đọc song song 1.350 registry: pha Plan từ khoảng 20 phút còn 2 phút.
    • Liệt kê tag hai pha: kiểm tra repo nguồn trước; khoảng 57% image không có chữ ký (promote trước khi bật ký) nên bỏ qua, số lời gọi API giảm khoảng một nửa.
    • Kiểm tra chữ ký trên registry chính trước khi lặp qua mirror: ở trạng thái ổn định giảm việc từ khoảng 17 giờ còn 15 phút.
    • Timeout cho từng request: từng có kết nối treo chặn pipeline hơn 9 giờ; nay mỗi thao tác mạng có timeout và tự thử lại.
    • Dùng lại kết nối HTTP và trạng thái auth.
  • Tổng: hơn 40 PR, 3 release; thêm hơn 10.000 dòng, xoá hơn 16.000, code nhỏ đi khoảng 20% dù có thêm tính năng; đóng 19 issue tồn lâu.
  • Không đổi gì phía người dùng: cùng lệnh, cùng flag, cùng manifest YAML, job Prow vẫn chạy suốt quá trình. Bắt được hai regression sớm ở production (một làm mọi image trông như "mất" nên không promote gì; một đặt số luồng mặc định bằng 0, chặn mọi goroutine), sửa trong vài giờ. Chiến lược hai release (engine mới, rồi mới xoá code cũ) cho một đường rollback rõ, dù không phải dùng.

Vì sao

  • Kiến trúc tách pha làm các cải tiến sau (song song, retry, timeout, provenance) dễ đưa vào; trước đó mỗi tính năng mới đều đau.

Bài học cho SWE

  • Viết lại hạ tầng quan trọng thì giữ nguyên giao diện và đi từng pha: bật đường mới làm mặc định, chạy thử, rồi mới xoá đường cũ ở release sau, để luôn có đường lui (Migration không downtime, Deploy và release an toàn).
  • Lỗi rate limit thường là tranh chấp giữa các việc chạy cùng lúc; chạy tuần tự từng pha hoặc tách việc phụ ra job riêng có thể nhanh hơn chạy song song tất cả.
  • Mọi lời gọi mạng cần timeout riêng: một kết nối treo có thể chặn cả pipeline hàng giờ.
  • Kiểm tra rẻ trước khi làm việc đắt (registry chính trước mirror, bỏ image không có chữ ký) cắt được nhiều bậc độ lớn.
  • Viết lại tốt có thể làm code nhỏ đi trong khi thêm tính năng.

Liên quan