저는 혼자서 개인 사이드 프로젝트를 진행하고 있습니다.
매번 AWS 혹은 EC2 Console에 ssh로 접속해서 서버의 상태를 확인하는 것을 매우 비효율적이기 때문에 이번에 Monitoring
를 도입하기로 했습니다.
사용할 기술 스택은 영한님께서도 추천해주신 Prometheus
와 Grafana
를 이용하여 진행해보겠습니다.
두 기술 스택 모두
오픈소스
라서 비용 문제 없이 접근할 수 있습니다. 이 점이 취준생 입장인 저에게 있어 상당히 매력적이었습니다.그리고 두 기술 모두 커뮤니티가 잘 되어 있기 때문에
관련 자료의 접근성
이 좋아서 선택했습니다
참고 블로그
build.gradle
에 해당 의존성을 추가해줍니다. (추가 후에는 꼭 Load Gradle Changes
해주세요!!!)
//Spring Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
//Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'
application.yaml
에 actuator
관련 설정을 추가해줍니다.
server:
tomcat: # tomcat 메트릭 설정 on. 톰캣 메트릭은 tomcat. 으로 시작
mbeanregistry: # 톰캣 메트릭을 모두 사용하려면 다음 옵션을 켜야하며, 옵션을 켜지 않으면 tomcat.session. 관련정보만 노출됩니다
enabled: true
management:
endpoints:
web:
exposure:
include: "*" # 이 설정은 모든 Actuator 엔드포인트를 외부에 노출
base-path: /api/actuator # Actuator 엔드포인트의 기본 경로 지정
server:
port: 9090 # Actuator 엔드포인트가 서비스될 서버의 포트
해당 내용을 다 추가하셨으면, Build
하시고 서버에 올려주시면 됩니다!
acturator
는 서버의 정보들이 포함되므로, 노출되면 위험할 수 있습니다.
그러므로 Security에 해당 actuator URL
에 대한 설정을 추가해줍니다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(req ->
req
.requestMatchers(getActuatorAllUrl()).hasRole("ACTUATOR")
.anyRequest().hasAnyRole("USER")
)
.sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
해당 Bean
을 추가해주시면 해당 하는 Metric들은 노출 되지 않습니다.
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config()
.meterFilter(MeterFilter.deny(id -> id.getName().startsWith("spring.data.repository")));
}
모니터링 서버에는 간편하게 사용할 수 있게 Docker-Compose
를 이용하여 Prometheus
와 Grafana
를 설치하고 쓰겠습니다.
모니터링 서버에 접속 후 Docker
및 Docker-Compose
를 설치해주세요 (본인 OS에 맞춰서 설치하시면 됩니다.)
docker-compose.yml
에서 사용할 폴더를 추가해주겠습니다.
# 현재 폴더에서 prometheus랑 grafana 폴더를 만들어 줍니다.
mkdir prometheus
mkdir grafana
# prometheus 폴더에 들어가서 config, volume 폴더를 만들어줍니다.
cd prometheus
mkdir config
mkdir volume
# config 폴더에 들어가서 prometheus.yml 파일을 만들어 줍니다. (내용은 추후에 추가)
cd config
touch prometheus.yml
# grafana 폴더에 들어가서 volume, provisioning 폴더를 만들어줍니다.
cd ../../grafana
mkdir volume
mkdir provisioning
# 원래 위치로 돌아오기
cd ..
docker에서 수정할 수 있도록 grafana 폴더 및 prometheus의 폴더의 권한을 변경합니다.
sudo chmod -R 777 ./prometheus
sudo chmod -R 777 ./grafana
이제 prometheus.yml
에다가 내용을 추가해주겠습니다.
# prometheus.yml 열기
vi prometheus/config/prometheus.yml
global:
scrape_interval: 15s # scrap target의 기본 interval을 15초로 변경 / default = 1m
scrape_timeout: 15s # scrap request 가 timeout waite/ default = 10s
external_labels:
monitor: 'monitor' # 기본적으로 붙여줄 라벨
query_log_file: query_log_file.log # prometheus의 쿼리 로그들을 기록. 설정되지않으면 기록하지않는다.
# 매트릭을 수집할 엔드포인드를 지정한다.
scrape_configs:
# job 기준으로 메트릭을 수집한다.
- job_name: "spring-actuator" # job_name 은 모든 scrap 내에서 고유해야한다
metrics_path: '/api/actuator/prometheus' # 스프링부트에서 설정한 endpoint [metrics_path의 기본 경로는 '/metrics'], 뒤에 prometheus를 붙이면 prometheus의 정보를 가져온다.
scrape_interval: 15s # global 값과 다르게 사용할려면 따로 정의하자.
scheme: 'https' # request를 보낼 scheme 설정 [scheme의 기본값은 `http`]
static_configs:
- targets: ['ServerIP:Port'] # request를 보낼 server ip 그리고 actuator port를 적어주면 된다. (위에서 지정한 포트는 9090이며, 서버 IP는 EC2의 Public Ip를 적어주자)
# 보안을 위해서 JWT를 사용. (내 Spring 서버에서 사용할 수 있는 JWT를 발급받아서 사용)
bearer_token: 'JWT Token'
actuator
서버용 포트가 AWS EC2
의 인바운드 포트로 잘 열려있는지 확인actuator
URL이 Security에 필터링이 되지는 않는지, JWT를 제대로 발급받았는지 확인EC2
에서 Docker
를 이용하고 있다면, actuator
서버 포트를 잘 expose
시켰는지 확인 (제가 이 문제로 삽질을 많이 했습니다 ㅠㅠ)다음으로 docker-compose.yml
를 작성하겠습니다.
version: '3.3' # 파일 규격 버전
services: # 이 항목 밑에 실행하려는 컨테이너 들을 정의
prometheus:
image: prom/prometheus
container_name: prometheus
# 내 폴더랑 docker 폴더랑 연결
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/volume:/prometheus
ports:
- 9090:9090 # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
command: # web.enalbe-lifecycle은 api 재시작없이 설정파일들을 reload 할 수 있게 해줌
- '--web.enable-lifecycle'
- '--config.file=/etc/prometheus/prometheus.yml'
restart: always
networks:
- promnet
grafana:
image: grafana/grafana
container_name: grafana
# user: "$GRA_UID:$GRA_GID"
ports:
- 3000:3000 # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
volumes:
- ./grafana/volume:/var/lib/grafana
- ./grafana/provisioning/:/etc/grafana/provisioning/
restart: always
networks:
- promnet
depends_on:
- prometheus
networks:
promnet:
driver: bridge
docker-compose up -d
명령어를 통해서 실행시켜 주세요. (docker-compose.yml
파일이 있는 곳에서 실행하셔야 합니다.)
정상적으로 실행이 되면, 모니터링 서버의 Public IP를 통해 prometheus
랑 grarafa
로 접속을 해봅니다.
prometheus
는 http://모니터링 서버 주소:9090
를 통해서 접속합니다.prometheus.yml
에 입력한 내용 확인이 가능합니다.grarafa
는 http://모니터링 서버 주소:3000
를 통해서 접속합니다. (기본 계정 ID/PW: admin/admin)http://prometheus:9090
를 입력합니다. (같은 docker-compose network라서 가능) → Save & Test이렇게 해서 prometheus 및 grafana 설치를 완료했습니다 !!
참고 블로그
Cloud 서버에 Node Exporter
를 설치하고 Prometheus
로 관련 메트릭을 수집하면 Cloud 서버의 하드웨어 정보도 수집하여 Grafana
를 통해서 시각화가 가능합니다.
※ 저는 Spring 서버
를 Docker
로 구동 중이라, Node Exporter
도 Docker
로 구동했습니다 !
EC2 서버에 접속 후 해당 명령어를 통해서 Node Exporter
를 Docker
로 실행한다.
docker run -d --name node-exporter \
--net="host" \
--pid="host" \
-v "/:/host:ro,rslave" \
quay.io/prometheus/node-exporter:latest \
--path.rootfs=/host
※ 해당 명령어에 대한 설명
-d
: 컨테이너를 백그라운드 모드로 실행
-name node-exporter
: 생성되는 컨테이너에 node-exporter
라는 이름을 할당
-net="host"
: 컨테이너가 호스트의 네트워크 네임스페이스를 사용하도록 설정. 이를 통해 컨테이너가 호스트와 동일한 네트워크 인터페이스와 포트를 사용할 수 있습니다.
-pid="host"
: 컨테이너가 호스트의 PID 네임스페이스를 사용하도록 설정. 이는 컨테이너 내에서 호스트 시스템의 모든 프로세스 정보에 접근할 수 있게 합니다.
v "/:/host:ro,rslave"
: 호스트의 루트 파일 시스템을 컨테이너의 /host
디렉토리에 읽기 전용(ro
)으로 마운트하고 rslave
옵션은 마운트 네임스페이스의 변경사항이 마운트 포인트에 전파되도록 합니다.
quay.io/prometheus/node-exporter:latest
: 사용할 이미지입니다. Prometheus의 node-exporter
이미지의 최신 버전을 quay.io
레지스트리에서 가져옵니다.
-path.rootfs=/host
: node-exporter
에게 호스트의 파일 시스템이 /host
에 마운트되었음을 알립니다. 이를 통해 node-exporter
가 호스트 시스템의 메트릭을 올바르게 수집할 수 있습니다.
EC2 서버의 9100 포트에 접속하면 Node Exporter
가 실행중인 것을 확인할 수 있습니다. (혹시나 접속이 안되면 인바운드 포트를 열었는지 확인!!)
http://EC2 서버 주소:9100/metrics
로 접속을 하시면 Node Exporter
가 수집하는 메트릭에 관한 모든 정보들을 확인할 수 있습니다.모니터링 서버가 Node Exporter
데이터를 수집할 수 있도록 모니터링 서버의 Prometheus 설정에다가 해당 주소를 추가해줘야 합니다.
prometheus.yml
파일을 수정합니다. (아래 내용을 추가)
- job_name: 'node-exporter-ocp' # AWS EC2의 하드웨어의 상태와 커널 관련 메트릭을 수집
metrics_path: '/metrics' # endpoint
scrape_interval: 30s # 수집 주기
scheme: 'http' # request를 보낼 scheme 설정 | default = http
static_configs:
- targets: ['EC2 서버 주소:9100']
모니터링 서버의 Prometheus
에 접속 후 Targets
에 들어가 보시면 Node Exporter
를 수집하고 있습니다.
추가된 데이터를 그래프로 확인하기 위해 Grafana
에 접속 후 DashBoard를 추가합니다.
이렇게 해서 Node Exporter
도 설치를 완료했습니다.