Profile picture

[Docker] rsyslog, journal 로그 Grafana로 연동하기

JaehyoJJAng2024년 02월 20일

◾️ 구성도

Grafana와 Loki에서 각 서버의 syslog 및 journal, static log를 송신하고자 한다.
서버 예상 구성도는 아래와 같다.
image


◾️ 서버별 구현 목표

▪️ 모니터링 서버

  • 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


▪️ 모니터링 서버

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 ####

image


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)
image
image


Loki Data Source가 정상적으로 추가되었다면, Explore 메뉴에 들어가서 Log가 정상적으로 수집되는지 관찰하자.
image
Labels filter를 filename으로 변경하고 'Run Query'를 클릭하자.


그럼 아래와 같이 로그 모니터링이 가능해진다.
image


Loading script...