[Docker] Ec2 서버 용량 문제(feat. Docker build cache)
코드 수정 후 푸시를 하면 자동 CI/CD가 이루어지도록 jenkins pipeline 구성해놨다.
근데 바뀐 코드가 적용이 안돼서 jenkins에 들어가보니 빌드 실패라고 나와있었다.(대체 왜...?)
코드만 수정했을 뿐인데 왜 에러가 발생했지하고 생각 후 콘솔창을 보니 아래와 같이 나와있었다.
장치에 여유 공간이 부족해서라길래 EC2 서버에 접속해 사용 용량을 확인해봤다.
df -h 명령어 실행!!
뭘까... 대체 왜 310G만큼이나 차지를 하고있는거지..?하고 생각했다.
혹시 도커를 내리고 올릴 때 이미지를 삭제 안해서 그런건가 해서 docker rmi $(docker images -q)로 이미지를 모두 지우고 다시 확인해봐도 똑같았다.
우선 어느 디렉토리가 용량을 많이 차지하는지 확인해보려 한다.
최상위 경로별 용량 확인(`/` 기준)
sudo du -sh /* 2>/dev/null
/var 디렉토리에 311G...??
대체 /var 안에 어떤 디렉토리가 문제일지 더 확인해보자.
/var 디렉토리 확인
sudo du -sh /var/*
확인해보니 /var/lib/docker이 모든 용량을 잡아먹고 있었다.
근데 잠깐만... 분명 나는 backend Dockerfile에서 아래와 같이 구현해놨었다.
docker compose build --no-cache bacakend
찾아보니 docker compose build --no-cache는 기존에 저장된 캐시를 사용하지 않고, 새로 빌드하는 것이기 때문에 기존에 저장된 캐시를 삭제하는 것과는 다른 의미다!!(바보같았다..)
/var/lib/docker에 쌓여있는 데이터를 지우기 전 어떤 데이터들이 용량을 차지하는지 확인하기 위해 찾아봤다.
1. 사용하지 않는 이미지
Docker는 컨테이너를 실행할 때 이미지를 사용하는데, CI/CD 과정에서 이미지가 계속 쌓이면 엄청난 용량을 차지할 수 있다. 특히, docker-copmose build나 docker build 명령을 자주 실행하면, 새로운 이미지가 계속 생성됨.
docker image prune -a -f
위 명령어를 통해 사용하지 않는 이미지 삭제
# 현재 저장된 이미지 확인
docker images -a
2. 중단된 컨테이너
컨테이너가 종료되어도 기본적으로 삭제되지 않고 남아있다. 컨테이너가 많으면 용량이 수백 GB까지 증가할 수 있다.
docker container prune -f
위 명령어를 통해 실행 중이 아닌 컨테이너 삭제
# 현재 저장된 컨테이너 확인
docker ps -a
3. 사용하지 않는 볼륨
볼륨은 MySQL, Redis, MongoDB에서 데이터를 유지하는 공간인데 오래된 볼륨이 남아있으면 욜양이 계속 증가할 수 있다. 특히, CI/CD 과정에서 docker-compose up을 여러 번 실행하면 볼륨이 계속 쌓일 수 있다. 컨테이너가 삭제되더라도 볼륨이 자동으로삭제되지 않음.
docker volume prune -f
위 명령어를 통해 사용하지 않는 볼륨 삭제
# 현재 저장된 볼륨 확인
docker volume ls
4. Docker 캐시 데이터
Docker는 빌드 속도를 높이기 위해 캐시를 저장하는데, 이 캐시가 쌓이면 수백 GB까지 차지할 수 있다. docker build 명령을 실행할 때마다 캐시가 남는다. 여러 개의 중간 이미지(Layer)가 저장된다.
docker builder prune -a -f
위 명령어를 통해 사용하지않는 빌드 캐시 삭제
5. Docker 로그 파일
컨테이너에서 생성되는 로그 파일이 삭제되지 않고 계속 남아 있으면 수십 GB까지 증가할 수 있음.
MySQL, Kafka, Nginx 같은 서비스는 매우 많은 로그를 생성
#컨테이너 별 로그 파일 크기 확인
find /var/lib/docker/containers/ -name "*.log" -exec du -sh {} +
#모든 로그 파일 초기화(데이터 삭제 X, 크기만 0으로)
truncate -s 0 /var/lib/docker/containers/*/*.log
로그 파일의 경우 docker-compose.yml에서 크기 제한을 설정하자.
# 10MB, 최대 3개 유지
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
6. Docker 네트워크
Docker는 컨테이너 간의 통신을 위해 네트워크를 자동 생성하는데, 네트워크가 많아지면 메모리와 디스크 공간을 차지할 수 있다.
docker network prune -f
위 명령어를 통해 사용하지 않는 네트워크 삭제
# 현재 저장된 네트워크 확인
docker network ls
7. 전체 Docker 용량 확인
# Docker가 사용하는 전체 용량 확인
docker system df
# 각 항목별 사용량 확인 가능
docker system df -v
불필요한 데이터를 모두 정리하기 위해 아래 명령어로 사용하지 않는 컨테이너, 네트워크, 볼륨, 이미지 등 모두 정리해주었다.
docker system prune -a -f
310GB를 차지하고 있어서 정리하는데 시간이 꽤 걸렸음......
정리 완!
CI/CD 설계할 때 다음을 고려해야겠다.
1. 스케줄링을 통한 docker 정리
2. docker-compose.yml에서 로그 파일 용량 크기 제한
참고