들어가며
Apache 웹서버를 운영하다 보면 "지금 동시 접속이 몇 개지?", "워커 프로세스가 부족한 건 아닐까?" 같은 질문이 계속 생깁니다. mod_status 페이지를 매번 브라우저로 열어보는 건 한계가 있죠. Apache Exporter를 붙이면 이 정보를 Prometheus 메트릭으로 자동 수집하고 Grafana에서 시계열로 볼 수 있습니다.
이 글에서는 2026년 기준으로 Apache Exporter를 바이너리와 Docker 두 가지 방식으로 설치하는 방법, 그리고 실제 운영 환경에서 자주 만나는 함정까지 정리합니다.
전체 구성도
+-------------------+
| Apache HTTPD |
| |
| mod_status |
| /server-status | <---+
+-------------------+ |
| (1) HTTP scrape
| ?auto 포맷
+--------+----------+
| apache_exporter |
| :9117/metrics |
+--------+----------+
|
| (2) Prometheus scrape
| 15s interval
+--------v----------+
| Prometheus |
| :9090 |
+--------+----------+
|
| (3) PromQL query
|
+--------v----------+
| Grafana |
| :3000 |
+-------------------+
구성 요소기본 포트역할
| Apache mod_status | 80 / 443 | 워커 상태, 요청 수 원본 데이터 노출 |
| apache_exporter | 9117 | mod_status 파싱 후 Prometheus 포맷 변환 |
| Prometheus | 9090 | 메트릭 수집 및 저장 |
| Grafana | 3000 | 시각화 |
1단계: Apache mod_status 활성화
Exporter는 Apache가 제공하는 /server-status 페이지를 긁어오는 방식입니다. 따라서 mod_status가 먼저 켜져 있어야 합니다.
모듈 로드 확인
httpd -M | grep status
# 또는 Debian/Ubuntu 계열
apache2ctl -M | grep status
status_module (shared) 가 보이면 이미 로드된 상태입니다. 없다면 활성화합니다.
# RHEL / Amazon Linux
vi /etc/httpd/conf.modules.d/00-base.conf
# LoadModule status_module modules/mod_status.so 주석 해제
# Debian / Ubuntu
a2enmod status
server-status 설정
vi /etc/httpd/conf.d/status.conf
ExtendedStatus On
<Location /server-status>
SetHandler server-status
Require local
# Exporter가 다른 호스트에 있다면 아래처럼 IP 허용
# Require ip 10.0.0.0/8
</Location>
ExtendedStatus On은 반드시 필요합니다. 이 옵션이 꺼져 있으면 CPU 사용률, 요청별 상세 정보 같은 확장 메트릭이 수집되지 않습니다.
설정 반영 및 확인
httpd -t
systemctl reload httpd
curl "http://localhost/server-status?auto"
아래처럼 key-value 텍스트가 나오면 정상입니다.
Total Accesses: 12345
Total kBytes: 67890
CPULoad: .0234
Uptime: 86400
ReqPerSec: 0.142
BusyWorkers: 3
IdleWorkers: 22
Scoreboard: __W__R.....
2단계: Apache Exporter 바이너리 설치
아키텍처 확인
Graviton 같은 ARM 기반 인스턴스라면 반드시 arm64 바이너리를 받아야 합니다.
uname -m
# x86_64 -> amd64
# aarch64 -> arm64
다운로드 및 배치
최신 버전은 GitHub 릴리스 페이지에서 확인하세요. 아래는 변수로 처리한 예시입니다.
VERSION="1.0.10"
ARCH="amd64" # Graviton이면 arm64
cd /tmp
wget https://github.com/Lusitaniae/apache_exporter/releases/download/v${VERSION}/apache_exporter-${VERSION}.linux-${ARCH}.tar.gz
tar xvfz apache_exporter-${VERSION}.linux-${ARCH}.tar.gz
sudo mv apache_exporter-${VERSION}.linux-${ARCH}/apache_exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/apache_exporter
apache_exporter --version
전용 계정 생성
root로 돌리지 않는 것이 원칙입니다.
sudo useradd --no-create-home --shell /sbin/nologin apache_exporter
sudo chown apache_exporter:apache_exporter /usr/local/bin/apache_exporter
3단계: systemd 서비스 등록
sudo vi /etc/systemd/system/apache_exporter.service
[Unit]
Description=Prometheus Apache Exporter
Wants=network-online.target
After=network-online.target httpd.service
[Service]
Type=simple
User=apache_exporter
Group=apache_exporter
ExecStart=/usr/local/bin/apache_exporter \
--scrape_uri="http://localhost/server-status?auto" \
--telemetry.address=":9117" \
--telemetry.endpoint="/metrics"
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now apache_exporter
sudo systemctl status apache_exporter
주요 실행 옵션
옵션기본값설명
| --scrape_uri | http://localhost/server-status/?auto | mod_status 주소. 반드시 ?auto 포함 |
| --telemetry.address | :9117 | Exporter 리슨 주소 |
| --telemetry.endpoint | /metrics | 메트릭 경로 |
| --insecure | false | HTTPS 자체서명 인증서 검증 무시 |
| --host_override | 없음 | 가상호스트 다중 구성 시 Host 헤더 지정 |
| --custom_headers | 없음 | 인증 헤더 등 추가 전달 |
동작 확인
curl http://localhost:9117/metrics | grep apache_
apache_up 1
apache_accesses_total 12345
apache_workers{state="busy"} 3
apache_workers{state="idle"} 22
apache_scoreboard{state="write"} 1
apache_cpuload 0.0234
apache_up 0이 나오면 Exporter는 살아있지만 mod_status를 못 읽고 있다는 뜻입니다. 1단계로 돌아가세요.
4단계: Docker로 설치하기 (대안)
컨테이너 환경이라면 바이너리 대신 이미지를 쓰는 편이 관리가 쉽습니다.
docker run -d \
--name apache_exporter \
--restart unless-stopped \
-p 9117:9117 \
lusotycoon/apache-exporter:v1.0.10 \
--scrape_uri="http://host.docker.internal/server-status?auto"
docker-compose 예시:
services:
apache_exporter:
image: lusotycoon/apache-exporter:v1.0.10
container_name: apache_exporter
restart: unless-stopped
ports:
- "9117:9117"
command:
- '--scrape_uri=http://web.example.com/server-status?auto'
Kubernetes라면 Apache 파드에 사이드카 컨테이너로 붙이고 ServiceMonitor를 만드는 패턴이 일반적입니다.
5단계: Prometheus 수집 설정
vi /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: 'apache'
scrape_interval: 15s
static_configs:
- targets:
- 'web01.example.com:9117'
- 'web02.example.com:9117'
labels:
service: 'web'
env: 'prod'
promtool check config /etc/prometheus/prometheus.yml
systemctl reload prometheus
Prometheus UI의 Status > Targets에서 해당 job이 UP인지 확인합니다.
6단계: 방화벽 및 보안 처리
# firewalld
sudo firewall-cmd --permanent --add-port=9117/tcp
sudo firewall-cmd --reload
AWS 보안그룹을 쓴다면 Prometheus 서버 보안그룹을 소스로 지정해 9117을 인바운드 허용합니다. 0.0.0.0/0 개방은 피하세요.
/server-status는 요청 URL과 클라이언트 IP까지 노출할 수 있으므로 외부에서 절대 접근되지 않도록 Require local 또는 내부 대역 제한을 유지해야 합니다. 보안 점검에서 자주 지적되는 항목입니다.
주요 메트릭과 활용 쿼리
메트릭의미
| apache_up | Exporter의 mod_status 수집 성공 여부 |
| apache_accesses_total | 누적 요청 수 (counter) |
| apache_sent_kilobytes_total | 누적 전송량 |
| apache_workers{state="busy"} | 처리 중인 워커 수 |
| apache_workers{state="idle"} | 대기 워커 수 |
| apache_scoreboard{state="..."} | 워커 상태별 분포 |
| apache_cpuload | Apache 프로세스 CPU 사용률 |
| apache_uptime_seconds_total | 프로세스 가동 시간 |
유용한 PromQL 예시:
# 초당 요청 수
rate(apache_accesses_total[5m])
# 워커 사용률 (%)
apache_workers{state="busy"}
/ (apache_workers{state="busy"} + apache_workers{state="idle"}) * 100
# 워커 고갈 임박 경보
apache_workers{state="idle"} < 5
Grafana 대시보드는 grafana.com에서 ID 3894를 임포트하면 바로 쓸 수 있습니다.
자주 겪는 문제와 해결
증상원인해결
| apache_up 0 | mod_status 접근 실패 | curl "http://localhost/server-status?auto" 로 직접 확인 |
| 403 Forbidden | Require local 인데 Exporter가 원격에 있음 | Require ip 로 대역 허용 |
| 확장 메트릭 없음 | ExtendedStatus Off | ExtendedStatus On 추가 후 reload |
| 메트릭이 0으로만 나옴 | ?auto 파라미터 누락 | scrape_uri 끝에 ?auto 확인 |
| 엉뚱한 가상호스트 값 | VirtualHost 다중 구성 | --host_override 로 Host 헤더 지정 |
| Exporter 즉시 종료 | 아키텍처 불일치 | uname -m 확인 후 arm64/amd64 재다운로드 |
| SELinux로 인한 연결 거부 | httpd 네트워크 정책 | setsebool -P httpd_can_network_connect 1 |
마무리
정리하면 순서는 이렇습니다.
- mod_status 활성화 + ExtendedStatus On
- 아키텍처에 맞는 apache_exporter 바이너리 설치
- systemd 등록 및 9117 포트 확인
- Prometheus scrape_configs 추가
- Grafana 대시보드 3894 임포트
핵심은 /server-status?auto가 먼저 정상 응답하는지 확인하는 것입니다. 이 단계만 통과하면 나머지는 거의 실패하지 않습니다. 웹서버가 여러 대라면 Ansible이나 사용자 데이터 스크립트로 2~3단계를 자동화해 두는 것을 권장합니다.
SEO 키워드: apache exporter 설치, 아파치 익스포터, Prometheus Apache 모니터링, mod_status 설정, apache_exporter systemd, 9117 포트, Grafana Apache 대시보드, 아파치 워커 모니터링, ExtendedStatus, Prometheus scrape_configs, Graviton arm64 exporter, 웹서버 메트릭 수집