모니터링 grafana error

coc·2025년 10월 11일

에러

grafana     | logger=migrator t=2025-10-11T03:28:15.873597899Z level=info msg="Unlocking database"
grafana     | Error: ✗ migration failed (id = create user table): disk I/O error: permission denied

yml 변경전

services:
  prometheus: 
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus/config:/etc/prometheus
      - ./prometheus/volume:/prometheus
    ports:
      - 9090:9090
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    restart: always
    networks:
      - promnet
  grafana: 
    image: grafana/grafana
    container_name: grafana
    ports:
      - 3000:3000
    volumes:
      - ./grafana/volume:/var/lib/grafana # 변경 전
    user: root
    restart: always
    networks:
      - promnet
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
networks:
  promnet:
    driver: bridge

yml 변경후

services:
  prometheus: 
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus/config:/etc/prometheus
      - ./prometheus/volume:/prometheus
    ports:
      - 9090:9090
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    restart: always
    networks:
      - promnet
  grafana: 
    image: grafana/grafana
    container_name: grafana
    ports:
      - 3000:3000
    volumes:
      - grafana-data:/var/lib/grafana # 변경된 부분
    restart: always
    networks:
      - promnet
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

networks:
  promnet:
    driver: bridge

volumes: # 추가된 부분
  prometheus-data:
  grafana-data:

문제원인

volumes:
  - ./grafana/volume:/var/lib/grafana  # 호스트 경로 마운트

Windows에서 발생하는 문제:
1. 파일 시스템 차이

  • Windows는 NTFS/FAT32 파일 시스템 사용
  • Linux 컨테이너는 ext4 같은 Linux 파일 시스템 기대
  • SQLite는 파일 잠금(file locking)에 민감한데, Windows 파일 시스템이 Linux 스타일의 파일 잠금을 제대로 지원하지 못함
  1. 권한 시스템 불일치
  • Linux: UID/GID 기반 권한 (예: 472:472)
  • Windows: ACL(Access Control List) 기반
  • Docker Desktop이 이를 변환하는 과정에서 권한 문제 발생
  1. I/O 작업 처리 방식
  • Windows 파일 시스템을 통한 I/O는 Docker Desktop의 변환 레이어를 거침
  • SQLite의 fsync() 같은 저수준 디스크 동기화 작업이 제대로 작동하지 않음
  • 결과: "disk I/O error: permission denied"

현재 방식이 성공한 이유

volumes:
  - grafana-data:/var/lib/grafana  # Named volume

volumes:
  grafana-data:  # Docker가 관리하는 볼륨

왜 이게 작동하는가:
1. 순수 Linux 환경

  • Named volume은 Docker Desktop 내부의 Linux VM에 저장됨
  • Windows 파일 시스템을 거치지 않고 순수 Linux 환경에서 동작
  • 위치: \wsl$\docker-desktop-data\data\docker\volumes\
  1. 파일 시스템 일치
  • 이전: Windows NTFS → Docker 변환 레이어 → Linux Container
  • 현재: Linux VM 내부 → Linux Container (직접 연결)
  1. 권한 문제 없음
  • Docker가 볼륨을 생성할 때 올바른 권한으로 자동 설정
  • Linux 컨테이너가 Linux 파일 시스템에 직접 접근
  1. SQLite 호환성
  • SQLite의 파일 잠금이 제대로 작동
  • fsync() 같은 동기화 작업이 정상 실행
  • 트랜잭션 안정성 보장

시각적 비교

❌ 호스트 경로 마운트 (실패)
┌─────────────────────────────────────────┐
│ Windows Host (NTFS) │
│ ./grafana/volume │
│ ↓ │
│ [Docker Desktop 변환 레이어] │
│ ↓ (권한/파일시스템 변환 문제) │
│ Linux Container │
│ Grafana + SQLite │
│ ↓ │
│ 💥 disk I/O error │
└─────────────────────────────────────────┘
✅ Named Volume (성공)
┌─────────────────────────────────────────┐
│ Docker Desktop Linux VM │
│ /var/lib/docker/volumes/grafana-data │
│ ↓ (직접 연결, 변환 없음) │
│ Linux Container │
│ Grafana + SQLite │
│ ↓ │
│ ✓ 정상 동작 │
└─────────────────────────────────────────┘

결론

Windows에서 Docker를 사용할 때는 데이터베이스나 I/O가 많은 애플리케이션의 경우 반드시 Named Volume을 사용해야 한다. 호스트 경로 마운트는 설정 파일처럼 읽기가 주된 파일에만 사용하는 것이 좋다.
현재 설정에서도 Prometheus의 ./prometheus/config는 호스트 경로를 사용하는데, 이건 설정 파일(읽기 전용)이라 문제가 없다!

profile
시작

0개의 댓글