컨테이너 이미지를 취약점 스캐너로 돌려본 적이 있다면 누구나 한 번쯤 겪는 상황이 있습니다. 스캔 결과에 수천 건의 CVE가 쏟아지는데, 정작 애플리케이션 코드는 아무 문제가 없고 대부분이 베이스 이미지의 OS 패키지에서 나온 것들입니다. 베이스 이미지가 새로 릴리스되기를 기다리거나, Dockerfile을 열어 apt-get upgrade를 끼워 넣고 전체 리빌드·재테스트를 돌리는 것이 지금까지의 대응이었습니다.
Copa(Copacetic)는 이 문제를 다르게 풉니다. 이미지를 리빌드하지 않고, 취약한 OS 패키지만 업데이트한 레이어 하나를 기존 이미지 위에 얹습니다. Microsoft가 시작해 현재 CNCF 샌드박스 프로젝트로 관리되고 있으며, 내부적으로 BuildKit을 사용합니다.
이 글에서는 Copa를 소개만 하고 끝내는 대신, Node 18 이미지(Ubuntu 22.04 기반)를 대상으로 실제 패치를 돌려 전/후 CVE 수치를 비교한 결과를 공유합니다.
Copa의 워크플로는 단순합니다.
핵심은 Dockerfile도, 소스 코드도, CI 파이프라인 전체 리빌드도 필요 없다는 점입니다. 원본 이미지의 기존 레이어는 그대로 유지되고, 맨 위에 업데이트 레이어 하나만 추가됩니다.
| 항목 | 내용 |
|---|---|
| 대상 이미지 | cimg/node:18.20.4 (Node.js 18, Ubuntu 22.04 기반) |
| 스캐너 | Trivy (최신 이미지, --scanners vuln) |
| 패처 | Copa v0.14.2 |
| 빌드 백엔드 | moby/buildkit 컨테이너 (docker-container://buildkitd) |
실행한 명령은 다음이 전부입니다.
# 1) 베이스라인 스캔 (Copa 입력용 JSON 리포트)
trivy image --scanners vuln -f json -o node18-before.json cimg/node:18.20.4
# 2) BuildKit 데몬 기동
docker run -d --rm --privileged --name buildkitd \
--entrypoint buildkitd moby/buildkit:latest
# 3) Copa 패치 실행
copa patch -i cimg/node:18.20.4 -r node18-before.json \
-t 18.20.4-patched -a docker-container://buildkitd --timeout 30m
# 4) 패치된 이미지 재스캔
trivy image --scanners vuln -f json -o node18-after.json cimg/node:18.20.4-patched
Copa 실행은 약 1분 30초 만에 끝났고, 148개의 보안 업데이트가 설치됐습니다. Copa가 출력한 요약은 다음과 같습니다.
Patch Summary: 6772 total, 4067 patched, 2705 skipped
Patched image (linux/amd64): cimg/node:18.20.4-patched
Trivy 재스캔 결과도 이 숫자와 정확히 일치했습니다.
| 심각도 | 패치 전 | 패치 후 | 감소 |
|---|---|---|---|
| CRITICAL | 21 | 7 | -14 (-67%) |
| HIGH | 388 | 170 | -218 (-56%) |
| MEDIUM | 5,610 | 2,190 | -3,420 (-61%) |
| LOW | 753 | 338 | -415 (-55%) |
| 합계 | 6,772 | 2,705 | -4,067 (-60%) |
주목할 점은 감소량 4,067건이 우연이 아니라는 것입니다. 패치 전 리포트에서 FixedVersion(수정 버전)이 존재하는 CVE가 정확히 4,067건이었고, Copa는 그 전부를 패치했습니다. 즉:
배포판 저장소에 수정판이 올라와 있는 CVE는 100% 제거됐고, 남은 2,705건은 전부 아직 수정판이 출시되지 않은(no fixed version) CVE입니다.
이것이 Copa의 성격을 가장 잘 보여줍니다. Copa는 마법을 부리는 도구가 아니라, "패키지 매니저로 올릴 수 있는 것을 전부, 리빌드 없이, 빠르게" 올려 주는 도구입니다.
패치 레이어가 런타임을 깨뜨리지 않는지도 확인했습니다.
$ docker run --rm cimg/node:18.20.4-patched node --version
v18.20.4
애플리케이션 바이너리와 기존 레이어는 건드리지 않으므로, 태그 교체만으로 배포 파이프라인에 태울 수 있습니다.
실험에서 그대로 드러난, Copa 도입 전에 알아야 할 특성들입니다.
node_modules나 런타임 자체의 취약점은 여전히 애플리케이션 빌드 단계에서 관리해야 합니다.--ignore-unfixed 옵션으로 노이즈를 관리하는 것이 현실적입니다. 참고로 Copa는 패치 결과를 OpenVEX 형식으로 출력하는 기능(-f openvex -o report.vex)도 제공합니다.--compression gzip 같은 압축 옵션으로 상당 부분 줄일 수 있습니다.archive.ubuntu.com, security.ubuntu.com)에서 실제 패키지를 내려받습니다. 폐쇄망이라면 내부 미러가 필요합니다."이미지 CVE가 수천 건"이라는 스캔 결과 앞에서 할 수 있는 일이 리빌드뿐이라면 대응은 늘 느려집니다. 이번 실측에서 Copa는 리빌드 없이 1분 30초 만에 OS 패키지 CVE의 60%(CRITICAL은 67%)를 제거했고, 수정판이 존재하는 취약점 기준으로는 빠짐없이 전부 패치했습니다. 스캐너 리포트를 입력으로 받아 패키지 매니저가 할 수 있는 일을 자동화해 주는, 역할이 명확하고 예측 가능한 도구입니다. 이미지 취약점 대응 파이프라인에 넣을 도구를 찾고 있다면 한번 돌려볼 가치가 충분합니다.