목차
[보안] Trivy vs Clair: 우리 팀에 맞는 컨테이너 이미지 보안 스캐너는?
컨테이너 이미지 보안 이야기를 하면 결국 한 번은 취약점 스캐너(vulnerability scanner, 알려진 보안 취약점을 찾아주는 도구) 선택 문제로 돌아오게 됩니다. 특히 팀에서 CI/CD를 굴리기 시작하면, 이미지 빌드까지는 잘 되는데 배포 직전에 “이 이미지를 그냥 올려도 되나?” 하는 순간이 꼭 오거든요. 저도 홈랩하고 회사 환경에서 이것저것 붙여보면서 삽질을 꽤 했습니다. 처음엔 스캐너면 다 비슷한 거 아닌가 싶었는데, 실제로 써보니까 Trivy와 Clair는 접근 방식이 꽤 다르더라고요. 이번 글에서는 컨테이너 이미지 보안 관점에서 두 도구를 비교하고, 어떤 팀에 어떤 선택이 맞는지 경험 기반으로 정리해보겠습니다.

Trivy와 Clair가 개발 파이프라인과 레지스트리 사이에서 어디에 붙는지 한눈에 보여주는 개요 이미지입니다.
1. 왜 컨테이너 이미지 보안이 먼저냐
쉽게 말해 컨테이너 이미지는 애플리케이션 실행에 필요한 파일 묶음입니다. 여기 안에는 애플리케이션 코드만 들어있는 게 아니라, 베이스 이미지(base image, 실행 기반 운영체제 레이어), 패키지 관리자 설치물, 언어별 라이브러리까지 같이 들어가죠. 그러다 보니 한 줄의 애플리케이션 코드보다 이미지 안에 포함된 오래된 패키지가 더 큰 리스크인 경우도 많습니다.
제가 직접 해보니 현업에서 자주 놓치는 포인트는 딱 두 가지였습니다. 첫째, 개발팀은 애플리케이션 dependency(디펜던시, 의존 패키지)는 보는데 OS 패키지는 잘 안 봅니다. 둘째, 운영팀은 이미지 태그만 보고 안심하는 경우가 있는데, 같은 애플리케이션이어도 베이스 이미지가 달라지면 결과가 완전히 달라집니다. 그래서 컨테이너 이미지 보안은 배포 뒤가 아니라 빌드 직후부터 챙겨야 하거든요.
2. Trivy와 Clair, 이 두 스캐너는 뭐가 다를까
Trivy는 실행이 빠르고 진입장벽이 낮은 올인원 성격의 스캐너에 가깝습니다. 공식 문서 기준으로 컨테이너 이미지뿐 아니라 파일시스템, Git 리포지토리, Kubernetes, SBOM(Software Bill of Materials, 소프트웨어 구성 명세)까지 다뤄요. 취약점뿐 아니라 misconfiguration(미스컨피규레이션, 잘못된 보안 설정)과 secret(시크릿, 노출된 비밀정보) 검사도 같이 가져갈 수 있어서 DevSecOps 도입 초반에 특히 편합니다.
Clair는 조금 결이 다릅니다. 컨테이너 취약점 정적 분석(static analysis, 실행 없이 구조와 패키지를 분석하는 방식)에 집중한 서비스형 구조에 더 가깝습니다. 공식 문서와 프로젝트 설명을 보면 API 기반으로 이미지를 인덱싱(indexing, 패키지 정보를 수집해 저장)하고, 이후 알려진 취약점과 매칭하는 흐름이 핵심입니다. 그래서 단일 CLI를 바로 실행하는 느낌보다는, 레지스트리나 내부 플랫폼에 연결해서 쓰는 그림이 더 자연스럽습니다.
여기서 중요한 포인트! 둘 중 누가 절대적으로 더 좋다고 보기는 어렵습니다. 우리 팀의 운영 방식이 더 중요합니다.
3. Trivy vs Clair: 우리 팀에 중요한 비교 포인트
| 비교 항목 | Trivy | Clair |
|---|---|---|
| 첫 도입 난이도 | 낮음. CLI 중심으로 바로 시작 가능 | 상대적으로 높음. 서비스와 설정 이해 필요 |
| 운영 형태 | 로컬 CLI, CI, 서버 모드 모두 가능 | API 기반 서비스 운용에 더 적합 |
| 주요 강점 | 취약점, misconfiguration, secret, SBOM 범위가 넓음 | 컨테이너 이미지 취약점 분석 파이프라인에 집중 |
| 데이터베이스 운영 | 자체 DB를 받아 캐시하며 사용 | PostgreSQL 기반 영속 저장 구조 사용 |
| 잘 맞는 팀 | 작은 팀, 플랫폼 초기 팀, 빠른 CI 통합이 필요한 팀 | 내부 보안 플랫폼/레지스트리 통합을 운영하는 팀 |
| 학습 곡선 | 완만함 | 구조 이해가 필요해서 가파른 편 |
실제로 써보니까 Trivy는 시작이 쉽고 범용적이었습니다. 반면 Clair는 아키텍처 안에 넣었을 때 힘을 발휘하더라고요. 그래서 팀의 질문도 달라야 합니다. “무엇이 더 강력한가”보다 “우리는 CLI 중심으로 갈 건가, 서비스 중심으로 갈 건가”가 먼저입니다.
4. Trivy로 바로 시작하는 실전 구현
처음 도입하는 팀이라면 저는 거의 무조건 Trivy부터 붙여봅니다. 이유가 단순합니다. 빨리 결과가 나오고, 개발팀이 거부감 없이 받아들이기 쉽거든요.
- 스캔 대상 이미지를 하나 정합니다. 예시는
nginx:latest처럼 공개 이미지로 해도 됩니다. - 로컬에서 한 번 돌려보고 결과 형식을 익힙니다.
- 그다음 CI에 붙여서 High/Critical 기준으로 fail 시킵니다.
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/.cache/trivy:/root/.cache/ \
aquasec/trivy image nginx:latest
이 명령은 Docker 소켓을 마운트해서 로컬 이미지 또는 엔진에서 접근 가능한 이미지를 검사합니다. 처음엔 DB를 내려받는 시간이 조금 걸릴 수 있어요. 저도 처음엔 “왜 이렇게 느리지?” 했었는데, 캐시가 잡히고 나면 훨씬 빨라지더라고요.
trivy image --severity HIGH,CRITICAL --exit-code 1 nginx:latest
이건 CI에 넣기 좋은 형태입니다. 지정한 심각도(severity, 위험도) 이상이 나오면 종료 코드를 1로 반환하니까 파이프라인에서 바로 실패 처리할 수 있어요. 단순하지만 실무에서는 이게 제일 중요합니다. 개발팀이 결과를 보는 것보다, 기준 이상이면 못 지나가게 막는 것이 더 효과가 크거든요.
trivy image --format spdx-json --output sbom.json nginx:latest
SBOM 생성도 됩니다. 여기서 DevSecOps 흐름이 한 단계 올라갑니다. 단순히 취약점 숫자만 보는 게 아니라, 이미지 안에 무엇이 들어있는지 자산 관리를 같이 할 수 있거든요.

Trivy를 CI에 붙여서 이미지 스캔이 자동으로 돌아가고, 기준 이상 취약점에서 빌드가 멈추는 흐름을 설명하는 이미지입니다.
Trivy를 추천하는 경우
- 빠르게 시작해야 하는 팀
- 보안 전담 인력이 많지 않은 팀
- 취약점 스캔 외에 misconfiguration, secret 검사까지 같이 보고 싶은 팀
- 개발자 로컬 환경과 CI에서 같은 도구를 쓰고 싶은 팀
5. Clair는 언제 빛나나: 서비스형 운영이 필요할 때
Clair는 “개발자가 CLI 하나 실행하는 도구”라기보다, 내부 서비스처럼 다루는 쪽이 더 맞습니다. 공식 문서 기준으로 Clair는 여러 모드(indexer, matcher, notifier, combo mode)를 가지며, PostgreSQL을 사용해요. 즉, 단순 바이너리 하나보다 스캐닝 서비스를 운영한다는 관점이 필요합니다.
저도 처음엔 이게 뭔가 싶었는데, 구조를 이해하고 나니 왜 이런 설계를 했는지 보이더라고요. 이미지 메타데이터를 인덱싱하고, 취약점 데이터와 매칭하는 과정을 API 기반으로 분리하면 레지스트리나 사내 플랫폼에 붙이기 좋습니다. 여러 팀이 공통 서비스로 재사용하기도 좋고요.
- PostgreSQL을 준비합니다.
- Clair 설정 파일을 작성합니다.
- combo mode로 먼저 띄워봅니다.
clairctl로 이미지를 제출해서 결과를 확인합니다.
http_listen_addr: :6060
introspection_addr: :8089
log_level: info
indexer:
connstring: host=clair-db port=5432 user=clair dbname=clair sslmode=disable
migrations: true
matcher:
connstring: host=clair-db port=5432 user=clair dbname=clair sslmode=disable
migrations: true
notifier:
connstring: host=clair-db port=5432 user=clair dbname=clair sslmode=disable
migrations: true
이 예시는 개념 설명용 최소 구성입니다. 실서비스에서는 인증, 네트워크, 스토리지, 운영 정책을 따로 잡아야 합니다. Clair 쪽은 특히 “일단 설치”보다 “운영 구조를 어떻게 가져갈지”를 먼저 생각해야 해요.
CLAIR_MODE=combo
CLAIR_CONF=/etc/clair/config.yaml
clair -conf /etc/clair/config.yaml -mode combo
clairctl report --host http://localhost:6060 ubuntu:focal
Clair는 이렇게 API 서비스와 클라이언트 도구가 분리된 흐름을 이해하면 훨씬 덜 헷갈려요. 반대로 이 구조가 부담스럽다면, 억지로 Clair부터 시작할 필요는 없다고 봅니다.

Clair가 단순 CLI가 아니라 indexer, matcher, 데이터 저장소가 분리된 구조라는 점을 보여주는 아키텍처 이미지입니다.
6. ⚠️ 실제로 겪었던 주의사항과 트러블슈팅
첫 번째, 결과 숫자만 보고 놀라지 마세요. 취약점 스캐너는 패키지 소스와 배포판 메타데이터를 해석하는 방식에 따라 결과가 달라질 수 있습니다. 같은 이미지라도 스캐너마다 개수가 다르게 보일 수 있거든요. 저도 초반엔 “왜 A는 12개인데 B는 20개지?” 하면서 한참 봤습니다. 이건 도구가 틀렸다기보다 탐지 기준과 데이터 소스 차이를 봐야 하는 경우가 많습니다.
두 번째, 스캔 시점을 통일해야 합니다. 개발자 로컬, CI, 레지스트리, 운영 배포 후 스캔이 다 따로 놀면 팀이 금방 지쳐요. 제 경험상 가장 덜 싸우는 방식은 이렇습니다.
- 개발자 로컬: 빠른 사전 확인
- CI: 정책 강제
- 레지스트리 또는 플랫폼: 중앙 모니터링
세 번째, False Positive(오탐)와 False Negative(미탐)를 운영 규칙으로 다뤄야 합니다. 취약점 스캐너는 만능이 아니거든요. 패키지가 실제로 exploitable(익스플로이터블, 실제 공격 가능 상태)한지와는 또 다른 문제예요. 그래서 보안팀이나 플랫폼팀이 예외 처리 기준을 문서화해야 합니다.
네 번째, 베이스 이미지 갱신 주기를 같이 가져가야 합니다. 스캐너만 붙여놓고 이미지가 매달 그대로면 결국 경고판만 늘어나요. 알림은 쌓이는데 고쳐지진 않죠. 이거 진짜 많이 봤습니다 ㅎㅎ
7. 검증: 어떤 결과가 나오면 잘 붙은 걸까
스캐너 도입이 끝났다고 판단하는 기준은 단순 설치 여부가 아닙니다. 아래 체크리스트가 돌아가야 합니다.
- 이미지 빌드 직후 자동 스캔이 실행된다.
- High 또는 Critical 기준으로 실패 정책이 적용된다.
- 어떤 패키지가 문제인지 개발자가 바로 확인할 수 있다.
- 재빌드 후 취약점 감소 여부를 비교할 수 있다.
- 예외 처리 사유가 기록된다.
예를 들어 Trivy라면 결과 테이블에서 패키지명, 취약점 ID, 설치 버전, 수정 버전이 보여야 하고, Clair라면 제출한 이미지에 대해 보고서가 안정적으로 반환되어야 합니다. 여기까지 되면 컨테이너 이미지 보안 체계가 최소한의 자동화 단계에는 올라온 겁니다. 🎉

스캔 결과를 한 번에 파악할 수 있는 대시보드와 재빌드 후 취약점 수가 줄어드는 검증 장면을 보여주는 이미지입니다.
8. 그래서 우리 팀은 뭘 고르면 되나
제가 멘토링하듯 정리하면 이렇습니다.
- Trivy: 작은 팀, 스타트업, 플랫폼 초기 단계, 개발자 자율 사용이 중요한 팀에 잘 맞아요.
- Clair: 중앙 서비스형 스캔, 레지스트리 통합, 내부 보안 플랫폼 운영이 중요한 팀에 잘 맞습니다.
조금 더 현실적으로 말하면, 대부분의 팀은 Trivy로 시작해서 운영 성숙도가 올라가면 Clair 같은 서비스형 구성까지 검토하는 흐름이 자연스럽습니다. 물론 이미 레지스트리 중심 운영이 잘 잡혀 있고, 보안 서비스 운영 경험이 있다면 Clair도 충분히 좋은 선택이 될 수 있습니다.
| 팀 상황 | 추천 | 이유 |
|---|---|---|
| 개발팀이 직접 CLI를 돌려야 함 | Trivy | 배포 전 빠른 피드백이 쉬워요 |
| CI에서 바로 차단 정책이 필요함 | Trivy | 간단한 exit code 기반 통합이 쉬워요 |
| 사내 공통 스캔 서비스를 운영함 | Clair | API 기반 구조가 잘 맞아요 |
| 레지스트리와 강하게 결합한 운영을 원함 | Clair | 이미지 인덱싱/매칭 구조가 자연스러워요 |

팀 규모, 운영 방식, DevSecOps 성숙도에 따라 Trivy와 Clair 중 무엇을 고를지 빠르게 판단할 수 있게 정리한 요약 이미지입니다.
9. 마무리: 도구보다 운영 습관이 더 오래 갑니다
정리해보면, Trivy vs Clair 비교는 기능표 한 장으로 끝나는 문제가 아니었습니다. 직접 써보니까 결국 승부는 운영 방식에서 나더라고요. Trivy는 시작이 빠르고 범위가 넓어서 도입 속도가 좋았어요. Clair는 서비스형 구조를 이해하고 운영할 수 있을 때 더 의미가 있었습니다.
혹시 지금 팀에서 취약점 스캐너를 막 도입하려는 상황이라면, 저는 이렇게 권하고 싶습니다. 먼저 Trivy로 CI 차단 정책 하나를 확실히 세우세요. 그다음 SBOM과 예외 처리 기준을 정리하세요. 그리고 조직 규모가 커지면서 중앙 서비스가 필요해질 때 Clair 같은 구조를 검토하면 됩니다. 이 순서가 실제로 덜 아프고, 덜 헷갈립니다.
다음 글에서는 Trivy를 GitHub Actions 같은 CI에 붙여서 DevSecOps 파이프라인을 만드는 방법도 다뤄볼 예정입니다. 이전 글에서 다뤘던 이미지 경량화와 베이스 이미지 관리 전략을 같이 보면 더 연결이 잘 되실 겁니다. ✅