[Docker / 모니터링] rsyslog, journal 로그 Grafana로 연동하기

◾️ 구성도

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

관련 글