개인 테스트 목적으로 Docker를 애용하고 있는데요. 원하는 패키지가 설치된 Docker 공식 이미지가 없는 경우 Docker hub에 게시된 공인받지 않은 커스텀 이미지를 받아서 사용하기 보단 원하는 Docker 이미지를 빌드하여 사용하곤 합니다. 이때는 보통 CentOS 환경이 익숙하기 때문에 저는 CentOS 7 이미지를 베이스 이미지로 하여 빌드를 하는데 최근에 Alpine Linux를 통해 Docker 이미지를 빌드하는 방법에 대해 알게되어 기술 공유하고자합니다.
Alpine 리눅스란
공식 사이트
https://www.alpinelinux.org/
1. Alpine Linux는 경량 리눅스 배포판으로 Docker 이미지 빌드 시 베이스 이미지로 주로 사용됩니다.
(물론 Docker 이미지를 빌드하는 목적 외에도 저사양 하드웨어에 OS로 설치하여 사용 가능합니다)
2. Alpine docker 베이스 이미지 용량은 약 5MB로 아주 가벼운 특징을 가지고 있습니다.
이 부분은 약 200MB의 용량을 가진 CentOS 7 이미지와 대조적입니다.
3. Alpine Linux는 CentOS, Ubuntu 와 같이 glibc(GNU C 라이브러리)를 사용하지 않고 musl 이라는 독자적인 라이브러리를 사용하기 때문에 기존 CentOS, Ubuntu 환경에서 빌드된 바이너리는 사용이 제한적입니다.(glibc 관련 라이브러리를 참조하는 경우 실행 에러 발생)
4. Alpine Linux는 별도의 패키지 매니저를 가지고 있어 apk라는 명령어를 사용하여 yum과 같이 디펜던시를 포함하여 패키지를 외부 레포지토리에서 내려받아 설치/삭제/업데이트 가능합니다.
아래 예시에서는 python3 패키지를 디펜던시 포함하여 설치하는 예시이며, --no-cache 옵션을 붙이는 경우 로컬 디렉토리에 패키지 관련 임시파일을 캐싱하지 않기 때문에 이미지 빌드 시 이미지의 용량을 줄이기 위해 추가하는 편이 좋습니다.
apk 명령어 사용 가이드
https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management
Alpine Linux로 Docker 이미지 빌드
Docker 이미지를 빌드하는 환경은 Amazon EC2 CentOS 7 AMI(x86_64)이지만 Docker가 설치된 환경이라면 어디서나 가능합니다.
Apache를 실행하는 Docker 이미지 빌드
동일하게 apache를 설치한 Docker 이미지를 빌드하되, Alpine Linux와 CentOS7 이미지를 각각 베이스 이미지로 설정하여 완성된 Docker 이미지의 용량을 비교해보겠습니다.
# 작업 디렉토리 생성
mkdir apache-alpine && cd apache-alpine
# Dockerfile 작성
vim Dockerfile
FROM alpine:latest
RUN apk update --no-cache && apk add --no-cache apache2
ENTRYPOINT [ "httpd","-D","FOREGROUND" ]
EXPOSE 80
# 이미지 빌드
docker build -t apache-alpine:1.0 ./
별도 모듈 없이 apache만 설치했기 때문에 이미지가 만들어지는데는 그리 오래 걸리지 않습니다.
Alpine Linux 이미지를 베이스로 만든 apache 이미지는 약 11MB의 용량을 가집니다.
생성한 이미지를 통해 컨테이너를 생성하여 접속해보겠습니다.
docker run -d -p 80:80 --name apache-alpine apache-alpine:1.0
웹을 통해 잘 접속되는 것을 확인할 수 있습니다. 같은 방식으로 CentOS7 이미지를 베이스로하여 만들어보겠습니다.
# 작업 디렉토리 생성
mkdir apache-centos && cd apache-centos
# Dockerfile 작성
vim Dockerfile
FROM centos:7
RUN yum install -y httpd
ENTRYPOINT [ "httpd","-D","FOREGROUND" ]
EXPOSE 80
# 이미지 빌드
docker build -t apache-centos:1.0 ./
이미지 빌드를 실행합니다.
(중략)
생성된 이미지 용량을 Alpine Linux 이미지를 베이스로 했을 때와 비교해보겠습니다. CentOS7이미지를 베이스 이미지로 했을 때의 용량은 약 380MB로 Alpine Linux 이미지를 베이스로 했을 때보다 약 30배 이상 용량이 큰 것을 확인할 수 있습니다.
마찬가지로 빌드한 이미지로 컨테이너를 생성하여 접속해봅니다.
docker rm -f apache-alpine
docker run -d -p 80:80 --name apache-centos apache-centos:1.0
이를 통해 동일하게 apache를 설치한 이미지를 만들 때 베이스 이미지를 Alpine Linux로 설정하면 Docker 이미지를 보다 더 가벼운 용량으로 생성할 수 있음을 확인할 수 있습니다.
Python Flask를 실행하는 Docker 이미지 빌드
이번에는 Python의 웹 프레임워크인 flask를 설치한 이미지를 빌드해보도록 하겠습니다.
# 작업 디렉토리 생성
mkdir flask-alpine && cd flask-alpine
# Dockerfile 작성
vim Dockerfile
FROM alpine:latest
RUN apk update --no-cache && apk add --no-cache py3-pip
RUN pip3 install flask
COPY app.py /app.py
ENTRYPOINT [ "python3","/app.py" ]
EXPOSE 5000
# flask 소스 파일 작성
vim app.py
from flask import Flask
app = Flask(__name__)
@app.route("/hello")
def test():
return "Hello Flask!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port="5000")
# 이미지 빌드
docker build -t flask-alpine:1.0 ./
이제 이미지를 빌드해보겠습니다.
(중략)
빌드된 이미지로 컨테이너를 생성하여 접속해보겠습니다.
docker run -d -p 5000:5000 --name flask-alpine flask-alpine:1.0
접속 시 포트(:5000)와 경로(/hello)에 유의하여 접속해봅니다. 정상적으로 접속되는 것을 확인할 수 있습니다.
이제 같은 방식으로 CentOS7 이미지를 베이스 이미지로 하여 빌드해보겠습니다.
# 작업 디렉토리 생성
mkdir flask-centos && cd flask-centos
# Dockerfile 작성
vim Dockerfile
FROM centos:7
RUN yum install -y python3-pip
RUN pip3 install flask
COPY app.py /app.py
ENTRYPOINT [ "python3","/app.py" ]
EXPOSE 5000
# flask 소스 파일 작성(flask-alpine 이미지와 동일)
vim app.py
from flask import Flask
app = Flask(__name__)
@app.route("/hello")
def test():
return "Hello Flask!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port="5000")
# 이미지 빌드
docker build -t flask-centos:1.0 ./
빌드를 실행합니다.
(중략)
빌드된 이미지로 컨테이너를 생성하여 접속해봅니다.
docker rm -f flask-alpine
docker run -d -p 5000:5000 --name flask-centos flask-centos:1.0
동일한 python 소스를 실행하는 flask 이미지의 용량을 비교해보겠습니다. Alpine Linux 기반의 flask 이미지의 용량은 약 73MB, CentOS7 기반의 flask 이미지의 용량은 약 402MB로 CentOS7 기반의 flask 이미지가 약 4배 이상 많은 용량을 차지합니다.
결론
위의 과정을 통해 Alpine Linux 이미지를 베이스 이미지로 하여 Docker 이미지를 빌드했을 때, CentOS7 기반의 이미지에 비해 이미지의 용량이 상당히 가벼운 것을 확인할 수 있었습니다. 다만, apache2(Alpine Linux) / httpd(CentOS)와 같이 동일한 패키지라도 Alpine Linux와 CentOS에서 설치할 때 사용하는 패키지 이름이 다르기 때문에 유의가 필요할 것으로 보입니다. apk 명령어의 사용법만 잘 익혀둔다면 원하는 Docker 이미지를 작은 용량으로 만들 수 있기에 유용할 것으로 생각됩니다.
'docker' 카테고리의 다른 글
Docker buildx를 통한 멀티 플랫폼 이미지 빌드 (0) | 2023.03.11 |
---|---|
traefik 리버스 프록시 로드밸런서 (1) | 2023.03.06 |
docker swarm (0) | 2023.03.06 |
docker buildx (0) | 2023.03.06 |