Docker_Cloudwave캠프: Stateful 컨테이너와 로그 파이프라인

1. Stateful 컨테이너의 특성

일반적인 API 서버는 stateless 구조이므로 컨테이너가 삭제되고 새로 생성되어도 문제가 없다.
하지만 데이터베이스와 같은 stateful 서비스는 다음 두 가지 조건이 반드시 필요하다.

1) 데이터의 지속성

  • 컨테이너가 삭제되거나 재생성되어도 데이터는 유지되어야 한다.
  • 이를 위해 볼륨(Volume) 또는 Bind Mount를 사용한다.

2) 고유한 식별자

  • 클러스터 환경에서 여러 개의 DB 인스턴스가 실행될 경우
  • 각 인스턴스는 자신만의
    • 고유한 스토리지(볼륨)
    • 고유한 네트워크 식별자
      를 가져야 한다.
  • 그렇지 않으면 데이터 충돌 또는 덮어쓰기 문제가 발생한다.

2. Host → Container Bind Mount 개념

Bind Mount의 목적

컨테이너 이미지 안에 소스코드를 포함하지 않고,
호스트의 파일 시스템을 컨테이너에 직접 연결한다.

이 방식의 장점은 다음과 같다.

  • 소스코드를 이미지 밖에서 관리 가능
  • 소스 수정 시 이미지 재빌드 불필요
  • 즉시 컨테이너에 변경 사항 반영

3. Bind Mount 실행 명령어 분석

 
docker run --name bind -p 80:80 -v <FOLDER_PATH> \app:/code/app was:fast.1

명령어 구성 요소

  1. docker run
    • 새로운 컨테이너를 생성하고 실행하는 명령어
    • 이미지 → 실행 중인 컨테이너 단계
  2. --name bind
    • 컨테이너 이름을 bind로 지정
    • 이후 관리 및 디버깅 시 편의성 향상
  3. -p 80:80
    • 포트 포워딩 설정
    • 호스트 80번 포트를 컨테이너 80번 포트로 연결
  4. -v <FOLDER_PATH>\app:/code/app
    • Bind Mount 설정
    • 호스트의 app 디렉토리를 컨테이너의 /code/app에 연결
    • 두 경로는 실시간으로 동기화됨
  5. was:fast.1
    • 실행할 Docker 이미지 이름

4. Docker 기반 로그 시스템 구축 실습 개요

실습 목적

여러 Docker 컨테이너에서 발생하는 로그를 중앙에서 수집하고 조회할 수 있는 로그 시스템을 구축한다.

기존 방식의 문제점:

  • docker logs 명령으로 컨테이너별 로그를 개별 확인해야 함

실습 목표:

  • 로그 수집, 저장, 조회 과정을 하나의 파이프라인으로 이해

5. 로그 시스템 전체 구조

로그 흐름

Docker 컨테이너 로그
→ Promtail (로그 수집)
→ Loki (로그 저장 및 검색)
→ Grafana (로그 조회 UI)


6. 구성 요소 역할

Promtail

  • 실행 중인 Docker 컨테이너의 로그를 수집
  • Docker 엔진과 통신하여 컨테이너 자동 탐색
  • 수집한 로그를 Loki로 전송

Loki

  • 로그 전용 저장 및 검색 서버
  • Promtail이 전송한 로그를 저장
  • Grafana의 로그 쿼리 요청을 처리

Grafana

  • Loki에 저장된 로그를 조회하는 웹 UI
  • 브라우저 기반 로그 검색 및 시각화 제공

observe 네트워크

  • Docker bridge 네트워크
  • 같은 네트워크에 속한 컨테이너 간 내부 통신 제공
  • 컨테이너 이름을 DNS 이름처럼 사용 가능

7. Docker 네트워크 핵심 개념

Bridge 네트워크 특성

  • 같은 네트워크에 있는 컨테이너는 내부 통신 가능
  • 컨테이너 이름이 내부 DNS 이름으로 동작

예시:

  • observe 네트워크 내에서
    • loki → 자동으로 IP로 변환됨
  • loki는 인터넷 도메인이 아님
  • Docker가 내부적으로 제공하는 이름이며 같은 네트워크에서만 유효

8. localhost의 정확한 의미

컨테이너에서 localhost는 항상 “자기 자신”을 의미한다.

예시:

  • Grafana 컨테이너에서 localhost:3100 접근
    • Grafana 자기 자신을 가리킴
    • Loki 컨테이너에는 접근 불가

올바른 접근 방식:

  • Grafana → Loki 연결 시
  •  
    http://loki:3100
  •  

9. Bind Mount의 실습 활용

이 실습에서는 설정 파일을 컨테이너 내부에 직접 만들지 않는다.

Bind Mount로 주입한 파일:

  • loki-config.yaml
  • promtail-docker.yaml

장점:

  • 설정 파일을 호스트에서 수정 가능
  • 컨테이너 재생성 없이 설정 변경 가능

10. docker.sock의 역할

docker.sock은 Docker 엔진과 통신하는 소켓 파일이다.

Promtail이 docker.sock을 사용하는 이유:

  • 실행 중인 컨테이너 목록 조회
  • 컨테이너 로그 위치 파악

docker.sock이 없을 경우:

  • Promtail은 컨테이너 정보를 알 수 없음
  • 로그 수집 불가능

11. 설정 파일 역할 정리

loki-config.yaml

  • Loki 서버 설정 파일
  • 주요 특징
    • 3100 포트에서 로그 수신
    • 파일 시스템 기반 로그 저장
    • 단일 인스턴스 구성
    • 인증 비활성화

역할:

  • 로그 저장 및 검색 서버 설정

promtail-docker.yaml

  • Promtail 설정 파일
  • Docker Service Discovery 사용
  • docker.sock을 통해 컨테이너 자동 탐색
  • 컨테이너 이름을 라벨로 로그에 포함

역할:

  • Docker 로그 수집기 설정

12. 실습에 사용한 핵심 명령어

Docker 네트워크 생성

 
docker network create --driver bridge observe

Loki 실행

docker run -d --name loki --network observe -v ./loki-config.yaml:/mnt/config/loki-config.yaml grafana/loki:3.4.1
--config.file=/mnt/config/loki-config.yaml

Promtail 실행

docker run -d --name promtail --network observe -v ./promtail-docker.yaml:/mnt/config/promtail-docker.yaml
-v /var/run/docker.sock:/var/run/docker.sock grafana/promtail:3.4.1 --config.file=/mnt/config/promtail-docker.yaml

Grafana 실행

docker run -d --name grafana --network observe -p 3000:3000 -e GF_SECURITY_ADMIN_USER=admin
-e GF_SECURITY_ADMIN_PASSWORD=admin grafana/grafana:12.3.1

13. 상태 확인 명령어

컨테이너 실행 상태:

 
docker ps

네트워크 연결 확인:

 
docker network inspect observe

Promtail → Loki 연결 상태:

 
docker logs promtail --since 2m

에러가 없으면 정상

Loki 상태 확인:

 
docker exec -it loki curl http://localhost:3100/ready

ready 출력 시 정상

Grafana → Loki 통신 확인:

 
docker exec -it grafana curl http://loki:3100/ready

14. Docker Build 관련 개념 정리

commit

  • 디버깅용으로 임시 이미지 생성 시 사용
  • 실무 build 과정에서는 사용하지 않음

docker build

 
docker build -f <Dockerfile> .
  • . 은 build context
  • Dockerfile 내부의 상대경로 해석 기준점

이미지와 태그

  • 하나의 태그는 하나의 이미지에만 매핑됨
  • 서로 다른 아키텍처를 하나의 태그로 지원할 수 없음

buildx

  • 여러 아키텍처용 이미지를 동시에 생성 가능
  • 하나의 태그 안에 여러 아키텍처 지원 (Multi-Arch Image)