← 아티클 목록

Docker latest 태그 문제 — 안전한 이미지 태그 전략

2027-10-11#docker#배포#운영

docker pull myapp:latest로 배포를 굴리다 보면, 어제 잘 돌던 서비스가 오늘 재배포에서 갑자기 깨지는 일이 생깁니다. latest는 "최신"이라는 뜻의 고정된 라벨일 뿐, 같은 태그가 시점마다 다른 이미지를 가리킬 수 있기 때문입니다. 운영에서 latest를 쓰면 "지금 무슨 버전이 돌고 있는지"를 아무도 확신할 수 없게 됩니다.

latest가 일으키는 실제 문제

문제왜 생기나
노드마다 다른 버전풀 시점이 달라 같은 latest가 서로 다른 이미지
롤백 불가"이전 latest"라는 건 존재하지 않음
캐시 혼란imagePullPolicy 기본 동작이 태그에 따라 달라짐
재현 불가빌드 로그에 latest만 남아 사후 추적 어려움

특히 쿠버네티스에서 태그가 latestimagePullPolicy가 자동으로 Always가 되고, 그 외 태그면 IfNotPresent가 기본이라 동작 자체가 달라집니다.

1단계 — 불변(immutable) 태그 쓰기

한 번 푸시한 태그는 다시 덮어쓰지 않는 것이 원칙입니다. 커밋 SHA나 CI 빌드 번호를 태그로 박습니다.

Docker
docker build -t myapp:1.4.2 -t myapp:$(git rev-parse --short HEAD) .
docker push myapp:1.4.2
docker push myapp:$(git rev-parse --short HEAD)

myapp:a1b2c3d처럼 커밋에 1:1로 묶이면, 장애 때 "어느 커밋이 돌고 있었나"가 즉시 드러납니다.

2단계 — 시맨틱 버전 + 이동 태그 분리

사람이 읽을 버전(1.4.2)과 편의용 이동 태그(1.4, 1)를 함께 둡니다.

태그가리키는 것용도
1.4.2정확히 그 빌드 (불변)배포·롤백 기준
1.41.4.x 중 최신패치 자동 수용
11.x 중 최신메이저 호환

운영 배포에는 항상 1.4.2처럼 완전히 고정된 태그만 지정합니다.

3단계 — 정말 고정하려면 다이제스트

태그조차 덮어쓰일 수 있는 환경이라면, 변하지 않는 콘텐츠 해시(다이제스트)로 핀합니다.

로컬 터미널
docker pull myapp@sha256:9f86d08...e3b0c44
YAML
# kubernetes
image: myapp@sha256:9f86d08...e3b0c44

다이제스트는 이미지 내용이 1바이트만 달라져도 바뀌므로, "정확히 이 이미지"를 100% 보장합니다.

확인·검증

로컬 터미널
docker images --digests myapp      # 태그별 다이제스트 비교
docker inspect myapp:1.4.2 --format '{{.RepoDigests}}'

같은 태그인데 노드마다 다이제스트가 다르면, 이미 latest류의 가변 태그 문제가 발생한 것입니다.

적용 체크리스트

로컬 터미널
# 운영 매니페스트에 latest가 남아있는지 점검
grep -rn ":latest" k8s/ docker-compose*.yml

docker images --digests           # 태그=다이제스트 1:1 확인

latest를 운영에서 추방하고 불변 태그로 배포하면, 롤백은 "이전 태그로 되돌리기" 한 줄이면 끝납니다.


태그를 일부러 덮어써 배포 불일치를 만들어 보고 다이제스트로 고정하는 실습은 도커 트랙에서 무료로 해볼 수 있습니다.