즉, 기본값이 "대체"되는 게 아니라 "앞에 끼워 넣어지는" 것이다. Docker Hub가 최종 백엔드라는 사실은 변하지 않는다. 이것이 한국·중국처럼 Docker Hub 접속이 느리거나 불안정한 지역에서 많이 쓰이는 패턴이다.
3) Podman — 진짜로 기본 레지스트리를 바꿀 수 있다
반면 Podman·Buildah·CRI-O 계열은 /etc/containers/registries.conf로 완전히 자유롭게 구성할 수 있다.
# /etc/containers/registries.conf
# 짧은 이름(예: nginx)을 찾을 레지스트리 목록 — 순서대로 탐색
unqualified-search-registries = [
"registry.mycompany.internal",
"quay.io",
"docker.io"
]
# short-name 해석 모드
# "enforcing" 이면 애매할 때 사용자에게 선택을 강제한다
short-name-mode = "enforcing"
# docker.io 에 미러 붙이기
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "mirror.mycompany.internal:5000"
이렇게 설정한 뒤 podman pull nginx를 실행하면, registry.mycompany.internal부터 차례로 뒤져본다. Docker보다 훨씬 유연한 것이다. 이 차이가 RHEL·OpenShift 생태계가 Docker 대신 Podman을 기본 채택한 여러 이유 중 하나이기도 하다.
⚠️ 짧은 이름이 부르는 보안 위협 — Typosquatting
기본 레지스트리를 바꿀 수 있다는 건 편리하지만, 반대로 함정이기도 하다. unqualified-search-registries에 여러 레지스트리를 등록해두면, 어느 레지스트리에서 이미지가 왔는지 애매해진다.
예를 들어 탐색 순서가 ["registry1.com", "registry2.com"]일 때, 공격자가 registry1에 nginx라는 이름의 악성 이미지를 먼저 올려두면, 진짜 nginx가 registry2에 있더라도 registry1의 악성 이미지가 먼저 받아진다. 이것이 짧은 이름 스쿼팅(short-name squatting) 공격이다.
방어 원칙 3가지
FQIN을 쓰자: 프로덕션에서는 항상 docker.io/library/nginx:1.27.3 처럼 레지스트리·네임스페이스·태그를 모두 명시
Digest 고정: 더 엄격하게는 nginx@sha256:72297... 형태의 해시 고정. 동일 이미지 보장
Short-name-mode = "enforcing" (Podman 한정): 애매한 짧은 이름은 사용자에게 확인받도록 설정
✅ 정리
docker pull nginx라는 평범한 한 줄은 사실, 레지스트리 → 네임스페이스 → 태그 세 번의 자동 보정을 거쳐 docker.io/library/nginx:latest로 확장되는 결과물이다. 이 규칙은 Docker Hub라는 특정 레지스트리의 관용이지, 컨테이너 세계 공통의 문법이 아니다.
핵심을 한 줄로 요약하면 다음과 같다.
순정 Docker Engine에서는 기본 레지스트리를 바꿀 수 없다 — registry-mirrors로 앞에 캐시만 끼워 넣을 수 있을 뿐이다.
Podman 계열에서는 unqualified-search-registries로 완전히 자유롭게 구성할 수 있다.
편의성의 대가는 애매함이다 — 프로덕션에서는 반드시 FQIN 또는 digest 고정을 습관화하자.
다음 단계로 관심이 있다면, Docker Hub의 pull rate limit 회피 전략, Harbor·ECR 같은 사설 레지스트리 구축, Sigstore 기반 이미지 서명 검증(cosign), CI/CD 파이프라인의 digest pinning 자동화 순으로 학습해 나가시면 좋겠다.