안녕하세요! Betalabs 백엔드 개발팀의 Soora 입니다.
Betalabs에서 모니터링을 구성하기 위해 노력했던 것, AWS
환경에서 조금은 고민이 될법한 내용을 공유해 드려봅니다.
어느덧 회사에서 운영 중인 서버는 수십 개 이상이 되었고, 서비스의 안정성을 위해 멀티 클라우드 환경도 구성하게 되었습니다. 멀티 클라우드에 구성된 수많은 서버가 항상 정상적일것이라고 믿고 있지는 않았습니다. 항상 불안정한 서버나 특정 시간대에 많은 요청으로 인해 리소스가 부족한 서버도 있을 것입니다. 또는 특정 클라우드의 AZ
가 문제가 되어서 수동적으로 대응이 필요할 수도 있을 것입니다.
앞서 걱정한 것과는 달리 항상 잘 운영이 되면 문제가 없겠지만, 소수의 인원으로 모든 서비스의 안정적인 운영이 필요했습니다. 결국 우리는 이 문제를 해결하기 위해 모든 서버의 리소스 정보를 한곳으로 모으기로 했습니다. 더 나아가 시각화를 통해 서버가 정상적으로 동작하고 있는지, 지속해서 증가하는 트래픽으로 인해 DataBase
등이 ScaleUp
이 필요한지 판단하기 위해 모니터링을 도입했습니다.
처음에는 DataDog
을 통해서 모니터링을 진행했습니다. DataDog
을 사용함으로써 모든 서버의 로그를 한곳에서 볼 수 있었고, 상태도 DataDog
을 통해 파악이 가능했습니다. DataDog
은 설정하기도 매우 편리하고, 모니터링 도구로 매우 훌륭했습니다. 하지만 서비스가 성장하면서 인스턴스의 개수도 늘게 되었고, 결국 비용도 증가하기 시작했습니다. 서비스가 더 커지게 된다면 배보다 배꼽이 더 큰 상황이 될것 을 우려해서 DataDog
사용을 고민하기 시작했습니다.
두 번째로 선택한 방법은 Grafana
와 Datasource
를 AWS CloudWatch
로 사용하는 것입니다. Grafana
를 이용하면 커뮤니티에 많은 사람이 Dashboard
를 만들어놨기 때문에 Dashboard
구성은 큰 문제가 없다고 생각했고, Datasource
도 AWS CloudWatch
를 통해 가져오면 되었습니다. 하지만 서비스의 안정성을 위해 멀티 클라우드를 구성하기 시작했고, AWS CloudWatch
처럼 정보를 제공해주지 않는 클라우드 서비스도 있었습니다. 그뿐만 아니라 회사 내부에서의 추가 모니터링 요구사항이 있었는데, 이것은 AWS CloudWatch
에서 제공해주는 정보가 아닌 애플리케이션 레벨에서 제공되는 데이터(Java Heap Memory 등)였습니다.
결국 두 가지의 큰 이유로 다른 방법을 고려했습니다.
앞서 설명해 드린 것처럼 우선 해결해야 할 문제는 적은 비용으로 멀티 클라우드 모니터링이 가능하고, 애플리케이션 레벨의 정보도 모니터링이 가능해야 했습니다. 결국 3가지 문제를 해결하기 위해 Prometheus
+ Grafana
를 선택했습니다.
해당 기술 스택을 통해 작은 사이즈의 서버로 모니터링 구성이 가능했습니다. 그리고 클라우드 환경에 상관없이 인스턴스에 node_exporter
를 설치하여 서버 리소스를 제공해 주었고, 커뮤니티에서 이미 잘 만들어 놓은 Dashboard
와 애플리케이션 레벨의 정보를 제공하는 exporter
가 있었습니다.
문제를 해결하기 위해 적은 비용이 들었다고 말씀드렸지만, 이것은 서버 비용뿐만 아니라 모니터링 구성을 위한 인력도 예상보다 많이 들지 않았습니다.
이번 글에서의 세팅 환경은 Ubuntu 20.04
+ AWS
입니다.
Prometheus
는 metric
수집, 시각화, 알림 등을 제공하는 오픈 소스 모니터링 시스템입니다. Prometheus
를 통해 멀티 클라우드에 있는 모든 서버의 리소스를 수집할 예정입니다.
Prometheus
를 쉽게 설치하기 위해서 apt-get
을 통해서 설치했습니다.
아래의 명령어를 사용하면 Prometheus
와 node_exporter
가 함께 설치됩니다.
sudo apt-get update
sudo apt-get install -y prometheus prometheus-node-exporter prometheus-pushgateway prometheus-alertmanager
Prometehus
에서 제공하는 Web
환경 확인 및 Grafana와
연결하기 위해 9090
번 포트를 열어주면 되고, 9100
번 포트는 서버의 리소스를 제공하는 node_exporter
를 위해 사용됩니다.
정상적으로 설치가 되었는지 확인하려면 아래의 명령어를 통해 확인이 가능합니다.
prometheus --version
----------
prometheus, version 2.15.2+ds (branch: debian/sid, revision: 2.15.2+ds-2)
build user: pkg-go-maintainers@lists.alioth.debian.org
build date: 20200113-10:10:54
go version: go1.13.7
prometheus-node-exporter --version
----------
node_exporter, version 0.18.1+ds (branch: debian/sid, revision: 0.18.1+ds-2)
build user: pkg-go-maintainers@lists.alioth.debian.org
build date: 20200221-05:56:03
go version: go1.13.8
명령어를 통해서 확인하는 방법 외에도 URL
을 입력해서 Prometheus
와 node_exporter
가 잘 설치되었는지 확인이 가능합니다.
Grafana
는 metric
데이터를 시각화 하는데 가장 최적화된 대시보드를 제공해주는 오픈소스 입니다. Grafana
를 통해 Prometheus
의 데이터를 시각화를 진행합니다.
Grafana
는 Prometheus
설치하는 법과 같은 방법으로 설치가 가능하지만 추가적인 설정이 필요합니다.
아래의 명령어를 통해서 설치하면 Key
를 추가해달라는 에러가 발생하게 됩니다. 이 문제를 해결 방법은 매우 간단합니다.
sudo apt-get install grafana
http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x8c8c34c524098cb6 에 접속해서 본문을 복사합니다.
이어서 grafana-key.txt
라는 파일을 vi
를 통해 열어줍니다.
vi grafana-key.txt
명령어를 통해 복사한 내용을 넣고 저장합니다.
이어서 아래의 명령어를 통해 Key
를 추가해줍니다.
sudo apt-key add grafana-key.txt
다음 명령어를 차례로 실행해서 Grafana
를 설치해줍니다.
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
curl https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo apt-get install grafana
sudo systemctl daemon-reload
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
다음 명령어를 통해 Grafana
가 잘 설치되었는지 확인이 가능합니다.
grafana-server -v
----------
Version 9.0.2 (commit: 0641b5d0cd, branch: HEAD)
명령어를 통해서 확인하는 방법 외에도 다음 URL
을 입력해서 Grafana
가 잘 설치되었는지 확인이 가능합니다.
http://grafanaIp:9100
node_exporter
는 서버의 리소스를 수집하여 metric
을 제공합니다. 만약 서버 리소스 모니터링은 필요가 없고, 애플리케이션 레벨에서 제공하는 데이터만 필요하시다면 생략하셔도 됩니다.
아래의 명령어를 통해 설치가 가능하고, 2020년 정도의 버전이 설치됩니다. 이 버전은 Grafana
에서 모니터링 할 때 어느 정도 필요한 정보가 제공됩니다.
sudo apt-get update
sudo apt-get install prometheus-node-exporter
Ubuntu 20.04
버전 이상과 같이 apt-get
명령어를 통해 설치해도 됩니다. 하지만 Ubuntu 20.04
버전 미만에서 Grafana
에서 모니터링 할 때 필요한 정보가 제공이 안 됩니다. 결국 Ubuntu 20.04
버전에서 사용되는 node_exporter
와 근접한 버전을 직접 설치했습니다.
아래의 명령어를 실행하여 node_exporter
를 설치합니다.
sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus # 유저 추가
cd ~
wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz # 20.04버전에 설치되는 버전 다운로드
tar -xvf node_exporter-0.18.1.linux-amd64.tar.gz
cd node_exporter-0.18.1.linux-amd64/ # 폴더 이동
sudo mv node_exporter /usr/local/bin/prometheus-node-exporter # 실행 파일 이동
node_exporter
를 systemctl
명령어로 실행하기 위해 아래의 명령어를 통해 파일을 작성해줍니다.
sudo vi /etc/systemd/system/prometheus-node-exporter.service
이어서 아래의 내용을 붙여 넣습니다.
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus-node-exporter
[Install]
WantedBy=multi-user.target
아래 명령어를 통해 node_exporter
실행 및 재기동 시 자동으로 node_exporter
가 실행이 되도록 설정을 해줍니다.
sudo systemctl daemon-reload
sudo systemctl start prometheus-node-exporter # node_exporter 실행
sudo systemctl enable prometheus-node-exporter # 재기동시 node_exporter 자동으로 실행되도록 설정
아래 명령어를 통해 node_exporter
가 잘 설치되었는지 확인이 가능합니다.
prometheus-node-exporter --version
----------
node_exporter, version 0.18.1 (branch: HEAD, revision: 3db77732e925c08f675d7404a8c46466b2ece83e)
build user: root@b50852a1acba
build date: 20190604-16:41:18
go version: go1.12.5!
명령어를 통해서 확인하는 방법 외에도, 다음 URL을 입력해서 node_exporter
가 잘 설치되었는지 확인이 가능합니다.
http://nodeexporterIp:9090
기본적으로 9090
, 3000
, 9100
번 포트를 열어주면 됩니다.
Grafana
와 Prometheus
의 연결 및 Prometheus Web
접속을 위해 9090
포트를 열어주고, Grafana
에 접속하기 위해 3000
번 포트를 열어줍니다. 마지막으로 Prometheus
와 node_exporter
를 연결하기 위해 node_exporter
서버의 9100
번 포트를 열어줍니다.
서버 리소스 모니터링을 위한 준비는 거의 다 끝이 났습니다.
Prometheus
가 node_exporter
에게 주기적으로 poll
을 해서 데이터를 가져오기 위해 추가로 데이터를 제공해주는 node_exporter
정보를 작성해줘야 합니다.
아래의 명령어를 사용하면 기본적으로 Prometheus
설치 시 설정된 정보가 나타납니다.
sudo vi /etc/prometheus/prometheus.yml
Prometheus
는 스스로의 서버 리소스를 제공하도록 node_exporter
가 함께 설치되고 Prometheus
스스로의 서버 리소스를 모니터링 할 수 있도록 설정이 되어 있습니다.
rule_files:
## 생략 ##
scrape_configs:
## 생략 ##
- job_name: 'prometheus'
## 생략 ##
- job_name: node
static_configs:
- targets: ['localhost:9100']
우리도 Prometheus
와 같은 node
라는 job
밑에 설정해도 괜찮겠지만, 따로 관리해보려고 합니다. job_name
은 soora_node
로 지정하고 모니터링 대상을 지정해줍니다.
rule_files:
## 생략 ##
scrape_configs:
## 생략 ##
- job_name: 'prometheus'
## 생략 ##
- job_name: node
static_configs:
- targets: ['localhost:9100']
- job_name: soora_node
static_configs:
- targets: ['server1Ip:9100', 'server2Ip:9100']
설정이 완료되면 다음 명령어를 통해 재시작해줍니다.
sudo systemctl restart prometheus
다음 URL
로 접속하고 메뉴에서 Status > Targets
로 들어가면 다음과 같이 soora_node
와 서버 2대가 설정이 된 것이 보입니다.
Prometheus
를 통해 데이터를 받아올 준비가 되어있으니, Grafana
와 연결을 진행하면 됩니다.
http://grafanaIp:3000 에 들어가게 되면 다음과 같이 로그인을 요구하는데 admin / admin
으로 초기 설정이 되어있습니다.
로그인 후 좌측 메뉴를 살펴보시면 Configuration > DataSource
라는 메뉴가 있습니다. 해당 메뉴를 통해 Prometheus
와 연결이 가능합니다.
Add Data source
를 누르게 되면 Prometheus
를 추가 해줍니다.
상세하게 설정이 가능합니다. 여기서 제일 중요한 HTTP URL
을 http://prometheusIp:9090을 입력해줍니다.
Prometheus
와 연결이 정상적으로 되는지 확인하기 위해 Save & Test
버튼을 누릅니다. 만약 정상적으로 잘 된다면 Data source is working.
이라고 나올 것입니다.
Promethus
와 Grafana
의 연결이 잘 되었으면 Dashboard
를 통해 시각화하면 됩니다. PromQL
을 배워서 직접 Dashboard
를 꾸밀 수도 있겠지만, 이미 커뮤니티에 올라온 Dashboard
를 사용하는 것도 좋은 방법입니다.
좌측에 Dashboards > import
를 선택하면 커뮤니티에 올라온 Dashboard
나 백업해놓으신 Dashboard
를 추가할 수 있습니다.
https://grafana.com/grafana/dashboards 에 들어가면 이미 만들어진 Dashboard
를 사용할 수 있습니다.
Dashboard
의 번호를 입력하고 Load
를 누르면 Import
가 됩니다. 여기서 Prometheus
를 설정해줘야 하는데, 우리는 앞서 설정한 것으로 선택하면 됩니다.
정상적으로 잘 되었으면 Prometheus
의 정보를 바탕으로 Dashboard
가 표현이 됩니다. 만약 표시가 안 된다면 Dashboard
에서 필요로 하는 정보가 node_exporter
에서 제공하지 않기 때문일 수 있습니다. 이때는 node_exporter
를 업데이트 해보는 것도 좋은 방법입니다.
Elastic Beanstalk
에서 생성되는 EC2
는 이벤트가 발생하면 삭제되었다가 새롭게 생성이 됩니다. 이러한 Elastic Beanstalk
특성 때문에 node_exporter
를 수동으로 설치하시면 언제든 제거가 될 수 있습니다.
Elastic Beanstalk
은 기본적으로 AMI
를 변경할 수 있는데, 이 기능을 이용하면 쉽게 문제를 해결할 수 있습니다.
우선 아무런 AMI
를 기반으로 새로운 AMI
를 생성하면 Elastic Beanstalk
에서 필요한 환경으로 구성이 안 될 수 있기 때문에 기존에 Elastic Beanstalk
에서 사용하던 AMI
를 기반으로 새로운 AMI
를 생성해야 합니다.
기존에 Elastic Beanstalk
에서 사용하던 AMI
의 ID
를 확인하는 방법은 Elastic Beanstalk > 환경 > 구성 > 용량 > AMI ID
을 통해 확인이 가능합니다.
Elastic Beanstalk
에서 사용 중인 AMI
의 ID
를 바탕으로 EC2
를 생성합니다. 그리고 EC2
에는 node_exporter
를 설치하고 새로운 AMI
를 만들어 줍니다. node_exporter
가 설치된 AMI
가 새롭게 생성이 되었다면 다시 Elastic Beanstalk > 환경 > 구성 > 용량 > AMI ID
에 새로운 AMI
의 ID
를 넣어주면 됩니다.
Elastic Beanstalk
, Auto Scaling
을 사용하면 자동으로 EC2
가 추가되거나 제거가 됩니다. 이때마다 prometheus.yml
을 수정할 수는 없으니 자동으로 수정/추가되도록 해야 합니다.
이 방법은 AWS
에서도 https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-PrometheusEC2.html 를 통해 설명해주고 있습니다.
다음 명령어를 통해 설정 파일을 수정합니다.
sudo vi /etc/prometheus/prometheus.yml
아래 내용을 추가합니다.
- job_name: soora_auto_node
ec2_sd_configs:
- region: ap-northeast-2
port: 9100
위의 설정을 추가하면 ap-northeast-2
에 있는 EC2
는 자동으로 Prometheus
에 추가되거나 삭제됩니다. 하지만 Prometheus
서버에 EC2
를 조회할 수 있는 권한이 필요한데, AWS > EC2
에서 Prometheus
인스턴스 선택 후 작업 > 보안 > IAM 역할 수정
을 눌러줍니다.
EC2
를 조회할 수 있는 IAM
을 선택해줍니다. 만약 조회할 수 있는 IAM
이 없다면 읽기 권한만 있는 IAM
을 만들어주면 됩니다.
정상적으로 모든 EC2
를 가져오는 것이 확인이 가능합니다. 만약 어떤 EC2
는 필요 없다고 생각하신다면 filter
를 통해서도 제거할 수 있습니다.
모니터링을 구축 후 서버 전반적으로 어느 부분이 부족하고, 넉넉한지 파악할 수 있었습니다. 모니터링을 통해 개발자들이 안정적으로 운영하면서 심적인 안정감도 취할 수 있도록 도울 것 입니다. 그리고 누적된 서버의 정보를 가지고 어느 시간대에 많은 요청이 생기는지 파악이 가능할것 입니다. 이 정보를 가지고 미래를 예측해서 더욱더 안정적인 서비스를 예측할 수 있기를 바라고 있습니다.
혹시 어플리케이션 서버에만 로그를 수집하셨나요?
예를 들면 rds나 redis의 경우는 별도로 모니터링하셨는지 궁금해요!