TL;DR
- 컨테이너화된 애플리케이션은 리눅스에서 네이티브 프로세스로 실행되며, 컨테이너 이미지에 리눅스 배포판이 반드시 필요한 것은 아님.
servertje라는 간단한 Go HTTP 서버를 정적 리눅스 바이너리로 컴파일하고, 바이너리 하나만 포함하는FROM scratch이미지로 구성함.- 이미지 파일 시스템에는
/servertje하나만 있으며, 실행 중인 컨테이너의 서버도 호스트에서 일반 리눅스 프로세스로 확인 가능함. - 컨테이너 이미지는 소프트웨어와 의존성을 패키징하는 방식이며, 프로세스 격리는 리눅스 커널 기능의 조합으로 이뤄짐.
- 많은 이미지가 리눅스 배포판을 포함하는 이유는 동적 링커, 시간대 정보, 루트 인증 기관 인증서 등 애플리케이션 의존 파일을 제공하기 때문임.
최소 컨테이너 이미지
- 모든 방문자에게 “Hello world”를 반환하고 8080 포트에서 HTTP 요청을 받는 작은 Go 프로그램을 작성함.
go mod init servertje로 모듈을 초기화한 뒤GOOS=linux CGO_ENABLED=0 go build -o servertje .명령으로 리눅스 바이너리servertje를 생성함. 이름은 네덜란드어로 “작은 서버”라는 뜻임.FROM scratch를 기반으로 한 Dockerfile에서servertje만/servertje에 실행 권한과 함께 복사하고, 이를 진입점으로 지정함.docker build . -t dockerized-servertje로 이미지를 빌드하고docker run --rm -p 8080:8080 dockerized-servertje로 HTTP 포트를 열어 실행함.- 실행 후
curl localhost:8080을 호출하면 “Hello world” 응답을 받으며, 브라우저에서 http://localhost:8080에 접속해 확인할 수도 있음.
이미지와 실행 중인 컨테이너 살펴보기
- 생성한 컨테이너 이미지의 파일 시스템에는
/servertje라는 파일 하나만 포함됨. 이미지를 내보내 레이어 내용을 확인하거나dive같은 도구를 사용해 검증 가능함. - 따라서 작은 HTTP 서버와 함께 리눅스 배포판을 이미지에 넣지 않음.
- 컨테이너 실행 중 호스트에서
ps -C servertje -o pid,user,cmd를 실행하면/servertje와 해당 프로세스 식별자(PID)가 표시됨. - 단, 컨테이너가 리눅스 가상 머신 안에서 실행 중이라면 해당 명령을 호스트가 아니라 가상 머신 안에서 실행해야 함.
이것이 의미하는 바
- 컨테이너 이미지는 소프트웨어와 그 의존성을 함께 패키징하는 방식임. 의존성이 없는 바이너리라면 바이너리만 패키징해도 됨.
- 컨테이너 안에서 명령을 실행하면 컨테이너화된 프로세스가 실행됨. 가상 머신 전체가 작동하는 것처럼 보일 정도로 격리되지만, 실제 격리는 리눅스 커널 기능의 조합으로 이뤄짐.
- 격리 기능은 향후 별도 글에서 다룰 예정이며, 자세한 내용은
runc의 컨테이너 명세에서 확인 가능함.
덧붙임: 컨테이너 이미지에 리눅스 배포판이 자주 포함되는 이유
- 많은 애플리케이션이 리눅스 배포판에 흔히 포함되는 파일에 의존하므로, 배포판을 이미지에 넣는 것이 편리함.
- 필요한 파일에는 동적 링커, 시간대 정보, 루트 인증 기관 인증서 등이 포함될 수 있음.
servertje같은 간단한 Go 프로그램은 이런 파일 없이도 실행되지만, 일반적인 애플리케이션에는FROM scratch이미지보다 더 많은 구성 요소가 필요할 수 있음.
컨테이너와 운영체제
- 실용적인 관점에서 컨테이너는 리눅스 기반 기술임. 리눅스를 사용하지 않는 환경에서는 선택한 컨테이너 도구, 대개 Docker Desktop이 백그라운드에서 리눅스 가상 머신을 시작하고 그 안에서 컨테이너를 실행함.
- 윈도 컨테이너도 존재하지만, 실제 사용하는 사례는 들어본 적이 없음.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요