일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 자바의 정석 기초편 ch1
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch7
- 스프링 mvc1 - 스프링 mvc
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch14
- 스프링 고급 - 스프링 aop
- 람다
- 스프링 mvc2 - 로그인 처리
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch11
- 데이터 접근 기술
- 자바의 정석 기초편 ch6
- 2024 정보처리기사 수제비 실기
- 자바의 정석 기초편 ch5
- 자바 고급2편 - 네트워크 프로그램
- 자바로 계산기 만들기
- 자바 기초
- @Aspect
- 자바의 정석 기초편 ch2
- 스프링 트랜잭션
- 자바의 정석 기초편 ch9
- 자바 고급2편 - io
- 스프링 입문(무료)
- 자바 중급1편 - 날짜와 시간
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch13
- 자바 중급2편 - 컬렉션 프레임워크
- 자바로 키오스크 만들기
- 자바의 정석 기초편 ch4
- Today
- Total
개발공부기록
Dockerfile, Docker Compose, Docker 모니터링과 로깅 본문
Dockerfile
Dockfile이란
Dockerfile은 Docker Image를 빌드하기 위한 파일로서 어떤 파일을 실행하고, 프로그램을 설치할지, 어떤 OS에서 실행할지 등을 적어놓은 파일이다.
이미지는 앱을 실행하는데 필요한 모든 것을 담고 있는데, 이 이미지를 만들기 위한 레시피라고 보면 된다.
도커 파일을 작성 후 빌드를 하게 되면 도커 파일에 설정되어있는대로 파일을 다운 받고 설치하고 실행하는 명령을 수행한다.
이렇게 빌드 된 이미지를 실행 시키면 도커 컨테이너가 실행되게 된다.
Dockerfile을 작성하면 앱이 필요로 하는 모든 것을 한 곳에 작성할 수 있게 되어 똑같은 앱 환경을 쉽게 만들 수 있게 된다.
그리고 앱을 만드는 과정을 자동화할 수 있기 때문에 똑같은 방식으로 앱을 만들고 편하게 배포할 수 있게 된다.
이 덕분에 앱을 만드는 일이 더욱 쉽고 같은 환경에서 실행하기 때문에 누구나 같은 결과를 얻을 수 있다.
Docker file 작성 예시
# Dockerfile
FROM ubuntu:latest
MAINTAINER Your Name <your-email@example.com>
RUN apt-get update && apt-get install -y nginx
COPY index.html /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
- 위 Dockerfile은 Ubuntu 최신 버전을 기반으로 nginx를 설치하고 index.html 파일을 nginx의 HTML 디렉토리에 복사하는 예시이다.
- Dockfile을 작성할 때에는 FROM, MAINTAINER, RUN 등의 명령어를 포함하여 작성하는데 자세한 부분은 뒤에서 설명과 함께 다뤄보겠다.
Dockerfile을 통해 이미지를 생성하는 과정
위의 예시처럼 Dockerfile을 만들었다고 가정하고 이미지를 생성하려면 아래의 명령어를 입력하면 된다.
아래의 명령어는 현재 디렉토리에서 Dockerfile을 기반으로 my-nginx:latest라는 이름의 Docker 이미지를 생성하는 명령어다.
- 아래의 명령어 중 첫 번째 명령이 실행되지 않은 경우 buildx 명령어를 추가하면 Dockerfile로 이미지를 생성할 수 있다.
docker build -t my-nginx:latest .
docker buildx build -t my-nginx:latest . # 위 명령이 실행되지 않는 경우 실행
위 명령어로 실행된 Docker 이미지는 컨테이너로 실행할 수 있다.
아래의 명령어는 my-nginx:latest 이미지를 기반으로 컨테이너를 실행하고 80번 포트를 호스트 머신의 80번 포스로 매핑한다.
docker run -d -p 80:80 my-nginx:latest
아래의 명령어를 입력하면 생성된 컨테이너가 종료된다.
docker stop my-nginx
이렇게 생성된 이미지는 컨테이너로 띄울 수 있기도 하지만 Registry에 저장하여 다른 사용자와 공유할 수 있다.
이런 레지스트리는 위의 이미지에서 처럼 On-premises로 private한 레지스트리도 있지만 Docker Hub, Azure Container, AWS Container 처럼 공용 클라우드 레지스트리 등을 사용할 수 있다
Dockerfile 명령어
FROM: 베이스 이미지를 지정한다
- 아래의 명령어는 ubunt:22.04로부터 이미지를 만든다.
- ex) FROM ubuntu:22.04
MAINTAINER: Dockerfile을 작성한 사람의 정보를 입력한다
- ex) MAINTAINER user <nbcamp@spartacoding.co>
LABEL: 이미지에 메타데이터를 추가한다
- ex) LABEL purpose='nginx test'
RUN: 이미지를 생성하는 동안 실행할 명령어를 입력한다.
- 사용자를 지정하지 않은 상태라면 root 로 실행된다.
- ex) RUN apt update && apt upgrade -y && apt autoremove && apt autoclean
- ex) RUN apt install openjdk-21-jdk
CMD: 컨테이너를 생성할 때 실행할 명령어를 입력한다.
- 컨테이너를 생성할 때만 실행되며 추가적인 명령어에 따라 설정한 해당 명령어 수정할 수 있다.
- ex) CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT: 컨테이너 시작할 때 실행할 명령어를 입력한다. CMD와의 차이점은 컨테이너를 시작할 때마다 실행된다.
- 컨테이너를 시작할 때마다 실행되며 추가적인 명령어 존재 여부와 상관 없이 무조건 실행 한다.
- ex) ENTRYPOINT ["npm", "start"]
ENV: 이미지안에 환경 변수를 설정할 수 있다.
- ex) ENV STAGE staging
- ex) ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
WORKDIR: 작업 디렉터리를 지정한다.
- 만약 디렉토리가 없으면 만들어서 지정한다.
- ex) WORKDIR /app
COPY: 호스트의 파일이나, 디렉토리를 이미지안에 복사할 수 있다
- Docker Context 즉, 빌드 작업 디렉토리 내 파일만 복사 가능하다
- ex) COPY index.html /usr/share/nginx/html
USER: 사용자를 설정한다.
- Container의 기본 사용자는 root 이며 root 권한이 필요 없는 application이라면 다른 사용자로 변경하여 사용해야 한다.
RUN ["useradd", "user"]
USER user
RUN ["/bin/bash, "-c", "ls"]
EXPOSE: 컨데이터에서 노출할 포트를 지정한다
- ex) EXPOSE 80
- ex) EXPOSE 443
1. FastAPI 앱을 실행하는 Dockerfile 예제
# 파이썬:3.11 이미지에서 실행
FROM python:3.11
RUN pip install pipenv
# 디렉토리를 /app으로 지정
WORKDIR /app
# 모든 파일을 /app에 복사(추가)
ADD . /app/
# 명령 수행
RUN pipenv --python 3.11
RUN pipenv run pip install poetry
RUN pipenv sync
RUN pipenv run pip install certifi
ARG STAGE
RUN sh -c 'echo "STAGE=$STAGE" > .env'
RUN sh -c 'echo "PYTHONPATH=." >> .env'
RUN chmod +x ./scripts/run.sh
RUN chmod +x ./scripts/run-worker.sh
CMD ["./scripts/run.sh"]
2. nginx 이미지를 생성하는 예제
- 실제로는 만들어져 있는 nginx:latest(최신 nginx) 이미지를 사용하면 되지만 예제를 위해 작성된 예시이다
# 우분투 22.04로 실행
FROM ubuntu:22.04
MAINTAINER your-name <your-email@example.com>
LABEL purpose=Web Server
# nginx 패키지 설치
RUN apt-get update && apt-get install -y nginx
# nginx 설정 파일 복사
COPY nginx.conf /etc/nginx/nginx.conf
# Nginx 실행
CMD ["nginx", "-g", "daemon off;"]
** 참고 - nginx.cong 예시
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
}
Docker Compose
Docker Compose를 사용하는 이유
편하게 설정
- Docker Compose는 여러 컨테이너를 한 파일에 적어서 설정할 수 있다.
- 해당 파일에는 컨테이너가 무슨 이미지를 쓸지, 어떤 포트를 사용할지, 환경 변수는 뭐가 필요한지 등을 적어두는데 이렇게 하면 여러 컨테이너를 한 번에 쉽게 설정할 수 있게 된다.
자동으로 배포
- 설정 파일이 있으면 Docker Compose가 알아서 컨테이너들을 만들어 주고 실행해 주기 때문에 개발자가 일일이 명령어를 입력할 필요가 없다.
의존성 관리
- 컨테이너들이 서로 의존하는 관계가 있으면 Docker Compose가 이를 관리해 준다
- 예를 들어 A 컨테이너가 B 컨테이너를 필요로 하면 A를 먼저 켜고 나서 B를 실행하는 경우이다.
모니터링과 로깅
- Docker Compose는 컨테이너들이 어떻게 돌아가는지 지켜보고 로그도 모아주기 때문에 문제가 생겼을 때 빨리 찾아서 고칠 수 있다
확장성
- 여러 컨테이너를 하나의 그룹으로 관리할 수 있다.
- 확장성이 좋은 이유를 예를 들면 웹 앱을 만드는 여러 컨테이너를 한꺼번에 관리하여 확장하기가 쉬워진다.
유연성
- Docker Compose는 개발 환경, 테스트 환경, 실제 운영 환경에서도 같은 설정 파일을 써서 일관성을 유지할 수 있다
보안 강화
- 컨테이너들의 네트워크를 분리해서 외부로부터의 접근을 제한할 수도 있어 보안이 강화된다.
쉬운 유지보수
- 설정 파일 하나로 컨테이너들을 관리하기 때문에 뭔가 바꿀 일이 있으면 파일만 수정하면 Docker Compose가 알아서 변경사항을 적용해준다.
위에서 알아 보았듯이 Docker Compose를 사용하면 여러 컨테이너를 더 쉽게 관리하고, 자동으로 설정하고, 확장하고, 보안을 강화할 수 있기 때문에 개발자 입장에서는 매우 편리한 도구가 편리할 수 밖에 없다.
Docker Compose가 사용되는 환경
주로 개발과 테스트에 많이 쓰지만 도커는 새로운 버전이 나올 때마다 다양한 용도로 사용할 수 있도록 계속 개선되고 있다.
개발 환경
- 앱을 개발할 때 앱을 따로 떼어 놓고 실행하고 테스트할 수 있는 환경이 필요한데 Docker Compose를 쓰면 이런 환경을 쉽게 만들고 관리할 수 있다.
- Compose 파일은 앱이 필요로 하는 모든 서비스들(데이터베이스, 큐, 캐시, 웹 API 등)을 정리해주고 docker compose up 명령어로 이 모든 것을 한 번에 시작할 수 있다.
- 여러 페이지의 설명서 대신에 Compose 파일 하나로 모든 설정을 통합할 수 있기 때문에 개발자가 새 프로젝트를 시작할 때 많은 시간을 절약할 수 있게 된다
자동화된 테스트 환경
- 자동화된 테스트는 앱이 잘 돌아가는지 확인하는 데 중요한데 Docker Compose는 이런 테스트를 위한 별도의 환경을 쉽게 만들고 없앨 수 있다.
- Compose 파일에 테스트 환경을 정의해두고 간단한 명령어 몇 개로 테스트 환경을 만들고 테스트를 실행한 다음 다시 환경을 없앨 수 있다
- 아래의 명령어처럼 사용하면 된다.
docker compose up -d
./run_tests
docker compose down
단일 호스트 배포
- Docker Compose는 주로 개발과 테스트에 많이 쓰이지만 단일 머신에서 앱을 운영하는 환경(프로덕션)에도 쓸 수 있다
Docker Compose 특징, 장점
한 번에 여러 컨테이너 설정
- Docker Compose는 여러 컨테이너의 설정을 하나의 YAML 파일에 넣어서 관리한다.
- 이 파일 하나로 여러 컨테이너의 모든 환경을 설정하고 한 번에 실행할 수 있죠.
빠른 서비스
- 설정 값들을 저장해 두고 다시 쓸 수 있다
- 만약 설정이 바뀌지 않았다면 Docker Compose는 이전에 저장해둔 정보를 다시 사용해서 서비스를 더 빨리 시작할 수 있다
같은 네트워크에서 쉽게 사용 가능
- docker-compose.yaml 파일에 있는 애플리케이션들은 모두 같은 네트워크에 자동으로 연결되기 때문에 복잡한 네트워크 설정 없이도 여러 컨테이너가 서로 쉽게 통신할 수 있다.
이런 특징들 덕분에 Docker Compose는 여러 컨테이너를 관리하고 실행하는 데 정말 편리한 도구로서 사용된다.
설정도 간편하고, 빠르게 실행할 수 있고, 컨테이너들끼리의 연결도 쉽게 할 수 있다
Docker Compose 실행 과정
- 각 애플리케이션의 Dockerfile 작성
- 보통 내가 만든 애플리케이션을 실행하기 위한 Dockerfile만 작성
- docker-compose.yaml 파일 작성
- 내가 만든 애플리케이션을 실행하기 위해 필요한 database라든지 redis라든지 다른 서비스들을 한꺼번에 정의하는 파일을 작성
- docker compose up 으로 실행
** YAML 파일이란?
YAML(YAML Ain't Markup Language) 파일은 컴퓨터가 읽을 수 있는 설정 파일로 사람이 읽기에도 쉬운 텍스트 형식으로 되어 있다.
YAML은 이름 그대로 마크업 언어가 아니다 라는 뜻이다.
YAML 파일은 일반 텍스트로 쓰여 있으며 설정이나 데이터를 쉽게 알아볼 수 있는 형식으로 나열한다
YAML 파일은 설정을 정리하고 관리하기에 매우 좋다
예를 들어 Docker Compose에서는 YAML 파일을 사용해서 여러 컨테이너의 설정을 한 곳에 쉽게 정리할 수 있다.
YAML은 읽기 쉽고 쓰기도 간단해서 많은 프로그램과 도구에서 선호하는 설정 파일 형식이며 확장자는 .yaml이 정석이지만 yml로도 많이 사용된다.
YAML파일은 들여쓰기를 사용해서 각 설정의 관계를 나타내기 때문에 구조가 명확하고 간단해서 사람이 보기에도 이해하기가 쉽다
YAML의 문법
- 키-값 쌍: 키와 값으로 이루어진 쌍으로 구성되며, 키와 값은 콜론(:)으로 구분된다.
- 리스트: 쉼표(,)로 구분된 값들의 리스트로 구성됩니다.
- 딕셔너리: 중괄호({})로 둘러싸인 키-값 쌍의 리스트로 구성됩니다.
- 불린 값: true, false, yes, no 등의 값으로 표현됩니다.
- 문자열: 큰 따옴표("")나 작은 따옴표('')로 둘러싸인 문자열로 표현됩니다
- 보통 들여쓰기가 잘못된 경우 yaml 파일을 의도와 다르게 해석하게 되니 들여쓰기에 매우 주의가 필요하다
- https://www.yamllint.com/ 에서 들여쓰기를 검사할 수 있다.
Docker Compose 예제 파일 분석
version: '3'
services:
web:
image: nginx:latest
ports:
- 80:80
volumes:
- ./web:/usr/share/nginx/html
depends_on:
- api
links:
- api:api
api:
image: java:latest
volumes:
- ./api:/app
ports:
- 8080:8080
environment:
- REDIS_HOST=redis
- MYSQL_HOST=mysql
- MYSQL_USER=root
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=test
depends_on:
- mysql
- redis
links:
- mysql:mysql
- redis:redis
redis:
image: redis:latest
ports:
- 6379:6379
mysql:
image: mysql:latest
ports:
- 3306:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=test
- MYSQL_USER=root
- MYSQL_PASSWORD=password
version: Docker Compose의 버전을 정의한다.
- docker engine의 버전과 연관되어 있다
- 과거에는 2.x, 3.x 버전처럼 관리하였지만 현재 관장되는 Compose 파일 포맷은 Compose Specification으로 2.x와 3.x버전을 통합한 형태라고 한다.
- https://docs.docker.com/reference/compose-file/
- https://docs.docker.com/reference/compose-file/legacy-versions/
services: 네 개의 서비스를 정의한다.
- web 서비스는 Nginx 이미지를 사용하며, 포트 80번을 호스트 머신에 노출
- api 서비스는 Java 이미지를 사용하며, 포트 8080번을 호스트 머신에 노출
- redis 서비스는 Redis 이미지를 사용하며, 포트 6379번을 호스트 머신에 노출
- mysql 서비스는 MySQL 이미지를 사용하며 포트 3306번을 호스트 머신에 노출
volumes: web 서비스는 현재 디렉토리 내 web 디렉토리를 컨테이너에 연결한다.
- api 서비스는 현재 디렉토리 내 api 디렉토리를 컨테이너에 연결
- mysql 서비스는 현재 디렉토리 내 mysql 디렉토리를 사용하여 MySQL 데이터를 영구적으로 저장
depends_on: 각 서비스 간의 의존성을 정의한다.
- web 서비스는 api서비스에 의존
- api 서비스는 mysql과 redis 서비스에 의존
links: 각 서비스 간의 링크를 정의합니다.
- web 서비스는 api서비스에 링크
- api 서비스는 mysql과 redis 서비스에 링크
이 예제에서는 web 서비스와 api 서비스가 각각 독립적인 컨테이너로 실행되며 web 서비스는 api 서비스에 의존하며, api 서비스는 mysql과 redis 서비스에 의존한다.
redis와 mysql 서비스는 각각 독립적인 컨테이너로 실행됩니다.
Dockerfile 구조 간략 버전
version: "3"
services:
service1:
# ...service1 설정
service2:
# ...service2 설정
networks:
# 네트워크 설정, 선택적
volumes:
# 볼륨 설정, 선택적
- Services안에 각 서비스의 이름을 지어서 서비스로 부를 컨테이너에 대한 정보를 입력한다
- 네트워크설정과 볼륨 설정은 선택적으로 설정할 수 있다.
services 상세 분석
services:
web:
build:
context: . # Dockerfile 의 위치
dockerfile: Dockerfile # Dockerfile 파일명
container_name: testapp_web_1 # 생략하는 경우
# 자동으로 부여 docker run 의 --name 옵션과 동일
ports: "8080:8080" # docker run 의 -p 옵션과 동일
expose: "8080" # 호스트머신과 연결이 아니라
# 링크로 연결된 서비스 간 통신이 필요할 때 사용
networks: testnetwork # networks 를 최상위에 정의한다면 해당 이름을 사용
# docker run의 --net 옵션과 동일
volumes: .:/var/lib/nginx/html # docker run 의 -v 옵션과 동일
environment:
- APPENV=TEST # docker run 의 -e옵션과 동일
command: npm start # docker run 의 가장 마지막
restart: always # docker run 의 --restart 옵션과 동일
depends_on: db # 이 옵션에 지정된 서비스가 시작된 이후에 `web`서비스가 실행
links: db # Docker가 네트워크를 통해 컨테이너를 연결하도록 정의합니다.
# 컨테이너를 연결할 때 Docker는 환경 변수를 만들고
# 컨테이너를 알려진 호스트 목록에 추가하여 서로를 검색할 수 있도록 합니다.
deploy: # 서비스의 복제본 개수 등 지정
replicas: 3
mode: replicated
- services에서는 컨테이너 대신 서비스 개념으로 간주하여 여러가지 설정을 할 수 있다.
- build
- 각 서비스의 이름은 자유롭게 지정할 수 있으며 해당 예제에서는 web으로 설정하였고 지정한 Dockerfile의 위치와 파일명을 입력하여 build를 하고 있다.
- 해당 부분 대신 이미 만들어진 이미지를 pull해서 사용할 수도 있다
- container_name
- 컨테이너 이름을 명시적으로 원하는 이름으로 부여할 수 있으며, 생략하는 경우 자동으로 부여된다.
- docker run의 --name 옵션을 붙이는 것과 동일하다
- ports
- 8080포트를 8080포트와 연결하고 있다.
- docker run의 -p옵션과 동일하다
- expose
- 8080으로 설정되어있는데, 호스트 머신과 연결이 아니라 링크로 연결된 서비스 간에 통신이 필요할 때 사용되는 포트이다.
- networks
- 네트워크 설정으로 networks를 docker compose의 최상위에 정의한다면 해당 이름을 사용할 수 있다
- docker run의 --net 옵션과 동일하다
- volumes(service 내부의 볼륨)
- 도커 볼륨 혹은 호스트 볼륨을 마운트한다.
- . (현재 디렉토리)를 /var/lib/nginx/html 디렉토리에 연결하고 있다
- docker run의 -v 옵션과 동일하다
- environment
- 환경변수를 작성할 수 있으며 docker run의 -e 옵션과 동일하다
- command
- docker run의 가장 마지막에 들어가는 내용이며 해당 컨테이너를 실행할 때 어떤 명령어를 실행할지를 적는다.
- restart
- 중지된 경우에 어떻게 할 것인지 정의한다
- docker run의 --rest의 옵션과 동일하다
- depends_on
- 이 옵션에 지정된 서비스가 시작된 이후에 web 서비스가 실행된다.
- link
- 도커가 네트워크를 통해 컨테이너를 연결하도록 할 때 작성한다.
- 컨테이너를 연결할 때 도커는 환경 변수를 만들고 컨테이너를 알려진 호스트 목록에 추가하여 서로를 검색할 수 있도록 한다
- deploy
- 서비스의 복제본 개수 등을 지정할 수 있다.
volumes(services 내부의 볼륨이 아닌 외부 volumes)
version: "3.9"
services:
web:
# ...
volumes:
- README.md:/docs/README.md # 호스트의 README.md 파일을 컨테이너 내부 /docs/README.md에 마운트
- logvolume01:/var/log # 선언된 도커 볼륨 logvolume01을 컨테이너 내부 /var/log에 마운트
# ...
volumes:
logvolume01: {} # 도커볼륨 logvolume01 선언
- 도커 볼륨 혹은 호스트 볼륨을 마운트하여 사용할 때 도커 볼륨을 services 바깥에서 선언하여 Docker 볼륨을 사전에 명시적으로 정의하고 해당 볼륨을 services 내부에서 다시 마운트 시킬 수 있다.
- 여러 컨테이너가 같은 볼륨을 공유할 때나 외부에서 만든 볼륨을 연결하거나 특정 드라이버를 쓸 때는 volumes를 serviese 바깥에 선언해야 한다고 한다.
networks(services 내부 networks가 아닌 외부 networks)
- 서비스가 소속된 네트워크로 따로 지정하지 않을 경우 default_${project} 처럼 지정된다.
- 기본적으로 컨테이너는 같은 네트워크에 있어야 통신이 가능하다.
healthcheck
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
start_interval: 5s
- 서비스 컨테이너가 계속 살아 있는지 체크하는 설정도 할 수 있다.
- Dockerfile에 정의된 것을 먼저 따르지만 docker-compose 파일에서 재지정이 가능하다.
Docker Compose CLI 명령들
docker-compose [COMMAND] [SERVICES...]의 형태로 지정된 서비스(컨테이너)만 제어가 가능하다
예를 들어서 web, redis 중에 web만 기동하고 싶을 경우 docker-compose up -d web와 같이 실행한다.
docker-compose up
- docker-compose up 실행시 다음의 순서로 진행하며 이미 생성된 경우 해당 단계를 건너뛴다. (멱등성)
- 서비스를 띄울 네트워크 생성
- 필요한 볼륨 생성(혹은 이미 존재하는 볼륨과 연결)
- 필요한 이미지 풀(pull)
- 필요한 이미지 빌드(build)
- 서비스 실행 (depends_on 옵션 사용시 서비스 의존성 순서대로 실행)
- 옵션
- --build: 이미 빌드가 되었더라도 강제로 빌드를 진행한다.
- -d: 백그라운드로 실행한다
- --force-recreate: docker-compose.yml 파일의 변경점이 없더라도 강제로 컨테이너를 재생성한다. 즉 컨테이너가 종료되었다가 다시 생성된다.
docker-compose down: 서비스를 멈추고 삭제하며 컨테이너와 네트워크를 삭제한다
- 옵션
- --volume: 선언된 도커 볼륨도 삭제한다.
docker-compose stop, docker-compose start
- 서비스를 멈추거나, 멈춰 있는 서비스를 시작한다.
docker-compose ps
- 현재 환경에서 실행 중인 각 서비스의 상태를 표시한다.
docker-compose logs
- 컨테이너 로그를 확인한다
- 옵션
- -f: tail -f와 유사하게 컨테이너 로그를 실시간으로 확인한다.
docker-compose exec
- 실행 중인 컨테이너에 해당 명령어를 실행한다.
docker-compose exec django ./manage.py makemigrations
docker-compose exec db psql postgres postgres
docker-compose run
- 특정 명령어를 일회성으로 실행하지만 컨테이너를 batch성 작업으로 사용하는 경우에 해당한다.
- 이미 기동하고 있는 컨테이너에 명령어를 실행하고자 하면 docker-compose exec을 사용하는 반면에 docker-compose run을 사용할 경우 컨테이너를 기동시키고 특정 명령어를 실행이 완료된 후에 컨테이너를 종료한다는 차이점이 있다
# 이미 실행된 web 컨테이너에서 echo "hello world"를 실행
docker-compose exec web echo "hello world"
# web 컨테이너에서 echo "hello world"를 실행하고 컨테이너 종료
docker-compose run web echo "hello world"
Docker 모니터링과 로깅
Docker 모니터링
도커에서 모니터링은 컨테이너가 어떻게 돌아가고 있는지 실시간으로 성능, 사용 중인 자원(예: CPU나 메모리), 네트워크 사용량 같은 것들을 확인하는것이다.
이런 정보들을 알면 컨테이너가 잘 돌아가고 있는지 어떤 문제가 있는지 빠르게 파악할 수 있으므로 모니터링은 항상 중요하다
도커에는 모니터링을 위한 몇 가지 기본 도구가 있는데 docker stats 명령어를 쓰면 실행 중인 컨테이너의 자원 사용량을 실시간으로 볼 수 있다.
또한, 외부 모니터링 도구를 사용해서 더 자세한 정보를 얻거나 여러 컨테이너의 데이터를 한눈에 볼 수도 있다.
이런 모니터링 정보를 통해 문제를 빨리 발견하고 해결할 수 있고 컨테이너를 효율적으로 관리하고 최적화할 수 있다.
Container 리소스 모니터링
docker stats: 모니터링의 시작점
- Docker stats는 Docker에서 제공하는 간단하고 실용적인 모니터링 도구로 이 명령어를 사용하면 현재 실행 중인 Docker 컨테이너들이 얼마나 많은 자원(CPU, 메모리 등)을 사용하고 있는지 실시간으로 볼 수 있다.
- docker stats라고 입력하기만 하면 사용할 수 있어 매우 실행이 간편하다
- 간편한 명령어 하나로 CPU 사용률, 메모리 사용량, 네트워크 I/O, 디스크 I/O 등 여러 중요한 정보를 알 수 있어 자주 사용된다.
- 해당 명령어를 실행하면, 실행 중인 모든 컨테이너의 상태가 표시되며 각 컨테이너의 이름, ID, CPU 사용량, 메모리 사용량 등이 실시간으로 업데이트되면서 나타난다
- 추가 팁
- 특정 컨테이너의 상태만 보고 싶다면, 컨테이너의 이름이나 ID를 명령어 뒤에 추가하면 된다
docker stats [컨테이너 이름 또는 ID]
htop: 시스템 모니터링의 필수 도구
- htop은 리눅스 시스템을 모니터링하는데 사용되는 강력한 도구로 일반적인 시스템 모니터와 비슷하지만 사용하기 편하고 여러 가지 유용한 기능을 제공한다.
- 컴퓨터의 CPU, 메모리 사용량 같은 중요한 정보를 실시간으로 볼 수 있어 컴퓨터가 어떻게 돌아가고 있는지, 어떤 프로세스가 많은 자원을 사용하고 있는지 알 수 있다.
- htop의 주요 기능은 아래와 같다
- 실시간 모니터링: CPU, 메모리, 스왑 사용량을 실시간으로 확인
- 프로세스 관리: 실행 중인 프로세스를 쉽게 확인하고 필요하면 종료 할 수 있음
- 사용자 친화적 인터페이스: 색상이 있는 그래픽과 간단한 조작으로 정보를 쉽게 읽을 수 있음
- 키보드 화살표를 사용해서 프로세스 목록을 넘겨볼 수 있고 F9를 눌러 프로세스를 종료할 수도 있다
# test-tools 이름으로 ubuntu:22.04 컨테이ㅓ 생성 및 실행
docker run --name test-tools -ti -d ubuntu:22.04
# 실행된 test-tools 컨테이너에 /bin/bash 명령을 실행(bash셀로 진입)
docker exec -ti test-tools /bin/bash
# apt 업데이트
apt update; apt upgrade -y; apt install htop -y;
# htop 실행
htop
exit
df
- disk free의 약자로 리눅스 시스템 전체의 디스크 사용량을 확인할 수 있다.
- -h 옵션을 입력해주면 단위를 읽기 쉬운단위로 변경해준다.
docker exec -ti test-tools /bin/bash
# -h 옵션을 사용하면 사람이 읽기 쉽게 단위를 변경함
df -h
exit
du
- 디렉토리 별로 사용 공간을 나타내준다
docker exec -ti test-tools /bin/bash
# 현재 디렉토리의 총 디스크 사용량을 GB 단위로 보여줌
du -sh
# 현재 디렉토리 한 단계 아래 디렉토리 까지만 사용량을 보여줌
du -h --max-depth=1
exit
Fluentd를 활용하여 특정 서버에서 데이터를 수집한 다음에 프로메테우스, 그라파나와 같은 툴을 활용하여 모니터링을 할 수 있다.
리눅스 명령어를 많이 사용하기 때문에 리눅스 명령어들을 공부해두는 것이 좋다.
Container 로깅
Docker는 모든 컨테이너 로그의 표준 출력(stdout) 또는 표준 에러(stderr)를 캡처하여 json-file 로깅 드라이버를 사용하여 json 형식으로 파일에 기록한다.
로그 파일의 위치
- Ubuntu 에서는 /var/lib/docker/containers/[컨테이너ID]/[컨테이너ID]-json.log에 위치한다.
특정 컨테이너의 로그 보기
docker run --name logs-test --rm -d ubuntu:22.04 /bin/bash -c 'while true; do date; sleep 1; done'
# logs-test 컨테이너의 로그를 전체 출력하기
docker logs logs-test
# logs-test 컨테이너의 로그를 tailing하기
docker logs -f logs-test
# 마지막 10줄부터 로그를 계속 보기
docker logs -f --tail 10 logs-test
로그 파일 설정 확인하기
docker inspect logs-test --format "{{.LogPath}}"
로그 로테이션 설정
- 실제로 운영하다 보면 로그 파일의 크기가 계속 커질 수 있기 때문에 로그 파일의 최대 크기와 최대 파일 개수를 지정한다.
- 아래의 명령은 최대 크기를 10m, 파일의 개수는 최대 10개가 되도록 설정하여 최신 nginx 컨테이너를 실행한다.
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=10 \
--name nginxtest \
--restart always \
-p 80:80 \
-p 443:443 \
nginx:latest
docker compose 파일에서도 동일한 설정을 적용할 수 있다
services:
app:
...
logging:
driver: 'json-file'
options:
max-size: '10m'
max-file: '10'
'인프라 > Docker, CI-CD' 카테고리의 다른 글
AWS 연동, Docker Volume, Docker Network, Docker Image 고급, Container 가상화 (0) | 2025.05.23 |
---|---|
Github Actions를 활용한 CI/CD 파이프라인 (0) | 2025.05.15 |
CI/CD란?, Docker 설치해보기, Docker Image와 Container (0) | 2025.05.14 |