도커 이미지와 컨테이너

JaeYeon·2025년 5월 5일
post-thumbnail

해당 포스팅은 개발자를 위한 쉬운 도커 를 수강하고 작성한 포스팅입니다.

이번 주차엔 도커의 이미지와 컨테이너의 개념, 그리고 이미지 레지스트리에 대해서 공부하였다.

도커이미지

도커의 이미지에 대해서 공부하기 전에 서버의 구성부터 이해해보자

서버를 구현하기 위해선 크게 하드웨어와 소프트웨어가 필요하고,

소프트웨어에서는 OS와 그를 위한 기본 시스템 파일이 추가적으로 필요하다. 즉 내가 아무리 혼자 구현해서 작동을 확인해도 다른 사람의 OS에서 내 파일을 돌리면 오류가 날 확률이 너무나도 크다는 것


도커는 이를 이미지라는 압축파일을 통해 해결한다.

우리가 서버를 도커없이 배포할때 생각해보자. 우선 우리가 만든 자바 파일을 jar 파일로 압축하고, 새로운 서버에 자바와 필요한 다양한 소프트웨어를 설치한 뒤에 jar파일을 실행한다.

이러한 작업들을 모두 하나의 이미지에 압축하여 이미지를 실행만 하면 내가 구현한 파일이 정상 실행되도록 도와주는게 이미지라는 개념인 것이다.

그럼 이미지만 가지고 이런게 될리가 없다. 단순히 생각해서 운영체제 위에 운영체제를 설치한다는 논제자체가 성립이 안된다. 그래서 우리가 저번주차에 공부한 컨테이너라는 가상화 기술과 함께 이용하는 것이다.

하나의 이미지를 create하면 해당 이미지를 위한 컨테이너가 생성된다. 즉 우리는 컨테이너 가상화 기술을 이용하여 해당 이미지를 독립적인 컨테이너 위에서 실행시킬 수 있는 것이다.

이미지와 컨테이너

해당 강의에서는 이미지와 컨테이너를 프로그램과 프로세스에 비유한다.

가장 공감되는 부분은 프로그램과 프로세스가 일대다 관계인 것처럼 이미지와 컨테이너도 일대다라는 점.

하나의 이미지를 여러 컨테이너에서 같이 실행 할 수 있다.

이런식으로 말이다.
여기까진 잘 이해가 됐지만 이 명령어를 보고,

80번 포트에서 작동하는 nginx가 3개나 켜졌는데 왜 충돌이 안나지?

라는 의문이 들었다. 이를 이해하기 위해서는 포트 바인딩에 대해서 이해해야한다.

docker run -d -p 8081:80 --name multinginx1 nginx

이게 우리가 일반적으로 도커를 이용하여 서버를 실행할때 사용하는 명령어이다. 즉, multinginx1이라는 하나의 컨테이너에서 실행중인 80번 포트와 현재 HOST OS의 8081포트를 연결해주어야 우리의 IP에서 접속이 가능해지는 것이다.

그러니까 예제에서의 명령어가 충돌이 나지 않았던 이유는, 포트 바인딩을 아직 해주지 않아서 각자의 컨테이너의 80번 포트에서 작동하고 있었기 때문이다.


이 고민증을 해결하면서 도커의 가상화 라는 개념에 훨씬 깊게 이해 할 수 있었다. 포트 바인딩이야 수없이 들었던 얘기라 떠올리지 못할만한 개념은 아니었지만,

정말 도커 컨테이너가 하나의 가상환경이고 내가 거기서 포트를 할당한 것이구나. 정말 하나의 가상환경이구나! 라고 생각하니 도커에 대한 이해가 훨씬 깊어졌다.

이미지와 메타데이터

우리의 이미지는 정해진 메타데이터를 지니고 있다

이 중 Cmd와 env가 주요한 메타데이터라고 볼 수 있다. Cmd는 우리가 이미지를 run했을때 실행되는 실행 명령어를 의미하고, env는 내부적으로 사용되는 환경변수 설정을 의미한다.

이러한 메타데이터는 실행시에 커스텀 할 수도 있다.

이걸 보면서 자연스럽게 Dockerfile이 생각이 났다.


FROM openjdk:17-jdk-slim

COPY build/libs/bolmal-re-0.0.1-SNAPSHOT.jar app.jar

CMD ["java", "-Dspring.profiles.active=dev", "-jar", "app.jar"]

이게 내가 이전에 사용하던 Dockerfile이다. 각각에 대해서 미약하게 이해했다 싶었지만 지금 다시보니 너무 새로운걸 보니 이 또한 무의식중에 합리화하고 사용한 boiler plate코드였구나 라는 생각을 했다.

솝트를 지금까지 진행하며 가장 크게 드는 생각....boiler plate.....

컨테이너의 라이프 사이클

컨테이너의 라이프 사이클은 다음과 같다.

create를 통해 이미지를 위한 컨테이너를 생성한다. 이때는 메모리를 통해 컨테이너만 생성될 뿐, 실제로 이미지가 실행되지는 않는다. 그렇기 때문에 CPU같은 자원을 할당하지 않는다.

이게 start를 통해 running 상태가 되면 실제로 이미지가 실행된다. 이때에는 CPU 자원을 이용하기 시작한다.

그리고 우리가 run으로 사용하던 명령어가 두 개를 합친 개념인 것이다.

running 상태에서는 두가지의 경우의 수가 생긴다

pause를 통해서 현재 작업 상황을 일시중단 할 수도,
stopped를 통해서 작업을 아예 중단 시킬 수도 있다.

stopped와 restart의 경우 모두 프로세스를 종료한 후에 재실행되는 개념이기 때문에 약 10초간의 딜레이가 존재한다.


또한 프로세스의 라이프 사이클과 컨테이너의 라이프사이클은 거의 유사하기 때문에, 프로세스를 얼마나 잘 관리하냐가 곧 컨테이너를 관리하는 방법론이 될 수 있다.

profile
내가 세상에서 개발 제일 좋아해

0개의 댓글