◾️ 구성도
Grafana와 Loki에서 각 서버의 syslog 및 journal, static log를 송신하고자 한다.
서버 예상 구성도는 아래와 같다.
◾️ 서버별 구현 목표
▪️ 모니터링 서버
- Grafana
- Dashboard
- Loki
- log를 적재하고 query문을 통해 read (tcp: 3100)
- Promtail
- syslog를 타 서버에서 전송할 수 있도록 receiver 역할을 함 (tcp: 1514)
- localhost의 journal을 loki에 전송
- localhost의 static log를 loki에 전송
▪️ 클라이언트 서버
- Promtail
- localhost의 journal을 loki에 전송
- localhost의 static log를 loki에 전송
- rsyslog
- syslog를 타 서버에 전송하는 역할을 수행.
◾️ 사전 준비
모니터링 서버 / 클라이언트 서버에는 모두 Docker, Docker-Compose가 설치 되어있어야 한다.
설치 방법은 아래 링크 참고
(CentOS 7에서 도커 설치하기 - WTT)
로그 서버 구축 전 모니터링 서버에서 rsyslog.conf 파일을 수정해주어야 한다.
$ cat /etc/rsyslog.conf
...
$template RemoteLogs, "/var/log/remote/%$YEAR%-%$MONTH%-%$DAY%.log"
*.* ?RemoteLogs
#### GLOBAL DIRECTIVES ####
관련 포맷은 rsyslog 서버 구축하기 - WTT 게시글을 참고하도록 하자.
대충 설명하자면 rsyslog 로그들을 /var/log/remote 경로 하위에 2023-01-01.log
형식으로 로그 파일을 생성하겠다는 의미이다.
(localhost 로그 및 클라이언트 서버들의 로그가 2023-01-01.log
파일에 기록된다. // 물론 클라이언트 서버의 rsyslog.conf 파일에 마스터 서버 IP가 기록되어 있어야 한다. 해당 내용은 위 링크 내용을 참고하도록 하자.)
위처럼 /etc/rsyslog.conf 파일을 수정하였으면 rsyslog 서비스를 재시작하자.
sudo systemctl restart rsyslog
◾️ 구성 진행
Reference
- https://grafana.com/docs/loki/latest/send-data/promtail/scraping/#rsyslog-output-configuration
- https://grafana.com/docs/loki/latest/send-data/promtail/configuration/#syslog
▪️ 모니터링 서버
1. loki에서 사용할 volume 생성. loki 컨테이너의 경우 user가 uid: 10001
이므로 생성한 volume의 소유권을 10001로 변경하여야 함.
mkdir -p /loki/config
chown 10001:10001 /loki
미 변경 시 loki 컨테이너가 정상적으로 생성되지 않음.
'Permission denied' 에러가 뜨므로, 사전에 호스트에서 생성한 볼륨의 소유권을 미리 변경해주도록 하자.
2. 공식 홈페이지에서 docker-compose.yaml 파일과 loki-config.yaml, promtail-config.yaml 파일을 다운로드 받자.
(https://grafana.com/docs/loki/latest/get-started/)
cd /loki
wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/cmd/loki/loki-local-config.yaml -O config/loki-config.yaml
wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/cmd/promtail/promtail-docker-config.yaml -O config/promtail-config.yaml
wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/production/docker-compose.yaml -O docker-compose.yaml
• loki-config
- 내용을 사용자의 환경에 맞게 수정
table_manager를 설정하여 2주 정도의 log만 보관되도록 설정
# cat /loki/config/loki-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
ingester:
wal:
enabled: true
dir: /tmp/wal
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 1h # Any chunk not receiving new logs in this time will be flushed
max_chunk_age: 1h # All chunks will be flushed when they hit this age, default is 1h
chunk_target_size: 1048576 # Loki will attempt to build chunks up to 1.5MB, flushing first if chunk_idle_period or max_chunk_age is reached first
chunk_retain_period: 30s # Must be greater than index read cache TTL if using an index cache (Default index read cache TTL is 5m)
max_transfer_retries: 0 # Chunk transfers disabled
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /tmp/loki/boltdb-shipper-active
cache_location: /tmp/loki/boltdb-shipper-cache
cache_ttl: 24h # Can be increased for faster performance over longer query periods, uses more disk space
shared_store: filesystem
filesystem:
directory: /tmp/loki/chunks
compactor:
working_directory: /tmp/loki/boltdb-shipper-compactor
shared_store: filesystem
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
ruler:
storage:
type: local
local:
directory: /tmp/loki/rules
rule_path: /tmp/loki/rules-temp
alertmanager_url: http://localhost:9093
ring:
kvstore:
store: inmemory
enable_api: true
• promtail-config
- 내용을 사용자의 환경에 맞게 수정
syslog receive와 journal 및 static log 설정
# cat /loki/config/promtail-config.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: jhtest
static_configs:
- targets:
- localhost
labels:
job: jhtest
__path__: /var/log/remote/*log
- job_name: syslog
syslog:
listen_address: 0.0.0.0:1514
labels:
job: "syslog"
relabel_configs:
- source_labels: ["__syslog_connection_ip_address"]
target_label: "ip_address"
- source_labels: ["__syslog_message_severity"]
target_label: "severity"
- source_labels: ["__syslog_message_facility"]
target_label: "facility"
- source_labels: ["__syslog_message_app_name"]
target_label: "app_name"
- source_labels: ["__syslog_message_hostname"]
target_label: "host"
- job_name: journal
journal:
max_age: 12h
labels:
job: systemd-journal
relabel_configs:
- source_labels: ["__journal__systemd_unit"]
target_label: "systemd_unit"
- source_labels: ["__journal__hostname"]
target_label: "nodename"
- source_labels: ["__journal_syslog_identifier"]
target_label: "syslog_identifier"
💡 __path__ 경로!
해당 경로는 /etc/rsyslog.conf에서 설정한 로그가 기록되는 path를 지정해준 것이다. 관련 내용은 Section: 사전 준비를 참고하자.
💡 clients.url 주소!
해당 주소에서 사용되는
http://loki:3100...
loki의 경우 loki 컨테이너 주소를 의미한다. docker-compose.yaml에 정의된 loki 컨테이너의 주소를 도커 네트워크가 찾아서 3100번 포트로 연결시킨다.
• docker-compose.yaml
- 내용을 사용자의 환경에 맞게 수정
Host의 /loki
경로에 모든 data가 수집되도록 마운트 경로를 잡아주자.
# cat docker-compose.yaml
version: "3.8"
services:
loki:
image: grafana/loki
restart: always
volumes:
- type: bind
source: '/loki/config'
target: '/mnt/config'
- type: bind
source: '/loki'
target: '/loki'
ports:
- "3100:3100"
command: -config.file=/mnt/config/loki-config.yaml
container_name: gafana-loki
networks:
- 'loki-net'
promtail:
image: grafana/promtail
restart: always
ports:
- "1514:1514"
volumes:
- type: bind
source: '/var/log'
target: '/var/log'
- type: bind
source: '/loki/config'
target: '/mnt/config'
- type: bind
source: '/var/log/journal/'
target: '/var/log/journal/'
- type: bind
source: '/run/log/journal/'
target: '/run/log/journal/'
- type: bind
source: '/etc/machine-id'
target: '/etc/machine-id'
command: -config.file=/mnt/config/promtail-config.yaml
container_name: loki-promtail
networks:
- 'loki-net'
grafana:
container_name: grafana
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- type: volume
source: "grafana-db"
target: "/var/lib/grafana"
networks:
- 'loki-net'
volumes:
grafana-db: {}
networks:
loki-net:
driver: bridge
external: false
• 컨테이너 실행
$ docker-compose up -d --build
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
38d2a266cc22 grafana/grafana:latest "/run.sh" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp grafana
7d5c0c8b2e7a grafana/loki "/usr/bin/loki -conf…" 3 minutes ago Up 3 minutes 0.0.0.0:3100->3100/tcp, :::3100->3100/tcp gafana-loki
e382dad4bea3 grafana/promtail:latest "/usr/bin/promtail -…" 3 minutes ago Up 3 minutes 0.0.0.0:1514->1514/tcp, :::1514->1514/tcp loki-promtail
서버쪽 설정은 끝이났다
▪️ Client 서버
Redhat 계열 배포판인 경우 SELinux
를 disable 시켜주도록 하자. 관련 내용은 아래 링크를 참조
(SELinux 비활성화 - WTT)
/etc/rsyslog.conf 파일에 아래 내용을 추가하자. (target
, port
들은 사용자 환경에 맞게 수정하면 된다.)
$ vi /etc/rsyslog.conf
...
action(type="omfwd" protocol="tcp" target="192.168.121.149" port="1514" Template="RSYSLOG_SyslogProtocol23Format" TCP_Framing="octet-counted")
#### GLOBAL DIRECTIVES ####
rsyslog 재기동
$ systemctl restart rsyslog
promtail에서 사용할 디렉토리 생성
$ mkdir -p /loki/config
promtail-config.yaml, docker-compose.yaml 파일 다운로드 받기
# /loki 디렉토리로 이동
$ cd /loki
# 파일 다운로드
$ wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/cmd/promtail/promtail-docker-config.yaml -O config/promtail-config.yaml
$ wget https://raw.githubusercontent.com/grafana/loki/v2.2.1/production/docker-compose.yaml -O docker-compose.yaml
• promtail-config
- 내용을 사용자의 환경에 맞게 수정
/loki/config/promtail-config.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /positions.yaml
clients:
- url: http://192.168.121.149:3100/loki/api/v1/push
scrape_configs:
- job_name: yjwang
static_configs:
- targets:
- localhost
labels:
job: yjwangtest
__path__: /var/log/yjwang/*/*log
- job_name: journal
journal:
max_age: 12h
labels:
job: systemd-journal
relabel_configs:
- source_labels: ["__journal__systemd_unit"]
target_label: "systemd_unit"
- source_labels: ["__journal__hostname"]
target_label: "nodename"
- source_labels: ["__journal_syslog_identifier"]
target_label: "syslog_identifier"
💡 clients.url 주소!
모니터링 서버의 IP 주소를 기입해주면 된다.
• docker-compose.yaml
- 내용을 사용자의 환경에 맞게 수정
/loki/docker-compose.yaml
version: "3.8"
services:
promtail:
image: grafana/promtail
restart: always
volumes:
- type: bind
source: "/var/log"
target: "/var/log"
- type: bind
source: "/loki/config"
target: "/mnt/config"
- type: bind
source: "/var/log/journal"
target: "/var/log/journal/"
- type: bind
source: "/run/log/journal/"
target: "/run/log/journal/"
- type: bind
source: "/etc/machine-id"
target: "/etc/machine-id"
command: -config.file=/mnt/config/promtail-config.yaml
container_name: loki-promtail
networks:
- 'loki-net'
networks:
loki-net:
driver: bridge
external: false
• 컨테이너 실행
docker-compose up -d --build
docker-compose ps
▪️ Grafana에서 테스트
http://<서버_IP>:3000
으로 접속
기본 암호는 admin/admin
이다.
로그인 후 Data Sources에 들어간 후 아래와 같이 추가해주도록 하자.
(URL: http://<loki_서버IP>:3100 또는 URL: http://<loki_컨테이너명>:3100
)
Loki Data Source가 정상적으로 추가되었다면, Explore 메뉴에 들어가서 Log가 정상적으로 수집되는지 관찰하자.
Labels filter를 filename으로 변경하고 'Run Query'를 클릭하자.
그럼 아래와 같이 로그 모니터링이 가능해진다.