- bit-for-bit 재현성이란 동일한 소스로 빌드하면 언제, 어디서, 누가 빌드하든 바이트 수준까지 완전히 동일한 결과물이 나오는 것을 의미
- 빌드 환경에 따라 미세하게 달라지는 타임스탬프, 캐시, 메타데이터 같은 비결정론적 요소를 모두 제거해야 달성 가능
- Docker 이미지를 직접 빌드해서 공식 배포 이미지와 다이제스트(해시)가 동일한지 비교하면, 배포된 이미지가 변조되지 않았음을 누구나 독립적으로 검증 가능 : 공급망 보안 측면에서 중요
- Arch Linux의 Docker 이미지가 이제 bit-for-bit 재현 가능한 형태로 제공되며, 몇 달 전 WSL 이미지에서 달성한 같은 이정표를 Docker 쪽으로 확장함
- 이 이미지는 전용
repro태그로 배포되며, 재현성을 보장하려면 pacman 키를 이미지에서 제거해야 해서pacman을 바로 사용할 수 없음- 적절한 해결책이 마련될 때까지는 이 제약 때문에 별도 태그로 우선 제공됨
- 컨테이너 안에서 패키지 설치나 업데이트를 하려면 먼저
pacman-key --init && pacman-key --populate archlinux를 실행해 keyring 재생성이 필요함- 처음 실행 시 대화형으로 진행하거나, 이 이미지를 베이스로 쓰는 Dockerfile의
RUN구문에서 실행할 수 있음 - Distrobox에서는
distrobox create -n arch-repro -i docker.io/archlinux/archlinux:repro --pre-init-hooks "pacman-key --init && pacman-key --populate archlinux"처럼 pre-init hook으로 처리 가능함
- 처음 실행 시 대화형으로 진행하거나, 이 이미지를 베이스로 쓰는 Dockerfile의
- 이미지의 bit-for-bit 재현성은 빌드 간 digest 일치로 확인되며,
podman inspect --format '{{.Digest}}' <image>와diffoci비교로 검증함 - 이 Docker 이미지를 재현하는 방법은
REPRO.md에서 확인할 수 있음
구현과 조정 사항
- Docker 이미지용 base rootFS를 결정론적으로 빌드하는 작업이 가장 큰 과제였고, rootFS 빌드 시스템을 공유하는 WSL 이미지와 같은 과정을 재사용함
- 관련 WSL 커밋은 여기에서 확인 가능함
- Docker 전용 조정 가운데 하나로
SOURCE_DATE_EPOCH를 설정하고, Dockerfile의org.opencontainers.image.createdLABEL도 이를 따르도록 맞춤 - 빌드된 이미지에서 비결정성을 유발하는
ldconfig보조 캐시 파일var/cache/ldconfig/aux-cache를 Dockerfile 단계에서 제거함 docker build또는podman build때--source-date-epoch=$SOURCE_DATE_EPOCH와--rewrite-timestamp옵션을 사용해 타임스탬프 정규화를 적용함- 예시로
etc/,etc/ld.so.cache,etc/os-release,sys/,var/cache/,var/cache/ldconfig/,proc/,dev/의 시간이 서로 다르게 찍히던 문제가 제시됨
- 예시로
- 관련 변경 사항 전체는
archlinux-docker저장소의 merge request diff에서 더 자세히 확인 가능함 - 이후 단계로는 Docker 이미지와 WSL 이미지, 그리고 앞으로의 재현 가능한 이미지들을 대상으로 rebuilder를 서버에 구축해 주기적 자동 재빌드, 재현성 검증, 빌드 로그와 결과 공개까지 고려하고 있음