콘텐츠로 이동

Docker (컨테이너)

"내 컴퓨터에서는 되는데요"라는 말, 어디서나 들어봤을 거예요. 코드가 돌아가는 환경(운영체제 버전, 라이브러리, 설정)이 조금만 달라져도 문제가 생기죠. Docker는 애플리케이션과 그 실행 환경을 이미지 한 장으로 묶어서, 어느 머신에 가져가도 똑같이 돌아가게 해주는 컨테이너 기술이에요.

우리 서비스도 전부 이 컨테이너 이미지로 포장되어서 Kubernetes 클러스터에 올라가요. 그래서 Docker의 동작 방식을 이해하면 뒤의 오케스트레이션 얘기가 훨씬 쉬워져요.

핵심 개념

이미지와 컨테이너. 이미지는 "실행 가능한 패키지"이고, 컨테이너는 그 이미지를 실제로 실행한 프로세스예요. 이미지는 읽기 전용이고, 컨테이너는 돌아가는 동안 위에 얇은 쓰기 레이어를 얹죠. 여러 컨테이너가 같은 이미지를 공유해서 써도 서로 간섭하지 않아요.

레이어(Layer). 이미지는 여러 겹의 레이어로 쌓여요. FROM base부터 시작해 패키지 설치, 코드 복사 같은 명령이 레이어 하나씩을 만듭니다. 재사용 가능한 레이어는 캐시되니까, 빌드가 빨라져요.

Dockerfile. 어떤 이미지를 만들지 선언하는 텍스트 파일이에요. 빌드 순서와 들어갈 내용을 씁니다.

FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
CMD ["npm", "start"]

컨테이너 격리. 컨테이너는 호스트 커널을 공유하면서도 네임스페이스(namespaces)로 프로세스·파일시스템·네트워크를 분리하고, cgroups로 CPU·메모리 사용량을 제한해요. 그래서 가상머신보다 가볍고 빠르게 여러 개를 띄울 수 있어요.

레지스트리. 이미지를 저장하고 내려받는 저장소예요. 공개 저장소가 Docker Hub이고, 사내 이미지는 Harbor 같은 사설 레지스트리에 두죠.

사용 사례 / 실제 적용

개발자 환경을 맞추는 일이 대표적이에요. 로컬에서도 운영과 같은 이미지로 띄우면 "내 컴퓨터에서는 되는데"라는 불일치가 줄어요. 여기서는 그 위에 한 걸음 더 나가, 이미지를 빌드·push하면 뒤이어 설명할 Kubernetes가 그 이미지를 받아 실제 서비스로 띄웁니다.

이미지를 만들 때 신경 쓸 지점이 몇 가지 있어요. 믿을 수 있는 베이스 이미지를 고르고, 불필요한 파일이 들어가지 않게 .dockerignore를 두며, 보안을 위해 루트가 아닌 사용자로 실행하도록 하는 거죠. 또 이미지의 버전을 명확히 태그로 남겨야 "이 배포가 어떤 이미지였는지" 되짚을 수 있어요.

하위 챕터

더 알아보기