Container Monitoring
컨테이너 모니터링
개요
이번 포스팅에서는 컨테이너 모니터링에 대해서 살펴보려고 한다. 모니터링 환경은 시스템을 운영하는 데 있어 없어서는 안될 부분이다. 모니터링은 로그, 지표 수집, 경보를 모두 고려해야 한다. 이 포스팅에서는 docker-compose 로 구성된 컨테이너 환경을 기반으로 로깅, 지표 수집을 어떻게 하는지 살펴볼 것이다. 테스트 목적의 구성이므로 프로덕션에서 사용하려면 하드웨어 구성에 따라 옵션을 조정해가면서 적합 여부를 테스트해보기 바란다.
도커 컨테이너 로깅
로깅 드라이버가 설정되지 않은 경우 기본적으로 json-file
로깅 드라이버를 사용한다. 호스트 파일 시스템에 계속해서 기록되며, docker logs
커맨드를 통해
로그를 조회할 수 있다.
아래와 같이 몇 가지 기본 드라이버가 제공되며, 직접 구현할 수도 있다.
- syslog
- gelf
- fluentd
- awslogs
- splunk
- etwlogs
- gcplogs
- Logentries
- local
- json-file
- journald
이 중에서 도커 커뮤니티 에디션에서 docker logs
커맨드로 로그를 조회할 수 있는 드라이버는 local
, json-file
, journald
뿐이다. 커뮤니티 에디션을
사용하면 로그를 확인하는 부분이 불편할 것 같지만 사실 전혀 불편하지 않다. 컨테이너를 구동하는 핵심 기능과 성능 면에서 커뮤니티 에디션과 엔터프라이즈 에디션은 큰 차이가
없으니 참고하기 바란다.
여러 호스트 서버에 접속해서 일일이 로그를 확인하기는 번거롭기 때문에 로그를 중앙으로 수집할 필요가 있다. 이때 일반적으로 사용할 수 있는 드라이버가 fluentd
,
splunk
가 될 수 있다. 이 포스팅에서는 여러 책에서 많이 언급된 fluentd
로깅 드라이버를 사용해서 살펴보기로 한다.
로그 수집
fluentd 데몬을 호스트 머신에 각각 구성하고, 일래스틱서치로 로그를 전달하는 방식을 사용했다.
로그를 수집하길 원하느 서비스 컨테이너의 docker-compose.yml 파일에는 서비스 속성에 다음과 추가하면 된다. 그리고 로깅드라이버 설정과는 별도로 애플리케이션 로그는 볼륨 마운트를 통해 호스트 볼륨에 퍼시스턴스하기 바란다.
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
tag: log.zk-1
일래스틱서치로 로그를 전달하려면 fluentd 컨테이너에 fluentd 플러그인을 설치해야한다. 다음과 같이 Dockerfile
을 만들어 도커 이미지를 만들어 놓을 수 있다.
# fluentd/Dockerfile
FROM fluent/fluentd:v1.6-debian-1
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "3.5.2"]
USER fluent
사설 컨테이너 레지스트리가 있다면 그것을 사용하도록 한다. 다음은 레지스트리에 푸시된 test/fluentd-es-plug:v1.6-debian-1
이라는 이미지를 사용하여
docker-compose.yml
컴포즈 파일을 구성한 모습이다. 이 fuentd
컨테이너는 호스트당 하나만 띄우면 된다.
version: '3'
services:
fluentd:
image: test/fluentd-es-plug:v1.6-debian-1
ports:
- 24224:24224
- 24224:24224/udp
environment:
- TZ=Asia/Seoul
extra_hosts:
- 'elasticsearch:172.26.0.100'
volumes:
- ./fluentd/conf:/fluentd/etc:ro
extra_hosts
속성에 있는 일래스틱서치 호스트 IP 를 적절하게 변경하기 바란다. 그리고 fluentd.conf
설정파일을 다음과 같이 생성한다.
# fluentd/conf/fluent.conf
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match *.**>
@type copy
<store>
@type elasticsearch
host elasticsearch
port 9200
user elastic
password 1234
logstash_format true
logstash_prefix fluentd
logstash_dateformat %Y%m%d
include_tag_key true
type_name container_log
tag_key @log_name
reconnect_on_error true
reload_on_failure true
reload_connections false
flush_interval 1s
</store>
<store>
@type stdout
</store>
</match>
일래스틱서치의 docker-compose.yml
구성은 다음과 같다.
version: '3'
services:
elasticsearch:
image: elasticsearch:7.6.1
ports:
- 9200:9200
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xmx1G
- xpack.security.enabled=true
- ELASTIC_PASSWORD=1234
- TZ=Asia/Seoul
ulimits:
memlock:
soft: -1
hard: -1
# volumes:
# - ./volume/es/data:/usr/share/elasticsearch/data
kibana:
image: kibana:7.2.0
environment:
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=1234
- TZ=Asia/Seoul
키바나를 통해 수집된 로그를 확인할 수 있다.
이로써 로그 수집 부분은 완료되었으며, 지표 수집 부분을 살펴보도록 하자.
지표 수집
지표 수집은 다음과 같이 두 가지로 나눌 수 있다. 이 지표는 CPU 사용량, 메모리 사용량, 네트워크 RX 및 TX 등의 중요 지표를 포함한다.
- 컨테이너 지표 수집
- 호스트 지표 수집
컨테이너 지표 수집에는 cAdvisor
를 사용하고, 호스트 지표 수집은 node-exporter
를 사용한다. 대략적인 구성도는 다음과 같다.
fluentd
와 마찬가지로 호스트당 컨테이너 하나를 띄우면 된다.
version: '3'
services:
cadvisor:
image: gcr.io/google-containers/cadvisor:v0.36.0
ports:
- 8180:8080
user: 0:0
privileged: true
environment:
- TZ=Asia/Seoul
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
node-exporter:
image: prom/node-exporter:v0.18.1
ports:
- 9100:9100
프로메테우스와 그라파나가 구성된 docker-compose.yml
파일은 다음과 같이 구성하면 된다.
version: '3'
services:
grafana:
image: grafana/grafana:6.7.1
ports:
- 3000:3000
environment:
- TZ=Asia/Seoul
# volumes:
# - ./volume/grafana/data:/var/lib/grafana
# - ./volume/grafana/logs:/var/log/grafana
# - ./volume/grafana/conf:/etc/grafana
prometheus:
image: prom/prometheus:v2.16.0
command:
- --config.file=/etc/prometheus/prometheus.yaml
environment:
- TZ=Asia/Seoul
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
prometheus.yaml
설정파일은 다음과 같이 생성하기 바란다. targets
에 지표수집 대상이 되는 호스트 목록을 추가하면 된다.
scrape_configs:
- job_name: monitor
scrape_interval: 5s
static_configs:
- targets:
# service
- 172.26.0.100:8180
- 172.26.0.101:9100
모두 정상적으로 구성되었다면, 그라파나를 통해 지표 모니터링을 시작할 수 있다.
경보
기본적으로 일래스틱서치는 경보 옵션을 제공하지 않는다. 유료 옵션을 구매해야 하는데, 그러지 않고도 로그에 기반하여 경보를 받을 수 있는 수단이 존재한다.
elastalert
이라는 도구를 사용하면 되며, 슬랙, 팀즈 같이 대중적으로 사용되는 채널들을 폭넓게 지원하고, 경보 폭탄을 받지 않도록 설정을 조절할 수 있는 장점이
있다.
마무리
비즈니스에서 장애는 치명적이고, 빠르게 복구되어야 한다. 따라서 문제를 빠르게 추적하고 현상을 이해하기 위해 로그 모니터링 시스템을 잘 구성하고 유지해야 한다.