Programming-[Infra]/Docker

도커 교과서(엘튼 스톤맨, 심효섭) - 8. 모니터링- prometheus, grafana

컴퓨터 탐험가 찰리 2023. 4. 5. 09:33
728x90
반응형

 

1. 컨테이너를 사용하는 환경의 모니터링

 

일반적인 환경은 서버의 목록과 각 서버의 현재 동작 상태를 표시해주는 형태이다. 컨테이너를 사용하는 환경은 수십~ 수백 개에 이르는 컨테이너가 생성 및 삭제를 반복하며 계속해서 동적으로 변화하는 환경이다. 이런 컨테이너 기반의 모니터링 및 측정에 연동되도록 그 자체가 컨테이너로 동작하는 오픈 소스 도구가 프로메테우스이다.

 

프로메테우스의 장점

  • 모든 애플리케이션에서(Node.js 이든 닷넷이든 상관없이) 똑같이 구성된 측정값을 출력한다.
  • 도커 엔진과 연결하여 도커 엔진 자체의 측정값도 추출할 수 있다.

 

도커 엔진의 daemon.json 파일

도커 엔진과 프로메테우스를 연결하기 위해서는 도커 엔진의 설정 파일인 daemon.json 파일에서 설정 내용을 추가해야한다. 교재에 따르면 윈도 환경에서는 C:\Program Data\docker\config 디렉터리에 위치하고, 리눅스 환경에서는 /etc/docker 디렉터리에 위치한다고 한다.

나의 경우 macOS라서 아래 위치에 있었다.

/Users/사용자명/.docker/daemon.json

기본적으로 /var/lib/docker 위치에 있다고 알고 있으나, 실제 파일은 상기 디렉터리에 있었다.

 


기타 배운 점들

docker info

터미널에 docker info를 입력하면 도커 설정 관련내용들을 확인할 수 있다.

 

사진의 맨 아래 Docker Root Dir 정보가 도커가 이미지, 볼륨 등을 관리하는 기본 root이다. 다만 앞서 기술한 것처럼 내 컴퓨터는 위치가 변경되어있었다... grep 명령어를 추가하여 한번에 위치를 뽑아낼 수도 있다.

 

grep

grep은 CLI 유틸리티로, 일반 텍스트, 로그 등에서 특정 문자열을 쉽게 찾을 수 있는 도구다. 기본 문법은 아래와 같다.

grep [options] pattern [file(s)]

 

예를 들어 아래처럼 입력하면, 앞선 예제의 Docker Root Dir 값을 바로 출력할 수 있다. -i는 대소문자 구분없이 찾는다는 Case Insensitive 옵션이다.

 

Docker info | grep -i "Docker Root Dir"

 


 

| 는 파이프라인 커맨드라고 불리는데, 앞 명령어의 output을 뒷 명령어의 input값으로 전달한다.

 

 

 

 

계속해서, daemon.json 파일을 열고 다음 값들을 추가한다.

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

 

docker desktop에서 직접 수정해도 된다. 나의 경우 docker-desktop 버전을 v4.18.0을 사용하는데, experimental값은 그냥 원래대로 false로 놔둬도 되는 것 같다. 수정후 docker를 restart하고 localhost:9323/metrics에 접속하면 아래와 비슷하게 도커 엔진을 통한 컨테이너 모니터링 로그들이 쭉 찍혀있는 것을 볼 수 있다.

 

 

2. 프로메테우스 빌드

이제 위에서 살펴본 로그에 타임 스탬프를 추가하고, UI상으로 모니터링 내용을 알려주도록 프로메테우스 기반 이미지를 사용한다. 우선 컨테이너는 자신을 실행 중인 서버의 IP주소를 알 수 없으므로 컨테이너에 이 값을 환경 변수로 직접 전달해준다.

 

$hostIP = $(Get-NetIPConfiguration | Where-Object {$_.IPv4DefaultGateway -ne $null }).IPv4Address.IPAddress(윈도우)
hostIP=$(ip route get 1 | awk '{print $NF;exit}') (리눅스)
hostIP=$(ifconfig en0 | grep -e 'inet\s' | awk '{print $2}') (macOS)

docker container run -e DOCKER_HOST=$hostIP -d -p 9090:9090 diamol/prometheus:2.13.1 #hostIP전달하여 프로메테우스 실행

 

그리고나서 localhost:9090에 접속하면 프로메테우스 GUI를 확인할 수 있다. Status -> Targets에 들어가면 9323 포트의 metrics가 제대로 실행중인지 확인할 수 있다.

ip주소 알아보기

위 화면에서 State가 DOWN인 이유는 위 명령어에서 ifconfig en0를 통해 en0 네트워크 인터페이스에서 'inet ' 문자에 해당하는 값을 찾아야하는데 찾을 수 없었기 때문이었다.

ifconfig 명령어를 입력하여 inactive status인 en0 대신 active status인 en<number> 인터페이스를 찾아서 위 hostIP를 설정하는 명령어를 수정해준다. 그리고 다시 프로메테우스로 접속하면 정상적으로 State가 UP인 것을 확인할 수 있다.

 

DOCKER_HOST로 지정된 IP주소로 Endpoint가 잡혀서 실행중인 것을 볼 수 있다. 로컬 환경이 아니라 개발환경이라면 IP 주소를 직접 전달해주면 된다.

 

GRAPH - engine_daemon_container_actions_seconds_sum 항목을 클릭하여 Execute 시 컨테이너가 실행된 시간 합계를 초 단위로 살펴볼 수 있다. 이런식으로 여러 데이터값을 쿼리로 조회하고 그래프로 그려낼 수 있다.

 

 

3. 애플리케이션 측정값 출력 실습

 

앞서 살펴봤던 Go, Java, Node.js로 구성된 image-of-the-day 애플리케이션을 실행하고 metrics로 측정값을 살펴본다.

 

cd ./ch09/exercises
docker network create nat #이미 있지만 더블 체크
docker-compose up -d

 

http://localhost:8010/metrics에 접속하면 로그 값들을 볼 수 있다. 그리고 http://localhost:8011/actuator/prometheus에 접근 시 자바 REST API의 측정값들을 확인할 수 있다.

 

엔드포인트로 요청을 보내고 8012/metrics에 접근하면 access-log의 로그를 볼 수 있다.

for ($i=1; $i -le 10; $i++) { iwr -useb http://localhost:8010 | Out-Null } (윈도우)
for i in {1..10}; do curl http://localhost:8010 > /dev/null; done (리눅스)

 

 

프로메테우스의 측정 원리

프로메테우스는 대상 시스템에서 측정값을 주기적으로 풀링하는 방식으로 작동한다. 이 과정을 스크래핑이라고 한다. 교재의 프로메테우스 설정에서는 10초마다 한 번씩 풀링을 실행하도록 설정하였다고 한다.

global:
	scrape_interval: 10s
    #...각 컨테이너 애플리케이션의 이름, port, 접근 경로등 정보

 

로드 밸런싱 확인

교재에서 제공해주는 access-log 애플리케이션을 스케일링 할 수 있는 컴포즈 파일로 실행하면, 요청들이 각 컨테이너에 골고루 분배되어 로드밸런싱이 제대로 작동되는 것을 확인할 수도 있다.

docker-compose -f docker-compose-scale.yml up -d --scale accesslog=3
for i in {1..10}; do curl http://localhost:8010 > /dev/null; done #요청 보내기 (리눅스)

 

localhost:9090/graph -> access_log_total 확인

 

로드 밸런싱이 돼서 각 컨테이너에 고르게 요청이 들어간 것을 볼 수 있다.

 

add graph 버튼을 누르고 다음 쿼리문을 입력 후 execute하면 그래프로도 실시간 차트로 볼 수 있다.

 

기초적인 그래프를 그릴 수는 있으나, 대시보드처럼 UI로 표현하는 기능을 위해서는 Grafana가 필요하다.

 

 

4. 그라파나 실행

 

로컬 컴퓨터의 IP 주소를 다시 한 번 확인한다. 그리고 다른 명령어를 써서 등록해본다.

 

# 환경변수 등록
## 윈도우
$env:HOST_IP = $(Get-NetIPConfiguration | Where-Object {$_.IPv4DefaultGateway -ne $null }).IPv4Address.IPAddress

## 리눅스
export HOST_IP=$(ip route get 1 | awk '{print $NF;exit}')

# 그라파나가 포함된 파일로 애플리케이션 실행
docker-compose -f ./docker-compose-with-grafana.yml up -d --scale accesslog=3

#부하주기
## 윈도우
for($i=1; $i - le 20; $i++) { iwr -useb http://localhost:8010 | Out-Null }
## 리눅스
for i in {1..20}; do curl http://localhost:8010 > /dev/null; done

 

ip 주소 등록 명령어

나는 macOS를 사용해서 리눅스 기준으로 명령어를 입력했다. ip 명령어는 'iproute2mac' 패키지를 설치해야한다.

brew install iproute2mac

그리고 위 ip route get 1 명령어는 네트워크 정보를 표시하는 라우팅 테이블 중에서, 기본 라우트를 의미하는 1을 입력하여 로컬 네트워크의 주소의 정보들을 가져오라는 의미가 된다.

 

 

awk

awk는 Unix, Linux에서 사용하는 문자열 처리기 명령어이다. 마치 코딩하는 것처럼 중괄호를 열고 print $NF; exit을 입력했다. print $NF는 입력값의 맨 마지막 줄을 출력하라는 의미이고, exit은 동작을 마치고 awk를 끝내겠다는 의미가 된다.

 

따라서 이 출력값은 위 ip route 정보 사진에서 맨 마지막 모자이크 처리된 ip 주소값만 출력한다. 이것을 환경 변수 HOST_IP로 등록하는 것이다. 참고로 '=' 사이에 띄어쓰기가 있으면 안된다. 그리고 env 명령어로 환경변수가 잘 등록 되었는지 확인해볼 수 있다. 또는 위에서 배운대로 env | grep 'HOST_IP'를 입력해봐도 된다.

 

 

위 명령어들을 모두 입력 후 localhost:3000으로 그라파나 웹으로 접근해본다.

 

그라파나 에러

그러나 해당 이미지에서 그라파나가 에러가 났다. docker-compose 파일상 설정 내용은 아래와 같았다.

 grafana:
    image: diamol/ch09-grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus
    networks:
      - app-net

 

docker desktop에서 해당 컨테이너에 들어가보니 경로에 executable한 파일이 없다고 나왔다

 

/usr/share/grafana/bin/grafana-server

 

그래서 docker-compose 파일을 일반 grafana로 수정하고 localhost:3000에 접속하니 접속은 됐지만 로그인이 안됐다.

 

그래서 무료 가입을 하면 그라파나 Cloud 페이지엔 접속이 가능하지만 localhost에서는 접속이 안됐다. 그리고 아래처럼 Free trial 기간이 정해져있었다.

 

docker를 학습하는데 필수적인 요건은 아닌지라 그냥 넘어가야할 것 같다. 그냥 이런 시각화 툴이 있다는 것 정도만 알면 될 것 같다. AWS나 Azure도 개별로 모니터링 툴을 제공하니까..

728x90
반응형