“전투에서 실패한 지휘관은 용서할 수 있지만 경계에서 실패하는 지휘관은 용서할 수 없다”는 말이 있습니다. 이 말을 서비스를 운영하는 개발자에게 비춰 보면 장애는 언제든지 발생할 수 있더라도 그만큼 모니터링을 잘 해야 한다는 뜻입니다. - 김영한 CTO
앞에 포스팅에서 기본적인 인프라 구성해보았다. 이번 포스팅에서는 웹서버에 Docker 컨테이너 기반 Prometheus와 Grafana를 설치하고 대시보드를 생성하는 과정을 다뤄본다.
참고. https://dev-ljw1126.tistory.com/458
Prometheus는 private subnet에 위치한 MySQL과 Redis 서버의 지표를 각 *exporter를 통해서 주기적으로 수집하게 된다. 그리고 Grafana는 Prometheus(DataSource)에서 수집한 지표를 시각화하여 대시보드로 나타낸다. (*둘 다 오픈소스 툴)
polling과 pulling 의 차이
- polling : 서버에 결과를 주기적으로 요청하는 것
- pulling : 서버의 데이터를 주기적으로 가져가는 것
Security Group 설정
전체 Security Group 설정을 표로 정리해보았다. 참고로 (private subnet에 위치한) MySQL과 Redis 지정된 포트로 (public subnet에 위치한) 웹서버에서 접근 가능하고, 외부에서는 직접 접근은 불가능하다.
집에서 웹 서버 접근하기 위해서는 아래 3가지가 설정되어 있어야 한다
- Security Group 에 지정 포트, ip 허용
- floating ip 할당
- Router에 Internet Gateway 연결
Prometheus, Grafana 컨테이너
먼저 웹 서버에 Docker 와 docker-compose 설치하고 Prometheus와 Grafana 컨테이너를 실행해본다
구분
① Prometheus : 웹 어플리케이션/MySQL/redis 지표 수집
② Grafana : Prometheus(=DataSource) 연동하여 대시보드 생성
docker 설치
$ sudo su
$ apt update && apt install -y docker.io
$ systemctl start docker
$ systemctl enable docker
$ systemctl status docker
docker ps 실행하면 권한이 없어서 permission denied 출력이 될 경우 아래 명령어 입력
$ chmod 666 /var/run/docker.sock
$ chown root:docker /var/run/docker.sock
$ docker ps -a
참고. https://github.com/occidere/TIL/issues/116
docker-compose 설치
$ sudo apt install -y docker-compose
$ docker-compose -v
docker-compose version 1.25.0, build unknown
$ which docker-compose
/usr/bin/docker-compose
$ $ sudo chmod +x /usr/bin/docker-compose // 실행 권한 부여
docker network 생성
$ docker network ls
$ docker network create --driver bridge mybridge
docker-compose.yml 생성
prometheus와 grafana 컨테이너를 함께 관리하고 배포하기 위해 docker-compose.yml 생성한다
$ vim docker-compose.yml // 아래 내용 복사 붙여넣기
version : "3"
services:
prom:
image: prom/prometheus-linux-amd64
container_name: prom
hostname: prom
ports:
- "9090:9090"
volumes:
- /home/prom/data:/data
- /home/prom/conf:/etc/prometheus
networks:
- mybridge
grafana:
image: grafana/grafana
container_name: grafana
hostname: grafana
ports:
- "3000:3000"
networks:
- mybridge
networks:
mybridge:
driver: bridge
prometheus volumn 마운트 용도로 웹 서버에 디렉토리를 생성하고, prometheus.yml 설정 파일을 생성한다.
+ promtheus.yml 설정 안에는 지표 수집 대상(ex. *exporter, spring-actuator) 정보를 기재한다.
+ container 실행시 volumn 마운트 되어 있기 때문에 해당 설정 정보를 가지고 Prometheus에서 지표를 수집한다.
+ 웹 서버의 8080 포트 정보는 spring-actuator 관련 내용으로 이번 포스팅에서는 다루지 않는다
$ sudo mkdir -p /home/prom /home/prom/data /home/prom/conf
$ sudo chmod 777 /home/prom /home/prom/data /home/prom/conf
$ cd /home/prom/conf
$ vim prometheus.yml
global:
scrape_interval: 5s
evaluation_interval: 5s
scrape_configs:
- job_name: spring-actuator
metrics_path: /actuator/prometheus
static_configs:
- targets: ['<웹서버 private ip>:8080']
- job_name: mysqld_exporter
static_configs:
- targets: ['<MySQL private ip>:9104']
- job_name: mysql_node_exporter
static_configs:
- targets: ['<MySQL private ip>:9100']
- job_name: redis_exporter
static_configs:
- targets: ['<Redis private ip>:9121']
# :wq 저장 후
$ sudo chmod 644 prometheus.yml
docker-compose.yml 위치한 디렉토리 이동 후 백그라운드로 실행하여 컨테이너가 올라온 것을 확인가능하다
$ docker-compose up -d
Prometheus 와 Grafana 웹 콘솔에 접속해본다.
집에서 접근하기 위해서는 web 서버의 security group에 tcp 9090포트와 3000포트 접속 허용이 되어 있어야 한다.
Prometheus 접속 주소: http://<웹서버 public ip>:9090
Grafana 접속 주소 : http://<웹 서버 public ip>:3000 (default 계정 admin / admin)
MySQL 서버 설정, *exporter 설치
MySQL 8.0 인스턴스 생성, root 비밀번호 설정 등은 이번 포스팅에서 다루지 않는다(앞 포스팅 참고)
private subnet에 위치해 있고, web 서버를 통해서만 MySQL 서버에 접속할 수 있다
$ ssh -i ~/.ssh/helloCloud.pem ubuntu@<Redis private ip>
1. node_exporter 설치 (defulat port :9100)
참고. prometheus/node_exporter 공식 저장소
https://github.com/prometheus/node_exporter/
/home/ubuntu 디렉토리에 작업했는데, 유도리있게 생성해서 관리하도록 한다 (ex. /opt/exporter/ )
$ cd /home/ubuntu
$ wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz
$ tar -xzf node_exporter-1.5.0.linux-amd64.tar.gz
$ cd node_exporter-1.5.0.linux-amd64
$ sudo cp node_exporter /usr/local/bin/
$ vim start_node_exporter.sh // 아래 내용 추가
nohup node_exporter &
# :wq 저장 후 나옴, 실행 권한 부여 후 sciprt실행
$ chmod +x start_node_exporter.sh
$ sh start_node_exporter.sh // 실행
2. mysqld_exporter 설치 (default port :9104)
참고. prometheus/mysqld_exporter 공식 저장소
https://github.com/prometheus/mysqld_exporter
mysqld_exporter에서 사용하기 위한 계정과 권한을 생성한다
$ mysql uroot -p
mysql> DROP USER IF EXISTS 'exporter'@'localhost';
mysql> CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'exporter123' WITH MAX_USER_CONNECTIONS 3;
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
mysql> flush privileges;
mysql> exit;
마찬가지로 버전 정보 확인 후 wget으로 내려받아 실행한다
$ cd /home/ubuntu
$ wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz
$ tar -xzf mysqld_exporter-0.14.0.linux-amd64.tar.gz
$ cd mysqld_exporter-0.14.0.linux-amd64
$ sudo cp mysqld_exporter /usr/local/bin/
.my.cnf, 실행 script 생성
mysqld_exporter에서 .my.cnf 정보로 MySQL 접속하여 정보를 수집한다
$ vim .my.cnf // 아래 내용 추가,당연히 mysql 계정/권한 생성되어 있어야 한다
[client]
host=localhost
user=exporter
password=exporter123
$ vim start_mysqld_exporter.sh // 아래 내용 추가
nohup mysqld_exporter --config.my-cnf="/home/exporter/.my.cnf" &
# :wq 저장 후
$ chmod +x start_mysqld_exporter.sh
$ sh start_mysqld_exporter.sh
마지막으로 프로세스, 포트가 잘 올라와 있는지 확인한다
Redis 설정
private subnet에 Redis 인스턴스를 생성해서 할당한다(생략). 마찬가지로 "redis-sg"로 security group을 따로 관리해준다.
MySQL 서버와 마찬가지로 web 서버에서 ssh(22/tcp) 접속해준다
$ ssh -i ~/.ssh/helloCloud.pem ubuntu@<MySQL private ip>
1. ~/redis/redis.conf 수정
참고로 nhn cloud 가이드 라인에서는 보안상 port와 비밀번호 수정할 것을 권장하고 있다. 지금은 테스트이기 때문에 bind 설정만 변경하고 redis를 재시작해준다.
$ vim ~/redis/redis.conf // 아래 설정 추가
#bind 127.0.0.1 -::1
bind 0.0.0.0
$ systemctl restart redis
아래와 같이 포트가 확인되야 한다.
2. redis_exporter 설치
참고. https://github.com/oliver006/redis_exporter 공식 저장소
마찬가지로 다운로드 후 설치해주도록 한다
$ wget https://github.com/oliver006/redis_exporter/releases/download/v1.62.0/redis_exporter-v1.62.0.linux-amd64.tar.gz
$ tar -xzf redis_exporter-v1.62.0.linux-amd64.tar.gz
$ cd redis_exporter-v1.62.0.linux-amd64
$ sudo mv redis_exporter /usr/local/bin/
$ vim start_redis_exporter.sh // 아래 내용 추가 후 저장
nohup redis_exporter &
$ chmod +x start_redis_exporter.sh
$ sh start_redis_exporter.sh
대시보드 생성
먼저 Prometheus에서 *.yml 설정 정보에 따라 수집하고 있는지 확인해본다
Prometheus 접속 주소 : http://<public ip>:9090
+ 앞서 설치한 *exporter 3개에서 정상적으로 수집(1) 하고 있는 것을 확인할 수 있었다.
이제 Grafana 웹 콘솔에 접속하여 Prometheus를 연결하고 대시보드는 생성해본다
Grafana 접속 주소 : http://<웹 서버 public ip>:3000 (default 계정 admin / admin)
[Connections > Data sources] 메뉴로 이동해서 Prometheus 선택해준다
현재 mybridge 네트워크에 컨테이너가 위치하고 있기 때문에 http://<컨테이너명>:9090 주소로 입력하였다.
하단에 "Save & test" 버튼 눌러서 정상적으로 연결되는지 확인한다. 이제 Prometheus 데이터 사용하여 대시보드를 생성한다.
[Connections > Data sources] 메뉴에서 Prometheus 항목에 "Build a dashboard" 버튼을 누른다
간단하게 템플릿 대시보드를 import 해서 생성하기 때문에 아래 "import dashboard" 버튼을 누른다
JSON 설정 파일을 drag & drop 하거나, 대시보드 템플릿의 주소 or JSON 설정 내용을 복사 붙여넣기 하면된다. 간단하게 아래 대시보드 탬플릿 주소를 복사/붙여 넣기 한다.
참고 버전에 따라 property 명칭이 달라서 호환 안 되어 대시보드에 아무것도 표기 안 되는 경우가 있다. 이때는 호환되는 대시보드 템플릿을 찾거나 직접 대시보드를 생성하거나 수정해야 한다.
참고. Grafana Lab Dashboard
jvm(micrometer) - https://grafana.com/grafana/dashboards/4701-jvm-micrometer/
Spring Boot HikariCP / JDBC - https://grafana.com/grafana/dashboards/6083-spring-boot-hikaricp-jdbc/
Spring Boot 3.x Statistics - https://grafana.com/grafana/dashboards/19004-spring-boot-statistics/
MySQL - Overview - https://grafana.com/grafana/dashboards/7362-mysql-overview/
참고. https://grafana.com/grafana/dashboards/
다음 화면에서 datasource 항목에 Prometheus를 선택하고 "import" 버튼을 누른다
정상적으로 JVM 대시보드가 출력되었다. (*안 나오는 지표가 있으면 property 속성을 수정해준다)
Redis의 경우 Redis plugin 설치하여 연결해주면 기본 대시보드를 import 해서 사용할 수 있다 (*단일 redis 인스턴스)
우측 상단에 "install" 버튼이 위치해 있는데 설치해준다.
[Connections > Data sources] 메뉴에 Redis가 추가되어 있을 건데, 아래와 같이 접속 정보, 비밀번호 등을 입력 후 저장한다
+ redis 서버가 private subnet에 위치함
+ redis 서버의 private ip , 기본 포트 6379 접속 정보 설정
+ 마찬가지로 웹 서버에서의 트래픽 접근 허용 위해 Security Group 설정이 되어 있어야 한다
redis-datasource 상세에서 Dashboard 탭에 이동하면 아래 두 개의 기본 템플릿을 제공해준다. 필요한 것을 import 한다
그리고 Dashboards 메뉴를 보면 Redis 관련 대시보드가 생성되어 있을 것이다.
*Redis 대시보드
쉽지 않은 여정이었다.
실무에서 모니터링이 없을 때 항상 서버에 접속해서 로그를 확인하거나
로컬 프로젝트 실행해서 확인하는 형태로 일을 했었다.
그러다보니 원인 파악이 쉽지 않았고 가정/추론에 의해 문제를 해결했었는데,
오픈 소스툴을 활용하여 다양한 지표를 대시보드 통해 확인가능해지면서 좀 더 객관적으로 원인을 찾아갈 수 있게 되었다.
(디스크와 네트워크 I/O, CPU와 메모리 사용량, HikariCP, Threads 등)
무료 오픈소스 툴만으로 이 정도의 인사이트를 얻을 수 있었는데
유료 툴은 얼마나 더 좋을지 싶다.
한달 전에 인프런의 인프라 강의를 시작으로 nhn cloud 까지
이렇게 또 하나의 경험을 쌓고 성장해간다.
'공부 > DevOps' 카테고리의 다른 글
[AWS] 서버리스 기반 URL 주소 단축 서비스 구현 - (1) 키 생성 람다 구현 (0) | 2024.09.24 |
---|---|
[AWS] VPC, Subnet, EC2 개발 인프라 구성 (선착순 쿠폰 발급 시스템) (0) | 2024.09.20 |
[NHN Cloud] 기본적인 웹 서버, DB 인프라 구축 (vpc, subnet, floating ip, ..) (5) | 2024.08.30 |
Jenkins 빌드 배포시 Slack 알림 설정 (5) (0) | 2023.07.16 |
[Ubuntu] /bin/bash로 기본 shell 변경하기 (0) | 2023.07.15 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!