Docker 컨테이너 이름 충돌 오류란?
최근 도커(Docker) 활용법에 관한 흥미로운 튜토리얼을 여러 편 소개했습니다. Docker는 LXC 기술을 깔끔하게 포장한 도구로, 운영체제(OS) 수준 가상화가 제공하는 강력한 기능을 개발자, 엔지니어, 시스템 관리자 누구나 부담 없이 누릴 수 있게 해줍니다. 하지만 편리한 만큼 골치 아픈 문제도 따라옵니다.
오늘 살펴볼 두 가지 문제는 이름이 지정된(named) 컨테이너를 시작하거나 기존 컨테이너를 삭제하려고 할 때 발생합니다. 화면에는 대략 다음과 같은 메시지가 출력됩니다.
- "Conflict. The name W is already in use by container XYZ..." (충돌: 해당 이름은 이미 다른 컨테이너가 사용 중입니다)
- "Conflict, cannot remove the default name of the container..." (충돌: 컨테이너의 기본 이름을 제거할 수 없습니다)
그럼 이 문제를 어떻게 해결해야 하는지 하나씩 짚어보겠습니다.
문제 상황 1: 컨테이너 시작 불가
docker run -d -ti -p 22 -p 80 --name <name> <repo:tag>
FATA[0000] Error response from daemon: Conflict. The name "XYZ" is already in use by container hexacode. You have to delete (or rename) that container to be able to reuse that name.
컨테이너를 시작하려는데 이름이 이미 사용 중이라는 오류가 발생합니다. 그런데 docker ps 명령으로 확인해 보면 해당 컨테이너가 목록에 보이지 않습니다. 게다가 문제가 되는 컨테이너를 종료하거나 삭제하려고 하면 또 다른 오류를 만나게 됩니다.
문제 상황 2: 컨테이너 삭제 불가
docker rm --link <name>
Error response from daemon: Conflict, cannot remove the default name of the container
FATA[0000] Error: failed to remove one or more containers
시작도 안 되고 삭제도 안 되니 마치 막다른 길처럼 느껴집니다. 과연 원인은 무엇일까요?
원인 분석
핵심 원인은 과거에 이름을 지정해 생성한 컨테이너를 실행해 둔 상태에서, 호스트 시스템이 어떤 이유로든 재부팅되었고 컨테이너를 정상적으로 종료하지 않았다는 점입니다. 재부팅 후 남겨진 잔여 파일(leftover files) 때문에 시스템은 기존 컨테이너가 아직 살아 있다고 판단하며, 결과적으로 같은 이름으로 새 컨테이너를 생성하지 못하도록 막는 것입니다.
해결 방법
문제를 해결하는 방법은 크게 두 가지입니다. 먼저 안전하고 권장되는 방법부터 살펴보겠습니다.
방법 1: docker ps -a로 잔여 컨테이너 정리
docker ps만 입력하면 현재 실행 중인 컨테이너만 표시되므로 아무것도 보이지 않습니다. 하지만 -a 플래그를 함께 사용하면 지금까지 생성된 모든 컨테이너 기록을 확인할 수 있습니다.
docker ps -a
비정상적으로 종료된 컨테이너는 상태 코드(status code)가 0이 아닌 값으로 표시됩니다. 컨테이너 이름을 기준으로 대상을 찾은 뒤, 실제 16진수(hexadecimal) ID를 이용해 삭제하면 됩니다.
docker rm 85c2981e63f6 26ea04f41ab3
방법 2: /var/lib/docker/containers 디렉터리 수동 정리
두 번째 방법은 /var 경로 아래에 남아 있는 파일을 직접 삭제하는 것입니다. 잔여 파일은 /var/lib/docker/containers/ 디렉터리에서 찾을 수 있습니다. 각 컨테이너마다 아주 긴 해시(hash) 식별자로 된 디렉터리가 존재하며, 그 안에는 설정 정보가 담긴 JSON 파일들이 들어 있습니다.
원하는 컨테이너 이름과 일치하는 문자열을 검색하면 해당 컨테이너의 설정 파일이 저장된 디렉터리를 찾을 수 있습니다. 예를 들어 grep을 활용하면 됩니다.
grep -l "컨테이너이름" /var/lib/docker/containers/*/config.v2.json
이름 검색에 매칭되는 부모 디렉터리를 삭제한 뒤 Docker 서비스를 재시작합니다. 이후에는 같은 이름을 다시 사용할 수 있습니다. KVM과 libvirt의 잔여 파일로 인한 문제와 유사한 사례라고 볼 수 있습니다.
systemctl restart docker
이제 다시 정상적으로 컨테이너를 생성하고 실행할 수 있을 것입니다!
마무리
서비스가 비정상 종료, 재부팅 같은 상황을 얼마나 견고하게 처리하는지와 관련된 문제는 특히 성가십니다. 잔여 파일 하나 때문에 이런 애로가 생기는 것은 바람직하지 않으며, 서비스는 이런 상황에서도 우아하게 복구되어야 마땅합니다. 하지만 컨테이너 기술은 아직 역사가 짧은 만큼, 이런 종류의 문제는 어느 정도 감수해야 하는 현실입니다.
이번 글이 갑작스러운 재부팅 이후 이름 있는 컨테이너 생성과 잔여 파일 삭제 과정에서 겪는 혼란을 해소하는 데 도움이 되었기를 바랍니다. 덕분에 Docker 사용 경험이 한결 쾌적해졌을 것이고, 백그라운드에서 어떤 일이 일어나는지도 조금 더 잘 이해하게 되었을 겁니다. 즐거운 컨테이너 라이프 되세요!