Prometheus 가 긁어 갈 메트릭을 내는 프로그램들이다. 대상마다 exporter 가 따로 있고, 각자 다른 포트에서 /metrics 를 연다.
| exporter | 대상 | 기본 포트 |
|---|---|---|
| node_exporter[1] | 호스트 CPU · 메모리 · 디스크 · 네트워크 | 9100 |
| kafka_exporter[2] | 토픽 · 컨슈머 그룹 랙 | 9308 |
| JMX exporter[3] | JVM 애플리케이션 내부 (Kafka 브로커 등) | 지정 |
| mysqld_exporter[4] | MySQL · MariaDB | 9104 |
| nifi_exporter | NiFi | 9103 |
https://github.com/prometheus/node_exporter
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=exporter
Group=exporter
Type=simple
Environment=LISTEN_ADDRESS=":9100"
Environment=WEB_CONFIG=/etc/node_exporter/web.config
ExecStart=/opt/node_exporter/bin/node_exporter \
--web.listen-address=${LISTEN_ADDRESS} --collector.systemd --collector.processes --collector.cpu --collector.meminfo --collector.diskstats --collector.filesystem \
--web.config.file=${WEB_CONFIG}
WorkingDirectory=/opt/node_exporter
Restart=always
# 로그 파일 저장
StandardOutput=append:/var/log/node_exporter/node_exporter.log
StandardError=append:/var/log/node_exporter/node_exporter.err
[Install]
WantedBy=multi-user.target
tls_server_config:
# Certificate for server to use to authenticate to client.
# Expected to be passed as a PEM encoded sequence of bytes as a string.
#
# NOTE: If passing the cert inline, cert_file should not be specified below.
[ cert: <string> ]
# Key for server to use to authenticate to client.
# Expected to be passed as a PEM encoded sequence of bytes as a string.
#
# NOTE: If passing the key inline, key_file should not be specified below.
[ key: <secret> ]
# CA certificate for client certificate authentication to the server.
# Expected to be passed as a PEM encoded sequence of bytes as a string.
#
# NOTE: If passing the client_ca inline, client_ca_file should not be specified below.
[ client_ca: <string> ]
# Certificate and key files for server to use to authenticate to client.
cert_file: <filename>
key_file: <filename>
# Server policy for client authentication. Maps to ClientAuth Policies.
# For more detail on clientAuth options:
# https://golang.org/pkg/crypto/tls/#ClientAuthType
#
# NOTE: If you want to enable client authentication, you need to use
# RequireAndVerifyClientCert. Other values are insecure.
[ client_auth_type: <string> | default = "NoClientCert" ]
# CA certificate for client certificate authentication to the server.
[ client_ca_file: <filename> ]
# Verify that the client certificate has a Subject Alternate Name (SAN)
# which is an exact match to an entry in this list, else terminate the
# connection. SAN match can be one or multiple of the following: DNS,
# IP, e-mail, or URI address from https://pkg.go.dev/crypto/x509#Certificate.
[ client_allowed_sans:
[ - <string> ] ]
# Minimum TLS version that is acceptable.
[ min_version: <string> | default = "TLS12" ]
# Maximum TLS version that is acceptable.
[ max_version: <string> | default = "TLS13" ]
# List of supported cipher suites for TLS versions up to TLS 1.2. If empty,
# Go default cipher suites are used. Available cipher suites are documented
# in the go documentation:
# https://golang.org/pkg/crypto/tls/#pkg-constants
#
# Note that only the cipher returned by the following function are supported:
# https://pkg.go.dev/crypto/tls#CipherSuites
[ cipher_suites:
[ - <string> ] ]
# prefer_server_cipher_suites controls whether the server selects the
# client's most preferred ciphersuite, or the server's most preferred
# ciphersuite. If true then the server's preference, as expressed in
# the order of elements in cipher_suites, is used.
[ prefer_server_cipher_suites: <bool> | default = true ]
# Elliptic curves that will be used in an ECDHE handshake, in preference
# order. Available curves are documented in the go documentation:
# https://golang.org/pkg/crypto/tls/#CurveID
[ curve_preferences:
[ - <string> ] ]
http_server_config:
# Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.
# This can not be changed on the fly.
[ http2: <boolean> | default = true ]
# List of headers that can be added to HTTP responses.
[ headers:
# Set the Content-Security-Policy header to HTTP responses.
# Unset if blank.
[ Content-Security-Policy: <string> ]
# Set the X-Frame-Options header to HTTP responses.
# Unset if blank. Accepted values are deny and sameorigin.
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
[ X-Frame-Options: <string> ]
# Set the X-Content-Type-Options header to HTTP responses.
# Unset if blank. Accepted value is nosniff.
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
[ X-Content-Type-Options: <string> ]
# Set the X-XSS-Protection header to all responses.
# Unset if blank.
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
[ X-XSS-Protection: <string> ]
# Set the Strict-Transport-Security header to HTTP responses.
# Unset if blank.
# Please make sure that you use this with care as this header might force
# browsers to load Prometheus and the other applications hosted on the same
# domain and subdomains over HTTPS.
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
[ Strict-Transport-Security: <string> ] ]
# Usernames and hashed passwords that have full access to the web
# server via basic authentication. If empty, no basic authentication is
# required. Passwords are hashed with bcrypt.
basic_auth_users:
[ <string>: <secret> ... ]
#!/bin/bash
# Variables
NODE_EXPORTER_BIN="/home/services/node_exporter/bin/node_exporter"
LISTEN_PORT="60001"
CERT_FILE="/home/services/certs/haedongg.crt"
KEY_FILE="/home/services/certs/haedongg.key"
PID_FILE="/home/services/node_exporter/node_exporter.pid"
LOG_FILE="/home/services/node_exporter/node_exporter.log"
# Start Node Exporter
start_node_exporter() {
if [ -f "$PID_FILE" ]; then
echo "Node Exporter is already running (PID $(cat $PID_FILE))."
else
echo "Starting Node Exporter on port $LISTEN_PORT with TLS..."
nohup $NODE_EXPORTER_BIN \
--web.listen-address=":60001" \
--web.config.file="" \
--web.tls-cert-file="$CERT_FILE" \
--web.tls-key-file="$KEY_FILE" > "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "Node Exporter started with PID $(cat $PID_FILE)."
fi
}
# Stop Node Exporter
stop_node_exporter() {
if [ -f "$PID_FILE" ]; then
PID=$(cat $PID_FILE)
echo "Stopping Node Exporter (PID $PID)..."
kill $PID
rm -f "$PID_FILE"
echo "Node Exporter stopped."
else
echo "Node Exporter is not running."
fi
}
# Restart Node Exporter
restart_node_exporter() {
stop_node_exporter
start_node_exporter
}
# Check Status
status_node_exporter() {
if [ -f "$PID_FILE" ]; then
echo "Node Exporter is running (PID $(cat $PID_FILE))."
else
echo "Node Exporter is not running."
fi
}
# Main Script Logic
case "$1" in
start)
start_node_exporter
;;
stop)
stop_node_exporter
;;
restart)
restart_node_exporter
;;
status)
status_node_exporter
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
# start.sh
#!/bin/bash
nohup ./node_exporter --web.listen-address=:9101 >/dev/null 2>&1 &
ps -ef | grep node_exporter
# stop.sh
#!/bin/bash
kill -9 `ps -ef |grep node_exporter | awk '{print $2; exit}'`
ps -ef | grep node_exporter
Kafka 를 Prometheus 로 볼 때는 두 가지를 같이 쓴다. 보는 것이 다르다.
| 도구 | 보는 것 | 붙는 위치 |
|---|---|---|
| kafka_exporter[2:1] | 토픽 · 파티션 · 컨슈머 그룹 랙(lag) | 별도 프로세스. 브로커에 클라이언트로 붙는다 |
| JMX exporter[3:1] | 브로커 내부 메트릭 — 요청 지연, ISR, 로그 플러시, GC | 브로커 JVM 에 javaagent 로 붙는다 |
KE_VER=1.10.0
curl -LO https://github.com/danielqsj/kafka_exporter/releases/download/v${KE_VER}/kafka_exporter-${KE_VER}.linux-amd64.tar.gz
tar -xzf kafka_exporter-${KE_VER}.linux-amd64.tar.gz
sudo install -m 755 kafka_exporter-${KE_VER}.linux-amd64/kafka_exporter /usr/local/bin/kafka_exporter
sudo tee /etc/systemd/system/kafka_exporter.service > /dev/null <<'UNIT'
[Unit]
Description=Kafka Exporter
After=network-online.target
[Service]
User=exporter
Group=exporter
Type=simple
ExecStart=/usr/local/bin/kafka_exporter \
--web.listen-address=:9308 \
--kafka.server=kafka01:9092 \
--kafka.server=kafka02:9092 \
--kafka.server=kafka03:9092
Restart=always
[Install]
WantedBy=multi-user.target
UNIT
sudo systemctl daemon-reload
sudo systemctl enable kafka_exporter --now
SASL 이 걸린 클러스터는 --sasl.enabled --sasl.username=<사용자> --sasl.password=<비밀번호> 를 더한다. 기본 포트는 9308 이다.
curl -s http://localhost:9308/metrics | grep -E '^kafka_consumergroup_lag|^kafka_topic_partitions' | head
브로커 기동 스크립트에 javaagent 를 건다. 설정 파일은 공식 예제(kafka-2_0_0.yml)를 그대로 써도 된다.
JX_VER=1.6.0
sudo mkdir -p /opt/kafka/jmx
sudo curl -Lo /opt/kafka/jmx/jmx_prometheus_javaagent.jar \
https://github.com/prometheus/jmx_exporter/releases/download/${JX_VER}/jmx_prometheus_javaagent-${JX_VER}.jar
sudo curl -Lo /opt/kafka/jmx/kafka.yml \
https://raw.githubusercontent.com/prometheus/jmx_exporter/main/examples/kafka-2_0_0.yml
kafka-server-start.sh 를 부르기 전에 환경변수로 넣는다. systemd 를 쓰면 [Service] 에 둔다.
Environment="KAFKA_OPTS=-javaagent:/opt/kafka/jmx/jmx_prometheus_javaagent.jar=9404:/opt/kafka/jmx/kafka.yml"
curl -s http://localhost:9404/metrics | grep -E '^kafka_server_' | head
scrape_configs:
- job_name: kafka
static_configs:
- targets: ['kafka01:9404', 'kafka02:9404', 'kafka03:9404']
- job_name: kafka_exporter
static_configs:
- targets: ['kafka01:9308']
kafka_exporter 는 한 대만 띄워도 클러스터 전체 랙이 나온다. JMX exporter 는 브로커마다 붙는다.
https://github.com/msiedlarek/nifi_exporter
# start.sh
#!/bin/bash
nohup ./nifi_exporter ./config.yaml >/dev/null 2>&1 &
# stop.sh
#!/bin/bash
kill -9 `ps -ef |grep nifi_exporter | awk '{print $2; exit}'`
ps -ef | grep nifi_exporter
exporter:
listenAddress: 0.0.0.0:9103
nodes:
- url: http://nifi01.haedongg.net:8080
username: haedongg
password: ${REDACTED}
labels:
env: nifi_node_01
- url: http://nifi02.haedongg.net:8080
username: haedongg
password: ${REDACTED}
labels:
env: nifi_node_02
- url: http://nifi03.haedongg.net:8080
username: haedongg
password: ${REDACTED}
labels:
env: nifi_node_03
https://github.com/prometheus/mysqld_exporter
# start.sh
#!/bin/bash
export MYSQLD_EXPORTER_PASSWORD=${REDACTED}
nohup ./mysqld_exporter --web.listen-address=:9111 --mysqld.address=:3306 --mysqld.username=exporter >/dev/null 2>&1 &
ps -ef | grep mysqld_exporter
# stop.sh
#!/bin/bash
kill -9 `ps -ef |grep mysqld_exporter | awk '{print $2; exit}'`
ps -ef | grep mysqld_exporter
node_exporter 최신 v1.12.1 — 2026-09-17 확인. https://github.com/prometheus/node_exporter/releases ↩︎
kafka_exporter 최신 v1.10.0 — 2026-09-17 확인. https://github.com/danielqsj/kafka_exporter/releases ↩︎ ↩︎
jmx_exporter 최신 1.6.0 — 2026-09-17 확인. jar 는 GitHub 릴리스에서 받는다(Maven Central 은 1.0.1 까지만 있다). https://github.com/prometheus/jmx_exporter/releases ↩︎ ↩︎
mysqld_exporter 최신 v0.20.0 — 2026-09-17 확인. https://github.com/prometheus/mysqld_exporter/releases ↩︎