보이지 않는 재작성: Kubernetes Image Promoter 현대화

발행: (2026년 3월 17일 AM 09:00 GMT+9)
17 분 소요

Source: Kubernetes Blog

번역을 진행하려면 실제 블로그 본문 텍스트가 필요합니다. 번역하고자 하는 전체 내용(마크다운 형식 포함)을 제공해 주시면, 요청하신 대로 한국어로 번역해 드리겠습니다.

개요

당신이 registry.k8s.io에서 끌어오는 모든 컨테이너 이미지는 kpromo, 즉 Kubernetes 이미지 프로모터를 통해 전달됩니다. 이 도구는 스테이징 레지스트리에서 프로덕션으로 이미지를 복사하고, cosign으로 서명하며, 20개가 넘는 지역 미러에 서명을 복제하고, SLSA provenance 증명을 생성합니다. 이 도구가 고장 나면 Kubernetes 릴리스가 배포되지 않습니다.

지난 몇 주 동안 우리는:

  • 핵심을 처음부터 다시 작성했습니다
  • 코드베이스의 20 %를 삭제했습니다
  • 성능을 크게 향상시켰습니다

…그리고 아무도 눈치채지 못했습니다. 그게 바로 요점이었습니다.

약간의 역사

연도이정표
2018년 말이미지 프로모터는 Linus Arver가 시작한 구글 내부 프로젝트였습니다. 목표: k8s.gcr.io에 컨테이너 이미지를 복사하는 수동적이고 구글러가 관리하는 과정을 커뮤니티가 소유하고 GitOps 기반 워크플로우(스테이징 레지스트리에 푸시 → YAML 매니페스트로 PR 열기 → 검토 및 병합 → 자동화가 나머지 처리)로 대체하는 것. KEP‑1734가 이 제안을 공식화했습니다.
2019년 초코드가 kubernetes-sigs/k8s-container-image-promoter 로 이동하면서 빠르게 성장했습니다.
그 이후Stephen Augustus가 여러 도구(cip, gh2gcs, krel promote-images, promobot-files)를 하나의 CLI인 kpromo 로 통합했습니다. 저장소 이름은 promo-tools 로 바뀌었습니다.
기여Adolfo Garcia Veytia (Puerco) 가 cosign 서명과 SBOM 지원을 추가했습니다. Tyler Ferrara 가 취약점 스캔을 구축했습니다. Carlos Panato 가 프로젝트를 건강하고 릴리즈 가능한 상태로 유지했습니다. 42명의 기여자가 ~3,500개의 커밋을 60개가 넘는 릴리즈에 걸쳐 작성했습니다.
2025년코드베이스는 여러 SIG와 하위 프로젝트에서 7년 동안 누적된 추가 사항을 포함하고 있었습니다. README에는 “중복된 코드, 동일한 작업을 수행하는 여러 기술, 그리고 여러 TODO가 보일 것입니다.” 라고 경고하고 있었습니다.

작동은 했지만, 모놀리식 아키텍처 때문에 새로운 기능(예: 프로베넌스나 취약점 스캔) 등을 확장하고 테스트하기가 어려웠습니다.

우리가 해결해야 했던 문제들

  • Production promotion jobs for Kubernetes core images가 정기적으로 > 30 분이 걸렸고, 종종 rate‑limit 오류로 실패했습니다.
  • 핵심 promotion 로직이 monolith 형태가 되어 확장이 어렵고 테스트도 힘들었습니다.
  • SIG Release 로드맵 항목인 “Rewrite artifact promoter”와 “Make artifact validation more robust”가 정리될 때까지 대기하고 있었습니다.

project board #171에 있는 여덟 개의 오픈 리서치 스파이크가 앞으로 진행하기 전에 답을 찾아야 할 질문들을 포착했습니다.

모든 문제를 해결하는 하나의 이슈

2026 년 2월issue #1701(“Rewrite artifact promoter pipeline”)을 열고, 여덟 개의 스파이크를 모두 하나의 트래킹 이슈로 해결했습니다. 리라이트는 각 단계가 독립적으로 검토·병합·검증될 수 있도록 의도적으로 단계별로 진행되었습니다.

단계

단계이슈우리가 한 일
Phase 1 – Rate Limiting#1702적응형 백오프를 사용하여 모든 레지스트리 작업을 적절히 제한하도록 Rate Limiting을 다시 작성했습니다.
Phase 2 – Interfaces#1704레지스트리 및 인증 작업을 깔끔한 인터페이스 뒤에 두어 교체 및 독립적으로 테스트할 수 있게 했습니다.
Phase 3 – Pipeline Engine#1705프로모션을 하나의 거대한 함수가 아니라 구분된 단계들의 순서로 실행하는 파이프라인 엔진을 구축했습니다.
Phase 4 – Provenance#1706스테이징 이미지에 대한 SLSA Provenance 검증을 추가했습니다.
Phase 5 – Scanner & SBOMs#1709취약점 스캔 및 SBOM 지원을 추가했습니다. 기본값을 새로운 파이프라인 엔진으로 전환했습니다. v4.2.0을 배포하고, 다음 단계로 진행하기 전에 프로덕션에서 충분히 검증했습니다.
Phase 6 – Split Signing from Replication#1713이미지 서명을 서명 복제와 분리하여 각각 별도의 파이프라인 단계로 만들었으며, 대부분의 프로덕션 장애를 일으키던 Rate Limiting 충돌을 제거했습니다.
Phase 7 – Remove Legacy Pipeline#1712구식 코드 경로를 완전히 삭제했습니다.
Phase 8 – Remove Legacy Dependencies#1716감사 서브시스템, 사용 중단된 도구, 그리고 e2e 테스트 인프라를 삭제했습니다.
Phase 9 – Delete the Monolith#1718구식 모놀리식 코어와 그 지원 패키지를 제거했습니다. 7‑9단계에 걸쳐 수천 줄의 코드가 삭제되었습니다.

각 단계는 독립적으로 배포되었습니다. 다음 날 v4.3.0이 출시되어 레거시 코드가 완전히 제거되었습니다.

후속 개선 사항

새로운 아키텍처가 구축되면서 일련의 후속 개선이 적용되었습니다:

  • 레지스트리 읽기 병렬화 (#1736)
  • 모든 네트워크 작업에 대한 재시도 로직 (#1742)
  • 파이프라인 정지를 방지하기 위한 요청당 타임아웃 (#1763)
  • HTTP 연결 재사용 (#1759)
  • 로컬 레지스트리 통합 테스트 (#1746)
  • 폐기된 credential‑file 지원 제거 (#1758)
  • cosign의 OCI API를 사용하도록 attestation 처리 재구성 및 폐기된 SBOM 지원 제거 (#1764)
  • in‑toto attestation 프레임워크에 등록된 전용 promotion‑record 프레디케이트 타입 (#1767)

이러한 개선 사항들은 리팩터링이 제공한 명확한 분리 없이는 적용하기 훨씬 어려웠을 것입니다. v4.4.0은 이 모든 개선을 포함하여 기본적으로 provenance 생성 및 검증을 활성화했습니다.

새로운 파이프라인

프로모션 파이프라인은 이제 명확히 구분된 일곱 단계로 구성됩니다:

graph LR
    Setup --> Plan --> Provenance --> Validate --> Promote --> Sign --> Attest
단계수행 내용
Setup옵션을 검증하고 TUF 캐시를 미리 준비합니다.
Plan매니페스트를 파싱하고 레지스트리를 읽어, 어떤 이미지가 프로모션이 필요한지 계산합니다.
Provenance스테이징 이미지에 대한 SLSA 어태스테이션을 검증합니다.
Validatecosign 서명을 확인합니다; 여기서 드라이런일 경우 종료합니다.
Promote서버 측에서 이미지를 복사하고 다이제스트를 보존합니다.
Sign키 없는 cosign으로 프로모션된 이미지를 서명합니다.
Attest전용 in‑toto 프레디케이트 타입을 사용해 프로모션 증명 어태스테이션을 생성합니다.

단계는 순차적으로 실행되므로 각 단계가 전체 레이트‑리밋 예산에 독점적으로 접근합니다—더 이상 경쟁이 없습니다.
시그니처 복제는 이제 이 파이프라인의 일부가 아니며, 전용 주기적 Prow 작업으로 실행됩니다.

빠르게 만들기

병렬 레지스트리 읽기 (#1736)

Plan 단계는 1,350개의 레지스트리를 읽습니다. 이를 병렬화함으로써 단계가 ~20 분에서 ~2 분으로 단축되었습니다.

두 단계 태그 나열 (#1761)

46,000개의 이미지 그룹을 20개 이상의 미러 전체에서 확인하는 대신, 먼저 소스 레지스트리만 확인하여 필요한 작업량을 크게 줄였습니다.

요약

  • kpromo의 핵심을 처음부터 다시 작성하고 코드베이스의 20 %를 삭제했습니다.
  • 단일형 프로모션 프로세스를 seven개의 명확히 정의된 단계로 분할했습니다.
  • 견고한 속도 제한, 깔끔한 인터페이스, 플러그인 가능한 파이프라인 엔진을 추가했습니다.
  • SLSA provenance, 취약점 스캔, SBOM, 키 없는 cosign 서명을 통합했습니다.
  • 성능이 크게 향상되었습니다 (Plan 단계가 20 → 2 분으로 단축).
  • 시스템을 테스트, 확장, 유지보수가 더 쉬워졌으며, 향후 Kubernetes 릴리스가 안정적으로 배포될 수 있도록 보장했습니다.

Source check before replication (#1727)

주어진 이미지에 대해 모든 미러를 순회하기 전에, 먼저 기본 레지스트리에서 서명이 존재하는지 확인합니다. 정상 상태에서는 대부분의 서명이 이미 복제되어 있기 때문에, 작업 시간을 ≈ 17 시간에서 ≈ 15 분으로 줄였습니다.

요청당 타임아웃 (#1763)

우리는 간헐적인 정지 현상을 관찰했으며, 정체된 연결이 파이프라인을 9 시간 이상 차단했습니다. 이제 모든 네트워크 작업마다 자체 타임아웃이 설정되어 있으며, 일시적인 오류는 자동으로 재시도됩니다.

Connection reuse (#1759)

우리는 HTTP 연결과 인증 상태를 작업 간에 재사용하기 시작했으며, 중복된 토큰 협상을 제거했습니다. 이를 통해 2023년부터 지속되던 요청을 마무리했습니다.

숫자로 보는 성과

  • > 40 PRs 병합, 3개의 릴리스 배포 (v4.2.0, v4.3.0, v4.4.0)
  • > 10 000 라인 추가> 16 000 라인 삭제 → 순 감소 ≈ 5 000 라인 (코드베이스 약 20 % 축소)
  • 전반적으로 성능이 크게 향상됨
  • 재시도 로직, 요청당 타임아웃, 적응형 속도 제한을 도입해 견고성이 향상됨
  • 19개의 장기 미해결 이슈 해결
  • 코드베이스가 1/5 감소하면서 다음을 얻음:
    • 출처 증명
    • 파이프라인 엔진
    • 취약점 스캔 통합
    • 병렬 작업
    • 재시도 로직
    • 로컬 레지스트리를 대상으로 한 통합 테스트
    • 독립형 서명 복제 모드

사용자에게 보이는 변경 사항 없음

  • kpromo cip 명령은 여전히 동일한 플래그를 받아들이고 동일한 YAML 매니페스트를 읽습니다.
  • post‑k8sio‑image‑promo Prow 작업은 계속해서 정상적으로 작동했습니다.
  • kubernetes/k8s.io의 프로모션 매니페스트는 변경되지 않았으며, 따라서 워크플로우나 설정 업데이트가 필요하지 않았습니다.

우리는 프로덕션 초기에 두 가지 회귀를 발견했습니다:

  1. #1731 – 레지스트리 키 불일치로 모든 이미지가 “손실된” 것으로 표시되어 프로모션이 차단되었습니다.
  2. #1733 – 기본 스레드 수가 0으로 설정되어 모든 고루틴이 차단되었습니다.

두 문제 모두 몇 시간 안에 해결되었습니다. 단계적 릴리스 전략(v4.2.0에 새 엔진, v4.3.0에 레거시 코드 제거)을 통해 명확한 롤백 경로를 확보했으며, 다행히도 실제로 롤백할 필요는 없었습니다.

다음 단계

모든 미러 레지스트리에서 서명 복제는 프로모션 사이클에서 가장 비용이 많이 드는 부분입니다.

  • Issue #1762archeio( registry.k8s.io 리다이렉트 서비스)가 서명‑태그 요청을 지역별 백엔드가 아니라 단일 정규 업스트림으로 라우팅하도록 하여 이를 완전히 없애는 방안을 제안합니다.
  • 또 다른 옵션은 서명 작업을 레지스트리 인프라 자체에 더 가깝게 이동시키는 것입니다.

두 접근 방식 모두 SIG Releaseinfrastructure 팀과의 추가 논의가 필요하지만, 어느 쪽이든 프로모션 사이클당 수천 건의 API 호출을 제거하고 코드베이스를 더욱 간소화할 수 있습니다.

감사드립니다

이 프로젝트는 7년에 걸친 커뮤니티 노력의 결과였습니다. 코드, 리뷰, 그리고 계획에 기여해 주신 Linus, Stephen, Adolfo, Carlos, Ben, Marko, Lauri, Tyler, Arnaud와 그 외 많은 분들께 감사드립니다.

SIG ReleaseRelease Engineering 커뮤니티는 모든 Kubernetes 릴리스가 의존하는 인프라 재작성에 필요한 맥락, 논의, 그리고 인내를 제공해 주었습니다.

참여하고 싶으시면 Kubernetes Slack의 #release-management 채널에 참여하시거나 저장소를 확인해 주세요.

0 조회
Back to Blog

관련 글

더 보기 »

Kubernetes 아키텍처 배우기: 다른 방식으로

제 브이로그에 오신 것을 환영합니다! 저는 DevOps 여정을 계속하고 있으며, 이것이 첫 번째 브이로그입니다. 앞으로 나아가기 위한 유일한 전제 조건은 Docker에 대한 기본 지식입니다. Do...

대규모 Terraform + 고급 개념

markdown !Aisalkyn Aidarovahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.c...