면접들을 보면서, 내가 기존에 진행했던 프로젝트들에서 더 깊게 하지 못했던 아쉬운 부분들이 보였다. 무작정 지금 상태로 계속 지원하기보다는 기존 프로젝트에서 모자랐던 부분들을 채우고 포트폴리오의 양식도 블로그 글까지 가지 않아도 문제 해결과정이 잘 드러날 수 있도록 바꿔보려고 한다.
우선 아쉬웠던 부분들을 채우기 위해 기존 프로젝트를 개선해야 하는데 원래 로컬에서 띄워서 사용했던 Redis, Kafka, MongoDB, MySQL 그리고 모니터링 도구들을 도커로 띄워서 진행할 것이다.
기존에 사용하지 않았던 exporter 등도 있기 때문에 도커로 띄우는 과정을 정리해보려고 한다.
Docker-Compose 작성
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.5.0
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
kafka:
image: confluentinc/cp-kafka:7.5.0
ports:
- "9092:9092"
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
redis:
image: redis:7.2
ports:
- "6379:6379"
redis-exporter:
image: oliver006/redis_exporter
ports:
- "9121:9121"
environment:
REDIS_ADDR: redis:6379
kafka-exporter:
image: danielqsj/kafka-exporter
ports:
- "9308:9308"
environment:
KAFKA_SERVER: kafka:9092
mongodb:
image: mongo:6.0
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
loki:
image: grafana/loki:3.0.0
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:3.0.0
volumes:
- ./promtail-config.yaml:/etc/promtail/config.yaml
- /var/log:/var/log
command: -config.file=/etc/promtail/config.yaml
jaeger:
image: jaegertracing/all-in-one:1.53
ports:
- "16686:16686"
- "6831:6831/udp"
- "6832:6832/udp"
- "14268:14268"
- "14250:14250"
volumes:
mongo-data:
grafana-storage:
- Kafka, Zookeeper
- Kafka Exporter: Kafka 토픽/처리량 등을 Prometheus로 노출
- Redis
- Redis Exporter: Redis 메트릭 수집
- MongoDB
- Prometheus, Grafana
- Loki, Promtail
- Spring 로그 수집 - logback -> stdout -> Promtail -> Loki -> Grafana 조회
- Jaeger: Sleuth 기반 Trace/Span 시각화 도구
기존에 로컬 개발환경에서의 데이터를 이용하기 위해 MySQL은 로컬환경 그대로 사용하고, Redis나 MongoDB는 포트가 겹칠 수 있기 때문에 기존에 로컬에서 실행되던 환경을 중지시켜주었다.
Prometheus
volumes의 경로 설정을 통해 해당 경로를 컨테이너에 그대로 붙여 사용함.
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
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'spring-apps'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080', 'host.docker.internal:8081']
- job_name: 'redis'
static_configs:
- targets: ['redis-exporter:9121']
- job_name: 'kafka'
static_configs:
- targets: ['kafka-exporter:9308']
- job_name: 'mongodb'
static_configs:
- targets: ['mongodb:27017']
- job_name: 'loki'
static_configs:
- targets: ['loki:3100']
loki-config
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9095
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
chunk_idle_period: 5m
chunk_retain_period: 30s
max_transfer_retries: 0
schema_config:
configs:
- from: 2025-01-01
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
shared_store: filesystem
filesystem:
directory: /loki/chunks
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
max_look_back_period: 0s
table_manager:
retention_deletes_enabled: false
retention_period: 0s
- auth_enabled: 인증 활성화 여부
- server: Loki가 실행될 HTTP 및 gRPC 포트
- ingester: 로그 수집 후 메모리 내 처리 설정
- schema_config: 어떻게 로그를 저장하고 인덱싱할지 정의
- from: 설정을 언제부터 적용할 것인지
- store: 인덱스 정보를 어떻게 관리할 지 (boltdb-shipper는 파일 기반 인덱스 저장 방식)
- object_store: 실제 로그 데이터를 저장할 위치
- schema: 인덱싱 구조 버전
- limits_config: 수집 가능한 로그의 제약 조건 설정
- chunk_store_config: 저장된 로그에 대한 조회 범위
- table_manager: 보존 기간 설정
promtail-config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*.log
- job/labels: 그라파나에서 검색용 필터 조건으로 활용
실행
docker-compose 파일을 작성하고, 필요한 config 파일들을 모두 작성했다면, docker desktop을 실행하고 docker-compose 파일을 실행해주면 된다.
docker-compose 파일을 잘 실행했다면, 로컬에서 했던 것 처럼 각 포트 URL에 접근해서 잘 동작하는지 체크하면 된다.
대표적으로 위와 같이 http://localhost:9090/targets 에 들어가보면 spring, redis, kafka 등등이 제대로 실행되고 프로메테우스에 메트릭 정보들을 제대로 전송하는지 보고 오류가 있는지 알 수 있다.
down된 부분이 있다면 log를 확인해 수정해나가면 된다.