도커 이미지는 도커 컨테이너에서 애플리케이션을 실행하는 데 필요한 모든 것을 포함하는 패키지이다.
이미지를 기반으로 컨테이너 인스턴스를 생성하고 실행할 수 있다.
도커 이미지는 도커 서비스를 하기 위해서 반드시 필요한 가상화 기술이다.
아마 도커를 시작하게 된다면 이미지를 가장 먼저 접하지 않을까 생각된다.
나는 처음 도커를 배울 때 이미지나 컨테이너, 컴포즈, 스웜... 생소한 용어들이 많아 헷갈렸던 기억이 있다.
그래서 처음에 이미지를 공부하면서 Docker hub를 통해 다양한 이미지를 설치해 연습했던 것 같다.
도커 이미지란?
도커 이미지는 도커 컨테이너를 실행하기 위해 필요한 파일 및 설정 등 포함하는 패키지다.
다양한 애플리케이션을 관리하기 위한 중요한 개념이며, 도커 이미지의 여러 가지 특징에 대해 정리해 보았다.
1. Dockerfile
도커 이미지는 Dockerfile이라는 스크립트로 정의되어 만들어지며, 베이스 이미지를 지정하고 추가적인 패키지, 환경 변수, 명령어 등의 작업을 기술한다.
개인적으로 Dockerfile을 통해서 이미지를 만들어 컨테이너까지 띄워본다면 이미지에 대해 이해하는데 많은 도움이 될 거라고 생각한다.
2. 가상 레이어
도커 이미지는 레이어로 구성되어 있으며, 각 레이어는 파일 시스템 레이어, 실행 환경, 메타데이터 등을 포함하고 있다.
이미지는 이 레이어를 통해 캐싱되어 있기 때문에 중복 다운로드를 최소화하고 이미지의 빌드 속도를 향상시켜준다.
이미지 레이어에 대한 개념이 정리가 되어 있지 않다면 이미지 버전 관리, 업데이트를 하면서 발생할 수 있는 이슈들이 이해가 되지 않은 경우들이 있다. 예전 도커 개발을 하던 프로젝트에서 레이어를 모르고 진행했다가 오랜 기간 고생했던 경험이 있다.
3. 계층화된 파일 시스템
도커 이미지는 계층화된 파일 시스템으로 구성되어 있다. 각 레이어별로 파일 및 디렉터리의 변경 사항을 가지고 있으며, 기존의 레이어를 기반으로 새로운 레이어를 생성한다.
4. 레지스트리
도커 이미지는 로컬 환경의 레지스트리뿐만 아니라 원격 레지스트리에도 저장하여 관리할 수 있다. 이를 통해 이미지를 공유하고, 배포 및 관리를 효율적으로 할 수 있다.
도커 이미지가 무엇인지 특징을 같이 정리해 보았는데, 도커 이미지에 대해 공부 중이라면 Dockerfile을 작성하여 이미지를 만들어 보고, 이미지를 컨테이너로 직접 띄워보는 것이 이해하는 데에 가장 좋을 것이다.
도커 이미지의 구조와 작동 원리
도커 이미지에 대해 공부중이라면 이미지의 구조와 작동 원리에 대해 간단하게라도 이해를 한다면 실제 개발을 할 경우에 많은 도움이 된다.
도커 이미지의 구조
도커 이미지는 여러 계층(Layer)으로 구성되어 있으며, 각 계층은 파일과 디렉터리의 변경 사항을 포함하고 있다.
도커 이미지의 기본이 되는 베이스 이미지는 운영체제, 도구, 라이브러리 등을 포함하고 있는 이미지다. 베이스 이미지는 불변하며, 만들고자 하는 이미지의 기반이 되는 역할을 한다.
Dockerfile 작성을 하게 될 때, 베이스 이미지를 포함하여 이미지를 만들게 되며, 만들고자 하는 이미지가 어떤 기능을 기반으로 만들어지는지에 따라 베이스 이미지를 선택하게 된다.
도커 이미지의 작동 원리
도커 이미지의 각 계층은 읽기 전용으로 생성된다. 컨테이너를 생성할 때, 베이스 이미지의 읽기 전용 계층 위에 새로운 계층을 생성한다.
변경 사항이 발생하면 해당 변경 사항만을 새로운 계층에 적용하고, 읽기 전용 계층은 변경되지 않는다. 이를 통해 이미지의 효율적인 관리와 디스크 공간의 절약이 가능하다.
이미지의 각 레이어는 고유한 해시값을 가지게 되며, 변경 사항이 없다면 동일한 레이어를 여러 이미지가 공유하게 될 수 있다.
위와 같은 구조와 작동 원리를 이해하면 도커 이미지 작업에 효과적으로 작성하고 사용하는 데 도움이 될 것이다.
도커 이미지 레지스트리
도커 이미지를 만들거나 다운로드하게 되면 기본적으로 로컬 저장소에 저장이 된다. 개인적으로 도커 이미지를 공부하고 학습할 때에는 로컬 저장소에만 저장하여 사용해도 크게 문제가 없지만, 실제 업무에서 협업을 하고 운영 관리를 하게 되는 경우에는 로컬 저장소가 아닌 중앙 저장소에 저장을 해서 팀 간의 이미지 공유를 하는 것이 좋다.
도커 이미지를 처음 설치하게 되면 보통은 중앙 저장소인 docker hub에서 이미지를 설치하게 된다. hub 레지스트리에서 받은 이미지를 그대로 사용해도 되고, 업무 환경에 따라 받은 이미지를 베이스 이미지로 사용하고 내용을 변경하여 새로운 이미지로 작성하여 사용해도 된다.
도커 이미지 예제
도커 이미지가 무엇인지 간단하게 정리를 해봤다면 실제 이미지를 만들고 실행해 보는 것이 이미지를 이해하는 데 빠를 것이다.
예제는 간단하게 nginx 이미지를 기반으로 작성하였다.
1. 작업 파일 생성
이미지를 만들기 위해 작업 디렉터리를 생성한다.
mkdir nginximage
cd nginximage
위의 디렉터리로 이동 후 Dockerfile 파일을 생성한다.
2. Dockerfile
도커 이미지를 생성하기 위해서 Dockerfile이란 스크립트를 이용해서 간단하게 만들 수 있다.
다음 스크립트 코드는 nginx 베이스 이미지를 기반으로 작성된 예제 코드다.
# nginx 이미지
FROM nginx:latest
# 작업 디렉토리
WORKDIR /usr/share/nginx/html
# 파일 복사
COPY index.html .
# 포트 설정
EXPOSE 80
스크립트 코드를 하나씩 정리하면,
1. nginx:latest 이미지를 베이스로 설정
2. 작업 디렉터리를 /usr/share/nginx/html로 변경
3. 현재 로컬 폴더에 있는 index.html 파일을 작업 디렉터리롤 복사
4. 마지막으로 포트를 80으로 설정한다.
3. index.html 파일 생성
위의 스크립트의 3번에 해당하는 index.html 파일을 생성한다.
<!-- index.html -->
<html>
<head>
<title>Hello Docker!</title>
</head>
<body>
<h1>Hello, Nginx!</h1>
</body>
</html>
4. 도커 이미지 빌드
Dockerfile 작성이 끝났다면 해당 스크립트 파일을 기반으로 이미지 빌드를 시작한다.
docker build -t nginximage .
Dockerfile 파일이 위치한 디렉터리에서 위의 명령어를 실행한다.
여기서 -t 옵션은 이미지에 태그를 설정하는 것인데, 'nginximage'는 이미지의 이름이고, 마지막 '.'는 현재 디렉터리를 의미한다.
5. 도커 이미지 확인
이미지 빌드가 정상적으로 되었다면 생성된 이미지를 확인한다.
docker images
위의 명령어 실행 시 nginximag라는 이미지가 포함되어 있다면 이미지 생성에 성공한 것이다.
6. 도커 컨테이너 실행
이미지 생성까지 성공하였다면 빌드된 이미지로 컨테이너를 띄우는 것은 간단하다.
docker run -p 8080:80 nginximage
위의 명령어를 실행하고 docker ps 명령어를 치면 실행된 컨테이너 목록이 조회될 것이다.
컨테이너 조회가 되었다면 브라우저에서 'http://localhost:8080' 접속하면 설정한 index.html 화면을 확일할 수 있다.
도커 이미지를 만드는 방법은 이렇게 간단하지만 이미지에 대한 개념을 이해하고 실제 구조에 대해서 정리해 두어야 나중에 만든 이미지가 문제가 생겼을 때 문제점을 파악할 수 있다.
위의 이미지를 만들기 위해 Dockerfile을 작성하였는데, 작성된 기능 외에도 다양한 기능이 있으며, 이를 통해 다양한 이미지를 만들어 서비스할 수 있다.
도커 이미지의 최적화
도커 이미지 작업을 하다 보면 이미지의 크기가 커지는 경우가 빈번하게 있다. 도커는 운영체제의 자원을 빌려와 사용하기 때문에 제한된 자원 내에서 효율적으로 사용해야 한다. 그래서 도커 이미지의 크기를 최적화해서 빌드와 배포 성능을 향상하는 것은 중요한 내용이다.
1. 베이스 이미지
- 베이스 이미지를 사용하는 경우에는 가능한 가볍고 최소한의 패키지만 포함한 이미지를 선택한다.
- 베이스 이미지에 경량화된 이미지가 있는지 확인하고 선택한다. (예를 들어, Apline Linux)
2. 멀티 스테이지 빌드
- 이미지 빌드에 필요한 패키지와 도구는 빌드 스테이지에서만 사용하고, 최종 이미지는 필요한 실행 파일만을 포함하도록 한다.
멀티 스테이지 빌드 사용 방법에 대해서 모르고 이미지 개발을 했을 때 이미지를 여러 번 빌드하고 버전 업하면서 이미지를 만들었던 적이 있다. 지금 생각해 보면 정말 비효율적인 이미지 개발 방식이었다.
- FROM 다중 명령어를 사용하여 빌드 스테이지와 실행 스테이지를 나눠 최종 이미지를 경량화한다.
# 빌드 스테이지
FROM node:14 as build
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# 실행 스테이지
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
위의 스크립트 코드와 같이 FROM을 다중 사용하여 스테이지를 나눠 빌드를 하면 이미지를 여러 번 만들지 않고 한 번에 효율적으로 생성이 가능하다.
3. 불필요한 파일 제거
이미지에 불필요한 파일은 최대한 제거하여 이미지 크기를 줄인다.
4. 레이어의 최소화
이미지 작업을 할 때 최대한 적은 수의 레이어를 사용하여 이미지를 생성하여 레이어 간의 중복을 최소화한다.
5. 다중 명령어 조합
명령어를 사용할 때에는 RUN을 여러 번 사용하여 명령어를 실행하지 않고 단일 RUN을 통해 명령어를 결합하여 이미지 레이어 수를 최소화한다. 이렇게 하면 캐싱 효과를 높일 수 있다.
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
6. 압축된 이미지 사용
이미지 레이어를 압축하여 이미지 크기를 최소화한다. 이미지를 압축하면 전송 및 저장 시에 디스크 공간을 절약할 수 있다.
위와 같은 내용을 통해서 이미지 최적화하는 습관을 길들이면 도커 개발에 많은 도움을 줄 수 있고, 효율적인 운영이 가능하다.
마무리
도커 이미지에 대한 내용을 주제로 정리해 보았다. 이미지를 만드는 방법은 간단하지만 이미지에 대한 개념은 다소 어려울 수 있으므로 정리를 해보는 것이 좋다.
도커를 이용해 서비스를 개발하다 보면 다양한 이미지를 접하기도 하고, 다양한 환경에서 이미지를 만들어 보게 된다.
처음 도커를 접했을 때에는 새로운 개념의 용어들이 많아 이해하는 데에 많은 시간이 들었던 기억이 있다. 지금 생각해 보면 그리 어렵지 않은 내용들이었던 것 같은데, 처음이었던 만큼 익숙해지는 데에 시간이 좀 걸리지 않았나 싶다.
이렇게 글을 쓰면서 내용을 정리해 보았는데, 단순히 머리로만 이해하고 개발하는 것보다 글로 쓰면서 정리를 하면 조금 더 깊이 있게 이해가 되고, 한층 더 성장할 수 있었던 시간이었다.
그래서 다음에도 이어서 도커의 다양한 내용을 주제로 글을 쓰면서 정리해 보아야겠다.
'Docker > docker' 카테고리의 다른 글
Docker를 활용한 Nginx 서버 구성하기 (1) | 2024.03.23 |
---|---|
도커의 핵심, Dockerfile의 기초부터 알아보기! (0) | 2024.01.18 |
도커 Compose로 애플리케이션 관리하기 (1) | 2023.10.17 |