Docker Swarm 모니터링

Docker Swarm 모니터링 (Monitoring Docker Swarm)

Prometheus는 v2.20.0부터 Docker Swarm 클러스터에서 대상을 발견할 수 있어요. 이 문서는 그 서비스 디스커버리 메커니즘을 사용하는 방법을 보여줍니다. Docker 데몬 자체의 메트릭과, Swarm에 배포된 컨테이너(cAdvisor 등)를 자동으로 스크레이프하는 설정을 다룹니다.

dockerswarm_sd_config에는 nodes, services, tasks 세 가지 역할이 있고, relabel_configs로 원하는 대상만 골라내는 패턴이 핵심이에요.

출처: 문서

본문

Prometheus는 v2.20.0부터 Docker Swarm 클러스터에서 대상을 발견할 수 있습니다. 이 문서는 그 서비스 디스커버리 메커니즘을 사용하는 방법을 보여줍니다.

Docker Swarm 서비스 디스커버리 아키텍처

Docker Swarm 서비스 디스커버리nodes, services, tasks의 3가지 역할을 포함합니다.

  • 첫 번째 역할 nodes는 Swarm의 일부인 호스트를 나타냅니다. Swarm 호스트에서 실행되는 Docker 데몬이나 Node Exporter를 자동으로 모니터링하는 데 사용할 수 있습니다.
  • 두 번째 역할 tasks는 Swarm에 배포된 개별 컨테이너를 나타냅니다. 각 task는 연관된 서비스 라벨을 가집니다. 하나의 서비스는 하나 또는 여러 개의 task로 뒷받침될 수 있습니다.
  • 세 번째 것 services는 Swarm에 배포된 서비스를 발견합니다. 서비스가 노출하는 포트를 발견합니다. 보통은 이것보다 tasks 역할을 쓰는 것이 좋습니다.

Prometheus는 포트를 노출하는 task와 service만 발견합니다.

참고: 이 문서의 나머지 부분은 실행 중인 Swarm이 있다고 가정합니다.

Prometheus 설정

이 가이드에서는 Prometheus를 설정해야 합니다. Prometheus가 Docker Swarm 매니저 노드에서 실행되고 /var/run/docker.sock의 Docker 소켓에 접근할 수 있다고 가정합니다.

Docker 데몬 모니터링

서비스 디스커버리 자체를 살펴보겠습니다.

Docker 자체는 데몬으로서 Prometheus 서버가 수집할 수 있는 메트릭을 노출합니다.

/etc/docker/daemon.json을 편집하고 다음 속성을 설정해 활성화할 수 있습니다:

{
  "metrics-addr" : "0.0.0.0:9323",
  "experimental" : true
}

0.0.0.0 대신 Docker Swarm 노드의 IP를 설정할 수 있습니다. 새 구성을 적용하려면 데몬을 재시작해야 합니다.

Docker 문서에 이에 대한 자세한 내용이 있습니다.

그런 다음 다음 prometheus.yml 파일을 제공해 Prometheus가 Docker 데몬을 스크레이프하도록 구성할 수 있습니다:

scrape_configs:
  # Make Prometheus scrape itself for metrics.
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  # Create a job for Docker daemons.
  - job_name: 'docker'
    dockerswarm_sd_configs:
      - host: unix:///var/run/docker.sock
        role: nodes
    relabel_configs:
      # Fetch metrics on port 9323.
      - source_labels: [__meta_dockerswarm_node_address]
        target_label: __address__
        replacement: $1:9323
      # Set hostname as instance label
      - source_labels: [__meta_dockerswarm_node_hostname]
        target_label: instance

nodes 역할에서는 dockerswarm_sd_configsport 파라미터를 사용할 수도 있습니다. 하지만 relabel_configs를 사용하는 것이 권장되는데, Prometheus가 동일한 Docker Swarm 구성에서 동일한 API 호출을 재사용할 수 있게 해주기 때문입니다.

컨테이너 모니터링 (Monitoring Containers)

이제 Swarm에 서비스를 배포해봅시다. 컨테이너 리소스 메트릭을 노출하는 cadvisor를 배포합니다:

docker service create --name cadvisor -l prometheus-job=cadvisor \
    --mode=global --publish target=8080,mode=host \
    --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock,ro \
    --mount type=bind,src=/,dst=/rootfs,ro \
    --mount type=bind,src=/var/run,dst=/var/run \
    --mount type=bind,src=/sys,dst=/sys,ro \
    --mount type=bind,src=/var/lib/docker,dst=/var/lib/docker,ro \
    google/cadvisor -docker_only

이것을 모니터링하는 최소한의 prometheus.yml 파일입니다:

scrape_configs:
  # Make Prometheus scrape itself for metrics.
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  # Create a job for Docker Swarm containers.
  - job_name: 'dockerswarm'
    dockerswarm_sd_configs:
      - host: unix:///var/run/docker.sock
        role: tasks
    relabel_configs:
      # Only keep containers that should be running.
      - source_labels: [__meta_dockerswarm_task_desired_state]
        regex: running
        action: keep
      # Only keep containers that have a `prometheus-job` label.
      - source_labels: [__meta_dockerswarm_service_label_prometheus_job]
        regex: .+
        action: keep
      # Use the prometheus-job Swarm label as Prometheus job label.
      - source_labels: [__meta_dockerswarm_service_label_prometheus_job]
        target_label: job

relabel 구성의 각 부분을 분석해보겠습니다.

- source_labels: [__meta_dockerswarm_task_desired_state]
  regex: running
  action: keep

Docker Swarm은 API를 통해 작업의 원하는 상태(desired state)를 노출합니다. 이 예시에서는 실행되어야 하는 대상만 유지합니다. 종료되어야 하는 작업을 모니터링하지 않도록 방지합니다.

- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
  regex: .+
  action: keep

cadvisor를 배포할 때 prometheus-job=cadvisor 라벨을 추가했습니다. Prometheus가 작업 라벨을 가져오므로, prometheus-job 라벨이 있는 대상만 유지하도록 지시할 수 있습니다.

- source_labels: [__meta_dockerswarm_service_label_prometheus_job]
  target_label: job

마지막 부분은 작업의 prometheus-job 라벨을 가져와 대상 라벨로 바꾸며, 스크레이프 구성에서 오는 기본 dockerswarm 작업 라벨을 덮어씁니다.

발견된 라벨 (Discovered labels)

Prometheus 문서에 라벨의 전체 목록이 있지만, 유용할 수 있는 다른 relabel 구성들이 여기 있습니다.

특정 네트워크를 통해서만 메트릭 스크레이프

- source_labels: [__meta_dockerswarm_network_name]
  regex: ingress
  action: keep

전역 작업만 스크레이프

전역 작업은 모든 데몬에서 실행됩니다.

- source_labels: [__meta_dockerswarm_service_mode]
  regex: global
  action: keep
- source_labels: [__meta_dockerswarm_task_port_publish_mode]
  regex: host
  action: keep

대상에 docker_node 라벨 추가

- source_labels: [__meta_dockerswarm_node_hostname]
  target_label: docker_node

Docker Swarm에 연결하기

위의 dockerswarm_sd_configs 항목에는 host 필드가 있습니다:

host: unix:///var/run/docker.sock

이것은 Docker 소켓을 사용하는 것입니다. Prometheus는 유닉스 소켓 대신 추가 구성 옵션을 제공해 HTTP와 HTTPS로 Swarm에 연결할 수 있습니다.

결론 (Conclusion)

어떤 대상을 어떻게 모니터링할지 더 잘 결정할 수 있는 발견 라벨이 많으며, tasks의 경우 25개 이상의 라벨을 사용할 수 있습니다. Prometheus 서버의 "Service Discovery" 페이지(Status 메뉴 아래)에서 모든 발견된 라벨을 확인해보세요.

서비스 디스커버리는 여러분의 Swarm 스택에 대해 어떤 가정도 하지 않으므로, 적절한 구성이 주어지면 기존 스택 어디에든 플러그인할 수 있습니다.

더 알아보기 (Learn more)