Docker는 환경 일관성 문제를 이미지로 해결한다

“내 컴퓨터에서는 됐는데요.”

개발하다 보면 한 번쯤 이 말을 하거나 듣게 된다. 로컬에서 잘 돌아가던 코드가 서버에 올리면 안 되는 상황. JDK 버전이 다르거나, 라이브러리 버전이 조금 달랐거나, OS가 달라서 경로 처리 방식이 다르거나. 원인은 항상 환경 차이에 있었다.

Docker는 이 문제를 이미지로 해결한다. 애플리케이션 코드와 실행에 필요한 모든 것(런타임, 라이브러리, 설정)을 이미지 하나에 담아버린다. 이 이미지를 실행하면 어느 환경에서든 동일한 결과가 나온다.

이미지와 컨테이너

이미지는 레이어 구조로 쌓인다. 베이스 OS 레이어 위에 런타임을 올리고, 그 위에 애플리케이션을 올리는 식이다. 각 레이어는 캐시되기 때문에 변경된 부분만 다시 빌드된다. 여러 이미지가 공통 레이어를 공유하면 디스크 낭비도 줄어든다.

컨테이너는 이미지를 실행한 인스턴스다. 호스트 OS의 커널을 공유하기 때문에 VM보다 훨씬 가볍고 빠르게 뜬다.

배포 파이프라인의 변화

Docker 이전에는 배포 환경마다 일일이 설정을 맞춰야 했다. Docker 이후로는 이미지를 빌드하고 레지스트리에 올리면 끝이다. 어느 서버든 같은 이미지를 pull해서 실행하면 된다. CI/CD 파이프라인과 연결하면 코드 푸시부터 배포까지 자동화가 자연스럽게 이어진다.

자원 효율성

VM은 게스트 OS 전체를 띄우기 때문에 무겁다. 컨테이너는 프로세스 격리 수준이라 시작 시간이 빠르고 메모리도 적게 쓴다. 마이크로서비스 아키텍처처럼 여러 서비스를 독립적으로 운영해야 할 때 컨테이너의 강점이 잘 드러난다.

한계도 있다

컨테이너가 많아지면 관리가 복잡해진다. 여러 컨테이너의 배포, 스케일링, 네트워크 설정을 손으로 관리하기는 어렵다. 그래서 Kubernetes 같은 오케스트레이션 도구가 등장했고, 현재는 Docker + Kubernetes 조합이 사실상 표준처럼 쓰인다.

“한 번 만들고 어디서든 실행”이라는 약속이 실제로 지켜지는 도구는 흔치 않다. Docker는 그 약속을 꽤 잘 지키고 있다.

연결 (이유)

출처(참고문헌)