▶︎ Zabbix
Zabbix는 엔터프라이즈 수준의 오픈 소스 모니터링 솔루션으로 네트워크와 서비스, 애플리케이션, 서버 등 IT 인프라의 상태를 실시간으로 모니터링하고 관리하는데에 사용된다.
zabbix는 다양한 모니터링 메트릭을 수집하고, 수집된 메트릭을 시각화하며, 장애 발생 시 알림을 발생 시키는 등의 다양한 기능을 제공한다.
그러면 zabbix를 Docker로 구축해보도록 하자.
▶︎ 실습 환경
- Proxmox VE 8
- VM OS: Ubuntu 22.04
- Docker
- Docker Compose
▶︎ Zabbix 구축
‣ 설치 순서
zabbix를 도커로 구축하기 위해서는 5개의 컨테이너가 필요하다.
1. mysql
- HOST DB
- mysql과 같은 호스트 DB가
zabbix-server-mysql
컨테이너와는 별도로 존재 해야함.
2. zabbix-server-mysql
- zabbix 서버의 백엔드 db 역할 수행
3. zabbix-web-nginx-mysql
- mysql 데이터베이스를 지원하는 nginx 웹 서버 기반의 zabbix 웹 인터페이스
4. zabbix-java-gateway
- java 모니터링을 위한 서비스로 필요에 따라 설치함.
5. zabbix-agent (테스트용 컨테이너)
- 클라이언트에 설치되는 것으로 OS와 연동하여 데이터를 수집
- 이번 실습에서는 테스트를 위해
zabbix-agent
컨테이너를 띄워 정상적으로 데이터가 수집되는지 확인
‣ 이미지 다운로드
zabbix 공식 이미지 저장소에서 컨테이너 이미지 pull
docker pull mysql
docker pull zabbix/zabbix-server-mysql
docker pull zabbix/zabbix-web-nginx-mysql
docker pull zabbix/zabbix-java-gateway
docker pull zabbix/zabbix-agent
이미지가 정상적으로 다운로드 됐는지 확인
docker images | grep -E "^zabbix|mysql"
‣ 방화벽 설정
서버에 방화벽 정책이 명시되어 있는 경우
하기 포트를 오픈해주어야 함.
web: 80/TCP
mysql: 3306/TCP
zabbix server: 10051/TCP
zabbix agent: 10050/TCP
zabbix-java-gateway: 10052/TCP
‣ 컨테이너 생성
include
키워드를 사용하여 zabbix 구동에 필요한 각 컨테이너별 YAML 작성
~/zabbix/docker-compose.yaml
version: "3.9"
include:
- "composes/mysql-server.yaml"
- "composes/zabbix-java-gateway.yaml"
- "composes/zabbix-server-mysql.yaml"
- "composes/zabbix-web-nginx-mysql.yaml"
- "composes/zabbix-agent.yaml"
networks:
zabbix-net:
driver: bridge
external: false
volumes:
mysql-server: {}
1. host용 MySQL
~/zabbix/composes/mysql-server.yaml
services:
mysql-server:
image: mysql:8.0-oracle
restart: always
volumes:
- type: volume
source: mysql-server
target: "/var/lib/mysql"
environment:
MYSQL_DATABASE: "zabbix"
MYSQL_USER: "zabbix"
MYSQL_PASSWORD: "zabbix"
MYSQL_ROOT_PASSWORD: "zabbix"
command: --character-set-server=utf8 --collation-server=utf8_bin --default-authentication-plugin=mysql_native_password
networks:
- "zabbix-net"
container_name: "mysql-server"
2. zabbix java gateway (선택)
‣ java 관련 검사를 수집하기에 tomcat, jeus 등의 WAS 모니터링이 필요한 경우 설치
~/zabbix/composes/zabbix-java-gateway.yaml
services:
zabbix-java-gateway:
image:
zabbix/zabbix-java-gateway:alpine-6.4-latest
restart: always
container_name: zabbix-java-gateway
networks:
- "zabbix-net"
3. zabbix server mysql
~/zabbix/Dockerfiles/zabbix-server.dockerfile
FROM zabbix/zabbix-server-mysql:alpine-6.4-latest
USER root
RUN apk update && apk add --no-cache curl
해당 컨테이너에서는 추후에 slack-메신저-연동 할 때 curl
패키지가 필요하다.
그래서 curl을 설치한 이미지로 빌드하도록 하겠다.
~/zabbix/composes/zabbix-server-mysql.yaml
services:
zabbix-server-mysql:
build:
context: ../Dockerfiles
dockerfile: zabbix-server.dockerfile
restart: always
environment:
DB_SERVER_HOST: "mysql-server"
MYSQL_DATABASE: "zabbix"
MYSQL_USER: "zabbix"
MYSQL_PASSWORD: "zabbix"
MYSQL_ROOT_PASSWORD: "zabbix"
ZBX_JAVAGATEWAY: "zabbix-java-gateway"
ports:
- "10051:10051"
volumes:
- type: bind
source: "../alertscripts"
target: "/usr/lib/zabbix/alertscripts"
networks:
- "zabbix-net"
container_name: "zabbix-server-mysql"
4. zabbix web nginx mysql
~/zabbix/composes/zabbix-web-nginx-mysql.yaml
services:
zabbix-web-nginx-mysql:
image: zabbix/zabbix-web-nginx-mysql:alpine-6.4-latest
restart: always
environment:
ZBX_SERVER_HOST: "zabbix-server-mysql"
DB_SERVER_HOST: "mysql-server"
MYSQL_DATABASE: "zabbix"
MYSQL_USER: "zabbix"
MYSQL_PASSWORD: "zabbix"
MYSQL_ROOT_PASSWORD: "zabbix"
ports:
- "80:8080"
networks:
- "zabbix-net"
container_name: zabbix-web-nginx-mysql
5. zabbix agent 생성
~/zabbix/composes/zabbix-agent.yaml
services:
zabbix-agent:
image: zabbix/zabbix-agent
restart: always
environment:
ZBX_HOSTNAME: "Zabbix server"
ZBX_SERVER_HOST: "zabbix-server-mysql"
container_name: zabbix-agent
networks:
- "zabbix-net"
agent 컨테이너 IP 확인
zabbix-agent
컨테이너가 정상적으로 배포되었다면 해당 컨테이너의 IP 주소를 확인해보자.
docker inspect zabbix-agent | grep "\"IPAddress\""
zabbix 웹에서 설정 값으로 넣어주어야 하니 기억하고 있자.
‣ 서비스 확인
docker-compose ps
5개의 컨테이너가 정상적으로 생성되었다.
브라우저에 http://<서버IP>
로 접속을 시도하면 아래와 같이 zabbix 초기 로그인 화면이 뜰 것이다.
초기 사용자 계정 정보의 경우 아래와 같다.
로그인 후 패스워드를 변경해주는 것을 권장한다.
- ID:
Admin
- PW:
zabbix
로그인을 하게되면 기본 대시보드를 확인할 수 있다.
zabbix agent를 배포하긴 했지만, 호스트 등록이 정상적으로 이루어지지 않아 system information
에 빨간 에러 창이 발생한 것을 볼 수 있다.
Monitoring - Hosts - Zabbix server - Host를 클릭하여
agent 주소로 설정된 127.0.0.1
을 agent 컨테이너 IP에서 확인했던 agent 컨테이너의 IP로 수정하여 저장하자.
업데이트 후 대시보드로 다시 돌아가면 1개의 서버가 정상적으로 모니터링 되고있는 것을 볼 수 있을 것이다.
▶︎ Agent 설치
- Agent 서버 환경
- Ubuntu 22.04
이번에는 Zabbix Agent
를 모니터링 대상 서버에 직접 설치하여 대상 서버도 zabbix 서버에서 모니터링이 되도록 구축해보자.
‣ 설치
1. wget 명령어를 사용하여 아래와 같이 zabbix release package를 다운로드
wget -O zabbix.ubuntu22.04.deb https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.0-3+ubuntu22.04_all.deb
2. 그리고 Package management 도구를 이용하여 다운로드 받은 zabbix 패키지를 설치해주자.
sudo dpkg -i zabbix.ubuntu22.04.deb
3. 마지막으로 패키지를 모두 업데이트
sudo apt-get update -y
zabbix가 정상적으로 설치되었는지 확인
$ apt list --installed 2>/dev/null | grep "^zabbix"
zabbix-release/now 1:6.0-3+ubuntu22.04 all [installed,upgradable to: 1:6.0-4+ubuntu22.04]
정상적으로 확인이 되었다.
4. 이제 에이전트를 내려받고 설치
sudo apt-get install -y zabbix-agent2
‣ 설정 파일 수정
/etc/zabbix/zabbix_agent2.conf
/etc/zabbix/zabbix_agent2.conf
위 IP는 zabbix Docker가 구동 중인 Host 서버의 IP 주소를 기입해주면 된다.
본인의 경우 zabbix가 구동 중인 서버의 IP가 192.168.219.179
이므로 위처럼 적어주었다.
아래 부분에는 호스트 이름을 적어주도록 하자.
/etc/zabbix/zabbix_agent2.conf
모두 수정했다면 :wq
로 저장하고 나오도록 하자.
그리고 zabbix 에이전트에 대한 서비스를 등록하고, Daemon을 재기동해주자.
sudo systemctl enable --now zabbix-agent2
‣ zabbix web 이동
zabbix web page로 들어가 호스트를 추가해주자.
(Monitoring - Hosts - Create host)
에이전트 서버의 /etc/zabbix/zabbix_agent2.conf
파일에서 적었던 호스트 이름을 적어주고, Templates에 위와 같이 Linux by Zabbix agent
를 찾아 선택해주도록 하자.
Host groups의 경우 Linux servers
를 선택
아래와 같이 에어전트를 설치한 호스트의 IP를 적어주고, 추가를 눌러주자.
에이전트를 설치한 호스트 이름의 상태가 활성 상태가 되어있다면 성공이다.
대시보드로 돌아가면 nginx-proxy-manager
에이전트의 CPU 모니터링이 안뜨는데 이건 수동으로 따로 설정 해주어야 한다.
Top hosts by CPU utilization
톱니바퀴 클릭 - 아래와 같이 Linux server
의 nginx proxy manager
에이전트를 추가 후 적용
그럼 이제 기본적인 모니터링 설정은 마무리가 되었다.
▶︎ 알림 설정
이번에는 모니터링 중인 Agent에 시스템 리소스 현황(cpu,memory,disk,port)을 확인하여 알림을 보내는 과정을 정리해보겠다.
먼저 Zabbix web 페이지로 접속하여
"경고 - 미디어 타입"로 들어가게 되면 아래와 같이 알림을 보낼 수 있는 플랫폼 목록을 확인할 수 있다.
또는 셸 스크립트를 작성하여 알림을 보낼 수 있는 방법도 존재한다.
본인의 경우 셸 스크립트를 작성하여 알림을 보낼 수 있는 방법에 대해 작성해보겠다.
먼저 zabbix에서는 AlertScriptsPath에 스크립트 파일을 올려 알림 서비스를 활용해볼 수 있다.
그러기 위해서 먼저 Zabbix 서버의 터미널로 접속한 후, zabbix-server-mysql
컨테이너의 터미널로 진입하자.
docker exec -it zabbix-server-mysql /bin/bash
그런 다음 /etc/zabbix/zabbix_server.conf
파일에서 아래 스트링을 검색하여 AlertScriptsPath
에 대한 경로를 확인해보자.
grep "^AlertScriptsPath" /etc/zabbix/zabbix_server.conf
/usr/lib/zabbix/alertscripts
이라고 명시되어 있다.
‣ 스크립트 작성
zabbix-server-mysql
컨테이너에서 exit
명령어로 빠져나온 후
./alertscripts
경로로 이동하여 아래와 같은 스크립트 파일을 만들어주자.
참고로 zabbix-server-mysql
컨테이너의 /usr/lib/zabbix/alertscripts
디렉토리를 호스트의 alertscripts
폴더와 바인드 마운트를 해줬기 때문에 컨테이너 간 파일이 실시간으로 공유된다.
해당 스크립트는 파라메터를 입력 받아 slack webhook으로 메시지를 보내도록 한다.
{% include codeHeader.html name="slack.sh" %}
#!/usr/bin/bash
# 메시지 보낼 채널
CHANNEL="#server_notification"
# 채널에서 표시될 사용자 이름
USERNAME="Server Bot"
# 채널에 사용하고자 하는 아이콘
EMOJI=":heart:"
# 스크립트 실행 시 삽입할 파라메터
TITLE="$1"
MESSAGE="$2"
# Set api url
PAYLOAD="payload={\"channel\": \"$CHANNEL\", \"username\": \"$USERNAME\", \"text\": \"*$TITLE*\n\n$MESSAGE\", \"icon_emji\": \"$EMOJI\"}"
webHookURI="<WEBHOOK URI>"
# 메시지 전송
curl -X POST --data-urlencode "$PAYLOAD" "$webHookURI"
‣ slack 메신저 연동
다시 zabbix web으로 들어가서 '경고 - 미디어 타입'으로 이동한 후, '연락 방법 생성'을 클릭해주자.
- 이름:
원하는 이름
- 종류:
스크립트
- 스크립트 방식으로 알림을 보낼 것이기에
- 스크립트 이름:
스크립트파일이름.sh
/usr/lib/zabbix/alertscripts
경로에 존재하게 되는 스크립트 파일명을 넣어줘야 함- 해당 예시에서는
slack.sh
- 스크립트 파라미터:
스크립트에서 입력받는 파라메터 값
slack.sh {TITLE} {MESSAGE}
추가를 해주고 나서 '유저 - 유저'로 이동
Admin
유저 클릭 후 '연락 방법'으로 이동하여 아래와 같이 위에서 생성한 연락 방법으로 추가
추가했으면 '갱신'
다시 '경고 - 미디어 타입'으로 돌아와서 위에서 생성했던 slack
미디어 타입 테스트
그러면 아래와 같이 정상적으로 슬랙으로 알림이 오는 것을 확인할 수 있음
‣ 디스크 알림 설정
Zabbix agent 서버로 이동하여 아래 명령어를 실행해보자.
$ df -Th
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 1.2G 1.5M 1.2G 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv ext4 29G 18G 9.9G 64% /
tmpfs tmpfs 5.9G 0 5.9G 0% /dev/shm
tmpfs tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 ext4 2.0G 251M 1.6G 14% /boot # 감시 대상
tmpfs tmpfs 1.2G 4.0K 1.2G 1% /run/user/1000
여기서 /
경로의 사용량이 70%가 넘어갈 경우 슬랙으로 알림이 올 수 있도록 설정을 해보려고 한다.
먼저 '데이터 수집' - '호스트'로 들어가서 알림을 보내고자 하는 에이전트의 템플릿에 들어가서 아이템, 트리거를 설정해줘야 한다.
1. 아이템 생성
'아이템'을 클릭해서 새로운 아이템을 생성해주자.
옵션 | 설명 |
---|---|
*이름 | 아이템 이름 설정 |
종류 | 에이전트에 대한 모니터링이므로 ZABBIX 에이전트로 지정 |
*키 | Zabbix에서 사용되는 아이템 키(Item Key) 지정vfs.fs.size[/,pused] 해당 키는 파일 시스템에서 사용 가능한 공간을 모니터링 하기 위해 사용됨.여기서 /,pused 는 파일 시스템의 경로 및 옵션을 지정함./ 는 루트 디렉토리를 나타내며, pused 는 사용된 공간의 백분율을 의미 |
데이터형 | 수치 (float): 소수점으로 표현할 것이기에 해당 옵션으로 지정 |
단위 | %: 퍼센트 단위로 지정 |
*갱신 간격 | 몇 분, 몇 시간 간격으로 트리거가 발동되도록 할 것인지에 대한 옵션 본인의 경우 5분 간격으로 발동되도록 설정 |
2. 트리거 생성
아이템 작성이 모두 끝났다면 이제 트리거를 작성해보자.
옵션 | 설명 |
---|---|
*이름 | 트리거 이름 설정 |
심각도 | 해당 트리거가 발생했을 때 어느 정도의 심각도로 지정할 것인지 지정 |
*조건식 | last(/Linux by Zabbix agent/vfs.fs.size[/,pused])>70 은 Zabbix에서 사용되는 트리거 표현식이다. 해당 표현식은 특정 조건이 충족될 때 알림을 발생시키기 위해 사용된다.last() 함수는 최근 수집된 값 중 가장 최신 값을 가져오는 함수이다.Linux by Zabbix agent/vfs.fs.size[/,pused] 는 Zabbix 에이전트를 통해 수집된 루트 디렉토리의 사용된 공간의 백분율 값을 나타낸다.>70 은 비교 연산자로, 값이 70보다 큰 경우를 나타낸다즉, 해당 표현식은 "루트 디렉토리의 사용 공간이 70%를 초과하는 경우" 해당 트리거가 발동된다. |
3. 트리거 액션 생성
이제 마지막으로 생성된 트리거에 대한 액션을 생성해주면 마무리가 된다.
'경고' - '액션' - 'Trigger Action'으로 이동한 후, 새로운 액션을 생성하자.
먼저 트리거에 대한 액션 조건을 설정해보자.
옵션 | 설명 |
---|---|
종류 | 설정할 액션 종류 지정 |
오퍼레이터 | 트리거의 상태에 따라 특정 동작을 수행하는 방법을 지정 |
그리고 트리거 심각도에 대한 액션 조건도 설정하자.
오퍼레이션을 설정해주자.
장애 발생시에 대한 오퍼레이션 설정은 아래와 같다.
장애가 복구되었을 때에 대한 오퍼레이션 설정은 아래와 같다.
이로써 모든 알림 설정이 완료되었다.
💥 장애 유발
테스트를 위해 dd
명령어로 디스크 용량을 늘려 장애 상황을 유발해보자.
sudo dd if=/dev/zero of=/var/log/test.log bs=1M count=3000
df -Th
루트 디렉토리의 용량이 70%가 넘어갔다.
5분이 지나니 정상적으로 장애 알람이 도착했다.
그럼 이제 /var/log/test.log
파일을 삭제하고 장애 복구가 정상적으로 도착하는지 확인해보자.
장애 알람도 정상적으로 수신되었다.
‣ 포트 알림 설정
Zabbix Agent 서버의 터미널로 들어가서 아래 명령어를 실행해보자.
sudo netstat -nltp | grep '80'
80번 포트가 정상적으로 살아있는지 확인을 하고 80번 포트가 다운되어 있다면 알림을 보내도록 Zabbix에서 알림 설정을 해보자.
위에서 설정했던 것과 동일하게 Agent의 템플릿 페이지로 이동하도록 하자.
1. 아이템 생성
옵션 | 설명 |
---|---|
* 키 | net.tcp.port[모니터링 Agent 서버 IP,모니터링 포트] Ex. net.tcp.port[192.168.219.196,80] : 192.168.219.196 서버의 80번 포트를 모니터링 |
2. 트리거 생성
옵션 | 설명 |
---|---|
* 조건식 | last(/Linux by Zabbix agent/net.tcp.port[192.168.219.196,80])=0 : 192.168.219.196 서버의 80번 포트가 비활성화 된 경우 트리거 실행 |
3. 트리거 액션 생성
장애 발생시에 대한 오퍼레이션 설정은 아래와 같다.
장애가 복구되었을 때에 대한 오퍼레이션 설정은 아래와 같다.
💥 장애 유발
테스트를 위해 의도적으로 80번 포트를 다운시켜보도록 하자.
kill -KILL $(ps -aux | grep "80$" | awk '{print $2}')
kill
명령어로 80번 포트를 점유하고 있는 프로세스를 강제로 종료시켰다.
장애가 발생했다고 슬랙으로 알림이 도착했다.
그럼 다시 80번 포트를 등록해주자.
cd ~/npm
docker-compose up -d
복구 됐다고 알림이 정상적으로 도착했다.