NGINX 계측 (Instrumenting NGINX)
Datadog APM은 두 가지 구성에서 NGINX를 지원해요.
출처: 문서
본문
Datadog APM은 두 가지 구성에서 NGINX를 지원해요:
- Datadog 모듈이 트레이싱을 제공하는 프록시로 운영되는 NGINX.
- Kubernetes용 Ingress Controller로서의 NGINX.
Datadog 모듈이 있는 NGINX
Datadog은 분산 트레이싱을 위한 NGINX 모듈을 제공해요.
모듈 설치
Datadog NGINX 모듈을 설치하려면 다음 지침을 따르세요:
- 최신 nginx-datadog GitHub 릴리스에서 적절한 버전을 다운로드해요.
- 특정 NGINX 버전과 CPU 아키텍처에 해당하는 tarball을 선택해요.
각 릴리스는 NGINX 버전과 CPU 아키텍처 조합마다 두 개의 tarball을 포함해요. 기본 tarball에는 Datadog NGINX 모듈인 ngx_http_datadog_module.so라는 단일 파일이 포함돼 있어요. 두 번째 것은 디버그 심볼이며 선택 사항이에요.
간단히 하기 위해 다음 스크립트는 최신 릴리스의 모듈만 다운로드해요:
get_latest_release() {
curl --silent "https://api.github.com/repos/$1/releases/latest" | jq --raw-output .tag_name
}
get_architecture() {
case "$(uname -m)" in
aarch64|arm64)
echo "arm64"
;;
x86_64|amd64)
echo "amd64"
;;
*)
echo ""
;;
esac
}
ARCH=$(get_architecture)
if [ -z "$ARCH" ]; then
echo 1>&2 "ERROR: Architecture $(uname -m) is not supported."
exit 1
fi
NGINX_VERSION="1.29.0"
RELEASE_TAG=$(get_latest_release DataDog/nginx-datadog)
TARBALL="ngx_http_datadog_module-${ARCH}-${NGINX_VERSION}.so.tgz"
curl -Lo ${TARBALL} "https://github.com/DataDog/nginx-datadog/releases/download/${RELEASE_TAG}/${TARBALL}"
다운로드한 tarball에서 tar를 사용해 ngx_http_datadog_module.so 파일을 추출하고 일반적으로 /usr/lib/nginx/modules에 있는 NGINX 모듈 디렉터리에 배치해요.
Datadog 모듈을 사용한 NGINX 구성
NGINX 구성의 가장 상단 섹션에서 Datadog 모듈을 로드해요.
load_module modules/ngx_http_datadog_module.so;
기본 구성은 로컬 Datadog Agent에 연결하고 모든 NGINX location에 대한 트레이스를 생성해요. Datadog 모듈의 API 문서에 설명된 전용 datadog_* 지시어를 사용해 커스텀 구성을 지정해요.
예를 들어 다음 NGINX 구성은 서비스 이름을 usage-internal-nginx로, 샘플링 비율을 10%로 설정해요.
load_module modules/ngx_http_datadog_module.so;
http {
datadog_service_name usage-internal-nginx;
datadog_sample_rate 0.1;
# servers, locations...
}
Kubernetes용 Ingress-NGINX Controller
Datadog은 Kubernetes에서 Ingress-NGINX controller를 모니터링하는 지원을 제공해요. 컨트롤러 버전과 요구 사항에 따라 다음 계측 방법 중에서 선택해요:
- Datadog의 기능을 사용한 v1.10.0+.
- OpenTelemetry를 사용한 v1.10.0+.
- v1.9.0 이하.
Datadog의 기능을 사용한 Controller v1.10.0+
이 계측 방법은 nginx-datadog을 사용하며 Kubernetes init-container 메커니즘을 활용해 Ingress-NGINX Controller 인스턴스 안에 모듈을 설치해요.
Datadog 모듈로 Ingress-NGINX **v1.10.0+**를 계측하려면 다음 단계를 따르세요:
Kubernetes
1. Ingress-NGINX 버전 확인 Ingress-NGINX Controller 버전을 확인하고 일치하는 Datadog init-container를 사용할 수 있는지 확인해요. init-container 버전(datadog/ingress-nginx-injection)은 시작 문제를 방지하려면 컨트롤러 버전과 정확히 일치해야 해요. 예를 들어 Ingress-NGINX v1.11.3을 실행 중이라면 datadog/ingress-nginx-injection:v1.11.3이 필요해요.
참고: v1.11.3 같은 버전 태그는 롤링 태그예요. 태그가 동일하게 유지되는 동안 기본 Datadog NGINX 모듈이 업데이트될 수 있어요. 정확한 버전을 고정하려면 이미지를 다이제스트로 참조해요(예: datadog/ingress-nginx-injection@sha256:...).
2. 컨트롤러의 파드 사양 수정 init-container를 포함하고 Datadog Agent 호스트 환경 변수를 구성하도록 컨트롤러 파드 사양을 업데이트해요:
spec:
template:
spec:
initContainers:
- name: init-datadog
image: datadog/ingress-nginx-injection:<MY_INGRESS_NGINX_VERSION>
command: ['/datadog/init_module.sh', '/opt/datadog-modules']
volumeMounts:
- name: nginx-module
mountPath: /opt/datadog-modules
containers:
- name: controller
image: registry.k8s.io/ingress-nginx/controller:<MY_INGRESS_NGINX_VERSION>
volumeMounts:
- name: nginx-module
mountPath: /opt/datadog-modules
env:
- ...
- name: DD_AGENT_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
volumes:
- ...
- name: nginx-module
emptyDir: {}
참고: Datadog Agent에 접근하는 대체 방법은 Kubernetes 설치 가이드를 참조하세요.
3. Ingress-NGINX 구성 Datadog 모듈을 로드하도록 ConfigMap을 생성하거나 수정해요:
kind: ConfigMap
apiVersion: v1
...
data:
enable-opentelemetry: "false"
error-log-level: notice
main-snippet: |
load_module /opt/datadog-modules/ngx_http_datadog_module.so;
4. ConfigMap 적용 Datadog 모듈이 올바르게 로드되도록 업데이트된 ConfigMap을 적용해요.
이 구성은 Datadog 모듈이 로드되어 들어오는 요청을 추적할 준비가 되도록 보장해요.
Helm
1. Ingress-NGINX 버전 확인 Ingress-NGINX Controller 버전을 확인하고 일치하는 Datadog init-container를 사용할 수 있는지 확인해요. init-container 버전(datadog/ingress-nginx-injection)은 시작 문제를 방지하려면 컨트롤러 버전과 정확히 일치해야 해요. 예를 들어 Ingress-NGINX v1.11.3을 실행 중이라면 datadog/ingress-nginx-injection:v1.11.3이 필요해요.
참고: v1.11.3 같은 버전 태그는 롤링 태그예요. 태그가 동일하게 유지되는 동안 기본 Datadog NGINX 모듈이 업데이트될 수 있어요. 정확한 버전을 고정하려면 이미지를 다이제스트로 참조해요(예: datadog/ingress-nginx-injection@sha256:...).
2. Helm 차트 값 덮어쓰기 Ingress-NGINX Helm 차트를 커스터마이즈하고 필요한 Datadog 모듈을 로드하려면 다음 구성으로 YAML 파일을 생성하거나 기존 파일을 수정해요:
values.yaml 파일에서:
controller:
config:
main-snippet: "load_module /modules_mount/ngx_http_datadog_module.so;"
opentelemetry:
enabled: false
extraModules:
- name: nginx-datadog
image:
registry: docker.io
image: datadog/ingress-nginx-injection
# 태그는 ingress-nginx controller의 버전과 일치해야 해요
# 예를 들어 이는 ingress v1.10.0용 Datadog 모듈을 주입해요
# 지원되는 모든 버전 목록은 <https://hub.docker.com/repository/docker/datadog/ingress-nginx-injection/tags>를 확인하세요
tag: "v1.10.0"
distroless: false
extraEnvs:
- name: DD_AGENT_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
3. 배포 -f 플래그를 사용해 이전 단계에서 만든 커스텀 values를 적용하여 Helm 릴리스를 설치하거나 업그레이드해요.
helm install my-release ingress-nginx/ingress-nginx -f values.yaml
OpenTelemetry를 사용한 Controller v1.10.0+
Kubernetes
1. Datadog Agent 준비 Datadog Agent가 OpenTelemetry Collector 역할을 하도록 gRPC OTLP Ingestion이 활성화되어 있는지 확인해요.
2. Ingress controller 구성 먼저 Ingress controller의 파드 사양에 HOST_IP 환경 변수가 설정되어 있는지 확인해요. 없다면 파드 사양의 env 블록에 다음 항목을 추가해요:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://$(HOST_IP):4317"
다음으로 controller에 대해 OpenTelemetry 계측을 활성화해요. 다음 세부 정보로 ConfigMap을 생성하거나 편집해요:
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
enable-opentelemetry: "true"
otel-sampler: AlwaysOn
# 기본값
# otel-service-name: "nginx"
# otel-sampler-ratio: 0.01
Helm
1. Datadog Agent 준비 Datadog Agent가 OpenTelemetry Collector 역할을 하도록 gRPC OTLP Ingestion이 활성화되어 있는지 확인해요.
2. Helm 차트 값 덮어쓰기 Ingress-NGINX Helm 차트를 커스터마이즈하고 필요한 Datadog 모듈을 로드하려면 다음 구성으로 YAML 파일을 생성하거나 기존 파일을 수정해요:
values.yaml 파일에서:
controller:
opentelemetry:
enabled: true
config:
otel-service-name: "nginx"
otel-sampler: AlwaysOn
otel-sampler-ratio: 0.01
extraEnvs:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://$(HOST_IP):4317"
3. 배포 -f 플래그를 사용해 이전 단계에서 만든 커스텀 values를 적용하여 Helm 릴리스를 설치하거나 업그레이드해요.
helm install my-release ingress-nginx/ingress-nginx -f values.yaml
Controller v1.9.0 이하
Datadog 트레이싱을 활성화하려면 enable-opentracing: "true"와 트레이스를 보낼 datadog-collector-host를 설정하도록 ConfigMap을 생성하거나 편집해요. ConfigMap의 이름은 Ingress-NGINX Controller 컨테이너의 명령줄 인수에 명시적으로 언급되며, 기본값은 --configmap=<POD_NAMESPACE>/nginx-configuration이에요. ingress-nginx가 Helm 차트로 설치되었다면 ConfigMap 이름은 <RELEASE_NAME>-nginx-ingress-controller 패턴을 따르게 돼요.
Ingress controller는 nginx.conf와 /etc/nginx/opentracing.json 파일을 모두 관리해요. 모든 location 블록에 대해 트레이싱이 활성화돼요.
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
enable-opentracing: "true"
datadog-collector-host: $HOST_IP
# 기본값
# datadog-service-name: "nginx"
# datadog-collector-port: "8126"
# datadog-operation-name-override: "nginx.handle"
# datadog-sample-rate: "1.0"
또한 컨트롤러의 파드 사양에 HOST_IP 환경 변수가 설정되어 있는지 확인해요. POD_NAME과 POD_NAMESPACE 환경 변수가 포함된 env: 블록에 이 항목을 추가해요.
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
어노테이션을 사용해 Ingress별로 다른 서비스 이름을 설정하려면:
nginx.ingress.kubernetes.io/configuration-snippet: |
opentracing_tag "service.name" "custom-service-name";
위 항목은 기본 nginx-ingress-controller.ingress-nginx 서비스 이름을 덮어써요.
트레이스를 로그와 상호 연관
APM 트레이싱을 활성화한 후 트레이스를 해당 NGINX 로그와 연결할 수 있어요. 이 상호 연관은 각 트레이스와 스팬을 해당 요청 중 생성된 특정 로그 이벤트와 연결해 문제를 트러블슈팅하기 위해 이들 사이를 전환할 수 있게 해줘요.
사전 요구 사항
시작하기 전에 다음을 확인하세요:
- 이 가이드의 앞부분 단계를 따라 NGINX에 대해 APM 트레이싱을 활성화했는지.
- NGINX에 대해 Datadog 로그 수집을 구성했는지.
1단계: NGINX 로그에 트레이스 및 스팬 ID 주입
log_format 지시어를 수정해 트레이스 ID와 스팬 ID를 포함해요. 사용하는 변수는 계측 방법에 따라 달라져요. 설정과 일치하는 지침은 아래 적절한 탭을 선택하세요.
Datadog NGINX Module
Datadog NGINX 모듈을 설치했다면 $datadog_trace_id와 $datadog_span_id 변수를 사용해요. 추적되지 않는 요청의 경우 이 값은 -예요.
NGINX 구성 파일(예: /etc/nginx/nginx.conf)을 업데이트해요:
http {
log_format main_datadog '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'dd.trace_id="$datadog_trace_id"' 'dd.span_id="$datadog_span_id"';
access_log /var/log/nginx/access.log main_datadog;
}
OpenTelemetry
NGINX OpenTelemetry 모듈을 사용한다면 $otel_trace_id와 $otel_span_id 변수를 사용해요. 추적되지 않는 요청의 경우 이 값은 빈 문자열이에요.
NGINX 구성 파일(예: /etc/nginx/nginx.conf)을 업데이트해요:
http {
log_format main_opentelemetry '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'dd.trace_id="$otel_trace_id"' 'dd.span_id="$otel_span_id"' ;
access_log /var/log/nginx/access.log main_opentelemetry;
}
변경 사항을 저장한 후 NGINX 구성을 리로드해요. 예:
sudo nginx -s reload
2단계: 트레이스 및 스팬 ID를 파싱하도록 로그 파이프라인 구성
기본적으로 로그는 dd.trace_id와 dd.span_id를 16진수 형식으로 캡처해요:
10.244.0.1 - - [12/Sep/2025:22:41:03 +0000] "GET /health HTTP/1.1" 200 87 0.002 "-" "kube-probe/1.32" "-" dd.trace_id="68c4a17f000000009aed12af2ccb1ead" dd.span_id="9aed12af2ccb1ead"
Datadog에서 로그와 트레이스의 상호 연관을 활성화하려면 이러한 ID를 16진수에서 10진수로 변환하는 로그 처리 파이프라인을 구성해요. 사용하는 계측 방법과 관계없이 동일한 단계를 따르세요.
- Datadog에서 Log Configuration 페이지로 이동해요.
- 활성 NGINX 파이프라인 위에 마우스를 올리고 Clone 아이콘을 클릭해 편집 가능한 버전을 만들어요.
- 복제된 파이프라인을 클릭해요.
- Add Processor를 클릭해요.
- 프로세서 유형으로 Grok Parser를 선택해요.
- 로그 이벤트에서 트레이스 ID 속성을 추출하도록 다음 파싱 규칙을 정의해요. 이 규칙은 Datadog 모듈과 OpenTelemetry 출력 모두에 대해 작동해요:
extract_correlation_ids %{data} dd.trace_id="%{notSpace:dd.trace_id:nullIf("-")}" dd.span_id="%{notSpace:dd.span_id:nullIf("-")}" - Create를 클릭해요.
- 다시 Add Processor를 클릭해요.
- 프로세서 유형으로 Trace ID Remapper를 선택해요. 이 프로세서는 파싱된 ID를 해당 APM 트레이스와 연결해요.
- Set trace id attribute(s) 필드에
dd.trace_id를 입력해요. - Create를 클릭해요.
- 다시 Add Processor를 클릭해요.
- 프로세서 유형으로 Span ID Remapper를 선택해요. 이 프로세서는 파싱된 ID를 해당 APM 스팬과 연결해요.
- Set span id attribute(s) 필드에
dd.span_id를 입력해요. - Create를 클릭해요.
- 새 파이프라인을 저장하고 활성화해요.
파이프라인이 활성화되면 새 NGINX 로그가 트레이스 및 스팬과 자동으로 상호 연관돼요.