컨테이너된 환경에서 애플리케이션 모니터링
: 프로메테우스(Prometheus)
전통적인 애플리케이션 모니터링
- 일반적으로 고정된 서버에서 애플리케이션을 실행하고 관리하므로, 서버의 상태를 추적하고 문제가 발생했을 때 알림을 받는 방식으로 작동한다.
- 보통 서버의 CPU 사용량, 메모리 사용량, 디스크 공간 등의 기본적인 지표를 추적한다.
- 컨테이너화된 애플리케이션 환경에서는 적합하지 않다.
- 컨테이너는 빠르게 생성되고 삭제되며, 많은 컨테이너가 동시에 실행될 수 있다.
- 컨테이너화된 애플리케이션 환경에서는 각 컨테이너의 상태를 개별적으로 추적하고, 컨테이너 간의 관계와 상호작용을 이해할 수 있는 모니터링 도구가 필요하다.
- 또한, 컨테이너가 생성되고 삭제되는 빠른 주기를 반영할 수 있는 동적인 모니터링 방식이 필요하다.
프로메테우스(Prometheus)
- 컨테이너화된 환경에서 애플리케이션을 모니터링 하기 위해 설계된 오픈소스 모니터링 시스템이다.
- 각 컨테이너의 상태를 개별적으로 추적하며, 컨테이너 간의 관계과 상호작용을 이해하고, 컨테이너의 생성과 삭제를 빠르게 반영하는 동적인 모니터링을 제공한다.
- 컨테이너 플랫폼과 연동하여, 정적인 컨테이너와 IP 주소 목록 없이도 실행 중인 애플리케이션을 모니터링할 수 있다.
프로메테우스(Prometheus)
- 분산 애플리케이션에서 모니터링을 쉽게 추가할 수 있도록 설계된 도구이다.
- 도커 엔진
- 컨테이너의 상태를 측정하고, 그 결과를 API를 통해 외부로 제공할 수 있도록 설정할 수있다.
- 프로메테우스
- 애플리케이션의 측정값을 외부로 공개하는 API를 포함하여 컨테이너를 만든다.
- 이는 애플리케이션의 상태 정보를 측정하고, 그 정보를 외부에 공개하도록 만드는 기능이다.
- 자신이 실행하는 컨테이너에서 도커 엔진과 다른 애플리케이션 컨테이너로부터 정보를 수집하고, 수집한 데이터를 시간과 함께 저장한다.
- 모니터링의 일광성이 확보된다.
- 모든 애플리케이션을 동일한 형태로 모니터링할 수 있다.
- 예: 윈도우 컨테이너에서 실행되는 닷넷 애플리케이션, 리눅스 컨테이너에서 실행되는 Node.js 애플리케이션 등
- 또한, 프로메테우스의 쿼리 언어를 이용하면, 전체 애플리케이션 스택에 동일한 모니터링을 적용할 수 있다.
- 모든 애플리케이션을 동일한 형태로 모니터링할 수 있다.
- 애플리케이션의 측정값을 외부로 공개하는 API를 포함하여 컨테이너를 만든다.
도커 엔진의 측정값도 프로메테우스가 같은 형식으로 추출할 수 있다.
- 이는 프로메테우스가 도커 엔진에서 일어나는 일들을 파악하는 데 도움을 준다.
- 이를 위해서는 도커 엔진 설정에서 프로메테우스 측정 기능을 명시적으로 활성화해야 한다.
도커 엔진 예시
- 컨테이너의 상태벼 개수 등과 같은 지속적으로 변화하는 정보를 포함하고 있다.
- 또한 시스템의 설치된 메모리 용량 등과 같은 정적인 정보도 포함하고 있다.
- 허나 도커 엔진의 상태 측정 기능이 아직 안정적이지 않고 개발 중인 기능이다.
- 그러나 주요 변경 없이 오랫동안 유지하고 있어 상대적으로 안정적이다.
- 도커 엔진의 상태 정보는 시스템 전체의 상태를 이해하는 데 중요한 역할을 하기 때문에 모니터링 대시보드에 추가할만 하다.
프로메테우스 예시
# 로컬 컴퓨터의 IP 주소를 확인해 환경 변수로 정의(윈도)
$hostIP = $(Get-NetIPConfiguration | Where-Object {$_.IPv4DefaultGateway -ne $null}).IPv4Address.IPAddress
# 환경 변수로 로컬 컴퓨터의 IP 주소를 전달해 컨테이너를 실행
docker container run -e DOCKER_HOST=$hostIP -d -p 9090:9090 diamol/prometheus:2.13.1
DOCKER_HOST는 프로메테우스가 도커 엔진의 메트릭을 수집하는 데 사용하는 환경 변수이다.
즉, 프로메테우스가 로컬 호스트의 도커 엔진으로 접속하여 메트릭을 수집할 수 있다.
- 프로메테우스는 설정된 주기에 따라 도커 엔진이 /metrics 엔드포인트에서 메트릭 정보를 수집하고, 이 정보를 DB에 타임스탬프와 함께 저장한다.
- 웹 인터페이스를 통해 수집된 메트릭을 확인하고, 쿼리를 실행하여 특정 메트릭을 검색하거나 시간에 따른 메트릭의 변화를 관찰할 수 있다.
프로메테우스 라이브러리
- 애플리케이션의 특정 정보(ex. 메모리 사용량, CPU 사용량, 에러 발생 횟수 등)를 측정하고 이를 수치데이터인 측정값으로 만들기 위해서는, 해당 정보를 생성하고 추출하는 코드를 작성해야 한다.
- 또한 이렇게 생성된 측정값을 모니터링 툴에서 사용하려면, HTTP 엔트포인트로 제공해야 한다.
- 도커 엔진의 경우, 이미 측정값을 수집하는 기능이 내장되어 있다.
- 주요 프로그래밍 언어(ex. 자바, 파이썬, Go 등)에서는 모니터링 툴을 지원하는 프로메테우스 라이브러리를 제공한다.
예시 - java
package iotd;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ImageController {
private static final Logger log = LoggerFactory.getLogger(ImageController.class);
@Autowired
CacheService cacheService;
@Autowired
MeterRegistry registry;
@Value("${apod.url}")
private String apodUrl;
@Value("${apod.key}")
private String apodKey;
@RequestMapping("/image")
@Timed()
public Image get() {
log.debug("** GET /image called");
Image img = cacheService.getImage();
if (img == null) {
RestTemplate restTemplate = new RestTemplate();
ApodImage result = restTemplate.getForObject(apodUrl+apodKey, ApodImage.class);
log.info("Fetched new APOD image from NASA");
registry.counter("iotd_api_image_load", "status", "success").increment();
img = new Image(result.getUrl(), result.getTitle(), result.getCopyright());
cacheService.putImage(img);
}
else {
log.debug("Loaded APOD image from cache");
registry.counter("iotd_api_image_load", "status", "cached").increment();
}
return img;
}
}
더보기
- Micrometer 라이브러리를 사용하여 애플리케이션의 매트릭을 측정하고 수집하고 있다.
- MeterRegistry 객체를 사용하여 프로메테우스에 데이터를 제공하는 데 필요한 측정 항목들을 등록하고 있다.
- /image 엔드포인트에서는 이미지를 불러올 때마다 프로메테우스의 counter 메트릭을 이용하여 이미지 로드 횟수를 측정하고 있다.
- 이미지가 캐시에서 불러오면 iotd_api_image_load라는 이름의 counter에 status라는 태그와 cached라는 값을 가진 항목의 카운트가 1 증가하고, NASA API로부터 새로운 이미지를 불러오면 status 태그의 success 값을 가진 항목의 카운트가 1 증가한다.
애플리케이션에 따른 수집할 값 기준
- 외부 시스템과의 통신에 걸린 시간 및 응답 상태 기록
- 외부 서비스의 지연 또는 실패가 애플리케이션의 성능에 어떤 영향을 미치는지 파악할 수 있다.
- 로그로 남길 가치가 있는 정보의 측정값 수집
- 로그는 애플리케이션의 동작에 대한 깊은 이해를 얻을 수 있지만, 로그 데이터는 공간을 많이 차지하고 처리하는 데 시간이 많이 소요된다.
- 반면 측정값은 데이터를 집계하고 효율적으로 저장하고, 시간 경과에 따른 추세를 시각화하는 데 유용하다.
- 따라서, 로그로 남기기에는 비효율적이지만 애플리케이션의 상태를 이해하는데 중요한 정보는 측정값으로 수집하는 것이 좋다.
- 사업 부서에서 필요한 애플리케이션 상태 및 사용자 행동 정보
- 애플리케이션의 성능 데이터 외에도 사업적인 측면에서 중요한 정보가있을 수 있다.
스크래핑(scraping)
프로메테우스의 작동 방식
- 측정값을 수집하기 위해 풀링 방식을 사용한다.
- 프로메테우스가 직접 대상 시스템에 연결하여 측정값을 가져오는 방식이다.
- 이와 반대로 푸시 방식은 대상 시스템이 측정값을 수집 시스템에 전송하는 방식이다.
스크래핑
- 프로메테우스에서 측정값을 수집하는 과정이다.
스크래핑 대상 엔드포인트 설정
- 프로메테우스는 대상 시스템의 특정 HTTP 엔드포인트로 요청을 보내 측정값을 가져온다.
- 프로메테우스를 실행할 때 어떤 시스템에서 측정값을 가져올지를 지정해야 한다.
- 이를 스크래핑 대상 엔드포인트 설정이라 한다.
- 즉, 어느 HTTP 엔드포인트로 요청을 보낼 것인지를 결정하는 것이다.
클러스터와 단일 서버 설정
- 프로메테우스를 실행하는 환경에 따라 스크래핑 대상을 찾는 방법이 다를 수 있다.
- 클러스터 환경에서는 모든 컨테이너를 스크래핑 대상으로 설정할 수 있다.
- 반면 단일 서버의 도커 컴포즈 환경에서는 도커 네트워크의 DNS를 통해 서비스 목록에서 대상 컨테이너를 자동으로 찾을 수 있다.
예시 - 로드 밸런싱이 잘 이루어지는지 확인
# 애플리케이션 측정값을 스크래핑하기 위한 프로메테우스 설정
global:
scrape_interval: 10s
scrape_configs:
- job_name: "image-gallery"
metrics_path: /metrics
static_configs:
- targets: ["image-gallery"]
- job_name: "iotd-api"
metrics_path: /actuator/prometheus
static_configs:
- targets: ["iotd"]
- job_name: "access-log"
metrics_path: /metrics
dns_sd_configs:
- name:
- accesslog
type: A
port: 80
더보기
- global 설정
- 전역 설정에서는 scrape_interval이라는 파라미터를 통해 얼마나 자주 측정값을 수집할지 설정할 수 있다.
- 여기서는 10초마다 수집하도록 설정하였다.
- scrape_configs 설정
- 프로메테우스가 어디에서 측정값을 가져올지 지정한다.
- job_name: 스크래핑 작업의 이름
- metrics_path: 측정값을 수집할 엔드포인트를 지정
- static_configs 또는 dns_sd_configs를 통해 측정값을 가져올 대상을 지정
- static_configs: 단일 서버나 컨테이너의 IP나 호스트명을 지정한다.
- 이 예제에서는 image-gallery와 iotd 서비스가 이에 해당한다.
- dns_sd_configs: DNS 서비스 디스커버리를 이용하여 동적으로 측정값을 수집할 서버나 컨테이너를 찾는다.
- 이 예제에서는 access-log 서비스가 이에 해당한다.
- static_configs: 단일 서버나 컨테이너의 IP나 호스트명을 지정한다.
- 단일 컨테이너: image-gallery와 iotd 서비스
- 여러 컨테이너: access-log 서비스
- 로드 밸런싱이라는 기술이 사용되어 요청이 균등하게 분배된다.
Label 시스템
- 측정값에 메타데이터를 추가하고 분류하는 데 사용된다.
- 키-값 형태로 구성된다.
- 예를 들어, 서버에서 CPU 사용률을 측정하는 경우, 레이블을 사용하여 해당 서버의 이름, 위치, 역할 등 추가 정보를 표시할 수 있다.
- PromQL(Prometheus Query Language)를 이용하여 복잡한 쿼리를 작성할 수 있다. 이를 통해 특정 레이블을 가진 측정값만 선택하거나, 레이블 값을 기반으로 측정값을 그룹화하거나 집계할 수 있다.
그라파나 컨테이너 실행하기
: 측정값 시각화
그라파나는 오픈 소스 데이터 시각화 및 모니터링 도구이다. 프로메테우스, 인플럭스 DB, MySQL, PostgreSQL 등과 같은 다양한 데이터 소스에서 데이터를 가져와 대시보드에 시각화하여 보여준다.
예시 1
# 로컬 컴퓨터의 IP 주소를 환경 변수로 저장하기(윈도)
$env:HOST_IP = $(Get-NetIPConfiguration | Where-Object {$_.IPv4DefaultGateway -ne$null }).IPv4Address.IPAddress
# 그라파나가 포함된 컴포즈 파일로 애플리케이션 실행
docker-compose -f ./docker-compose-with-grafana.yml up -d --scale accesslog=3
# 커스텀 그라파나 이미지의 Dockerfile 스크립트
FROM diamol/grafana:6.4.3
COPY datasource-prometheus.yaml ${GF_PATHS_PROVISIONING}/datasources/
COPY dashboard-provider.yaml ${GF_PATHS_PROVISIONING}/dashboards/
COPY datasource.json /var/lib/grafana/dashboards/
더보기
- 위 과정을 통해 그라파나 도커 이미지를 생성하게 되며, 이 이미지를 실행하면 복사된 설정 파일들이 기본으로 적용되어 그라파나가 실행된다. 이를 통해 커스텀 설정이 적용된 그라파나 서버를 쉽게 실행하고 관리할 수 있다.
'DevOps > Docker' 카테고리의 다른 글
[Docker] 헬스 체크와 디펜던시 체크 (0) | 2023.07.18 |
---|---|
[Docker] 도커 컴포즈와 분산 애플리케이션 (0) | 2023.07.18 |
[Docker] 도커 볼륨과 마운트 (0) | 2023.07.18 |
[Docker] 도커 레지스트리와 도커 허브: 이미지 공유와 관리 (0) | 2023.07.18 |
[Docker] 멀티 스테이지와 애플리케이션 빌드 (0) | 2023.07.09 |