コンテンツにスキップ

モジュール@Nginx

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


モジュール (静的/動的) のセットアップ方法

ビルド

Nginxでは、モジュールを事前にビルドし、バイナリに組み込む必要がある。

ただ、すでにビルド済みで提供されている場合は、それをインストールすればよい。


Dockerの場合

▼ 未ビルドモジュールの場合

マルチステージビルドを使用して、モジュールのビルド用のステージと実際に使用するステージを分ける。

# -----------------
# builderステージ
# -----------------
FROM nginx:<バージョン>-alpine as builder

# ここで未ビルドモジュールをビルドする

# -----------------
# mainステージ
# -----------------
FROM nginx:<バージョン>-alpine

# builderステージからビルド後のモジュールを取り出す
COPY --from=builder /usr/lib/nginx/modules/otel_ngx_module.so /usr/lib/nginx/modules/

...

▼ ビルド済みモジュールの場合

ビルド済みモジュールをインストール後、そのまま使用する。

FROM nginx:<バージョン>-alpine

# ビルド済みモジュールをインストールする


...


gRPCパッケージ

gRPCパッケージとは

nginxモジュールがgRPCを使用できるようにする。


セットアップ

▼ 未ビルドの場合

パッケージをインポートする前に、ビルドする必要がある。

$ git clone --shallow-submodules --depth 1 --recurse-submodules -b <バージョン> https://github.com/grpc/grpc
$ cd grpc
$ mkdir -p cmake/build
$ cd cmake/build
$ cmake \
    -DgRPC_INSTALL=ON \
    -DgRPC_BUILD_TESTS=OFF \
    -DCMAKE_INSTALL_PREFIX=/install \
    -DCMAKE_BUILD_TYPE=Release \
    -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \
    -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \
    -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
    -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
    -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF \
    -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \
    ../..
$ make -j2
$ make install


opentelemetry-cppパッケージ

opentelemetry-cppパッケージとは

C++でNginxを計装できるようにする。


セットアップ

▼ 未ビルドの場合

パッケージをインポートする前に、ビルドする必要がある。

$ git clone --shallow-submodules --depth 1 --recurse-submodules -b <バージョン> https://github.com/open-telemetry/opentelemetry-cpp.git
$ cd opentelemetry-cpp
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/install \
    -DCMAKE_PREFIX_PATH=/install \
    -DWITH_ZIPKIN=OFF \
    -DWITH_JAEGER=OFF \
    -DWITH_OTLP=ON \
    -DWITH_OTLP_GRPC=ON \
    -DWITH_OTLP_HTTP=OFF \
    -DBUILD_TESTING=OFF \
    -DWITH_EXAMPLES=OFF \
    -DWITH_ABSEIL=ON \
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
    ..
$ make -j2
$ make install


otel_ngx_module

otel_ngx_moduleとは

OpenTelemetryコミュニティ製のモジュールであり、NginxをOpenTelemetryで計装できるようにする。

gRPC Exporterを使用するために、gRPCパッケージが必要である。

また、NginxはC++で実装されているため、opentelemetry-cppパッケージが必要である。


セットアップ

▼ 未ビルドの場合

モジュールをインポートする前に、ビルドする必要がある。

$ git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git
$ cd opentelemetry-cpp-contrib/instrumentation/nginx
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release \
    -DNGINX_BIN=/usr/sbin/nginx \
    -DCMAKE_PREFIX_PATH=/install \
    -DCMAKE_INSTALL_PREFIX=/usr/lib/nginx/modules \
    -DCURL_LIBRARY=/usr/lib/libcurl.so.4 \
    ..
$ make -j2
$ make install

otel_ngx_moduleは動的モジュールであるため、nginx.confファイルでモジュールをインポートする必要がある。

load_module modules/otel_ngx_module.so;


ディレクティブ

▼ opentelemetry_config

モジュールのtomlファイルを設定する。

http {
    opentelemetry_config /conf/otel-nginx.toml;
}

▼ opentelemetry_operation_name

スパン名を設定する。

server {

    location / {
        opentelemetry_operation_name $request_uri;
        proxy_pass $scheme://$host$request_uri;
    }
}

▼ opentelemetry_propagate

トレースコンテキスト仕様として、W3C Trace Contextを設定する。

執筆時点 (2024/05/02) では、他のトレースコンテキスト仕様 (例:X-Rayなど) を伝播できない。

server {

    opentelemetry_propagate;

    location / {
        proxy_pass $scheme://$host$request_uri;
    }
}


otel_webserver_module

otel_webserver_moduleとは

ApacheまたはNginxをOpenTelemetryで計装できるようにする。

otel_apache_moduleとngx_http_opentelemetry_moduleの両方を含んでいる。


otel_apache_module

OpenTelemetryコミュニティ製のモジュールであり、ApacheをOpenTelemetryで計装できるようにする。


ngx_http_opentelemetry_module

OpenTelemetryコミュニティ製のモジュールであり、NginxをOpenTelemetryで計装できるようにする。


ngx_otel_module

ngx_otel_moduleとは

Nginxコミュニティ製のモジュールであり、NginxをOpenTelemetryで計装できるようにする。

執筆時点 (2024/03/10) では、セットアップの簡単さやパフォーマンスでOpenTelemetry製のotel_ngx_moduleに勝っているらしい。


セットアップ

▼ 未ビルドの場合

モジュールをインポートする前に、ビルドする必要がある。

なお、gRPCのビルドは30分ほどかかるため、gRPCを含むビルド済みのモジュールをインストールした方が良い。

$ git clone https://github.com/nginxinc/nginx-otel.git
$ cd nginx-otel
$ mkdir build
$ cd build
$ cmake -DNGX_OTEL_NGINX_BUILD_DIR=/path/to/configured/nginx/objs
$ make -j2
$ make install

ngx_otel_moduleは動的モジュールであるため、nginx.confファイルでモジュールをインポートする必要がある。

load_module modules/ngx_otel_module.so;

その他、alpineはMercurialからインストールすると良い。

▼ ビルド済みの場合

ビルド済みモジュールをインストールする。

Nginx (1.25.3) であればビルトインパッケージになっているため、ビルドが不要である。

# aptリポジトリから
$ apt install -y nginx-module-otel
# yumリポジトリから
$ yum install -y nginx-module-otel

Alpineの場合は、執筆時点 (2024/03/13) でalpineリポジトリにngx_otel_moduleがなく、Nginxのalpineリポジトリにパッケージがある。

apkコマンドはそのまま使うと常に最新をインストールしてしまう。

そこで、wgetコマンドで一度ファイルを取得し、apkコマンドでそのファイルからモジュールをインストールする。

# nginxのalpineリポジトリから
$ wget -qO nginx-module-otel-<リビジョン>.apk https://nginx.org/packages/mainline/alpine/<バージョン>/main/x86_64/nginx-module-otel-<リビジョン>.apk
$ apk add --allow-untrusted nginx-module-otel-<バージョン>.apk


ディレクティブ

▼ otel_exporter

Exporterを設定する。

執筆時点 (2024/03/14) 時点では、gRPC用のエンドポイントしかありません。

http {

    otel_exporter {
        endpoint foo-opentelemetry-collector.foo-namespace.svc.cluster.local:4317;
    }
}

▼ otel_service_name

http {
    otel_service_name foo-service;
}

▼ otel_trace

分散トレースを有効化するかどうかを設定する。

http {
    otel_trace on;
}

▼ otel_trace_context

http {
    # 受信したCarrierにトレースコンテキストがない場合はInjectし、あればExtractする
    otel_trace_context propagate;
}

▼ otel_span_name

スパン名を設定する。

デフォルトでは、リクエストのLocation値がスパン名になる。

http {

    location / {
        otel_span_name foo;
        proxy_pass $scheme://$host$request_uri;
    }
}

▼ otel_span_attr

スパンの属性を設定する。

http {

    location / {
        otel_span_attr otel.resource.deployment.environment <実行環境名>;
        proxy_pass $scheme://$host$request_uri;
    }
}


変数

$otel_trace_id

トレースIDが割り当てられている。

$otel_span_id

現在のスパンIDが割り当てられている。

$otel_parent_id

親スパンのスパンIDが割り当てられている。

$otel_parent_sampled

受信したリクエストに親スパンが存在する場合、1になる。

Parent Basedなサンプリングを実行できる。

http {
    otel_trace $otel_parent_sampled;
}