はい、承知いたしました。Ingress-Nginx Annotations の便利な設定集に関する詳細な解説記事を作成します。約5000語のボリュームで、Ingress-Nginx を効果的に活用するための様々な Annotation の設定方法、ユースケース、注意点などを網羅的に解説します。
以下に記事の内容を直接表示します。
Ingress-Nginx Annotations 徹底活用ガイド:実践的な設定集とその詳細
Kubernetes 環境で外部からのトラフィックをサービスにルーティングする際に、Ingress は非常に重要な役割を果たします。特に、広く利用されている Ingress Controller である Ingress-Nginx は、その柔軟性と豊富な機能を Annotation を通じて提供しており、これにより高度なトラフィック管理、セキュリティ強化、パフォーマンス最適化などが可能になります。
この記事では、Ingress-Nginx が提供する様々な Annotation に焦点を当て、それぞれの設定方法、具体的なユースケース、そしてその背後にある Nginx の仕組みまで、詳細かつ網羅的に解説します。約5000語にわたるこのガイドを通じて、Ingress-Nginx の Annotation を自在に操り、Kubernetes クラスタの外部アクセスをより効果的に制御できるようになることを目指します。
1. はじめに:なぜ Ingress-Nginx と Annotation なのか
Kubernetes における Ingress の役割
Kubernetes クラスタで稼働するアプリケーションは、通常 Pod や Service としてデプロイされます。Service はクラスタ内部での Pod へのアクセスを抽象化しますが、外部インターネットからこれらのサービスにアクセスするためには、何らかの仕組みが必要です。NodePort や LoadBalancer といった Service Type も外部公開の手段としてありますが、以下のような課題があります。
- NodePort: 各 Pod が稼働するノードのポートを占有し、ポート管理が煩雑になりがちです。また、外部公開用の固定IPアドレスが通常ありません。
- LoadBalancer: クラウドプロバイダーが提供するロードバランサーをプロビジョニングするため、コストがかかります。また、パスベースやホストベースのルーティングといった高度なトラフィック制御機能が限定的です。
Ingress は、これらの課題を解決するために導入された Kubernetes の API オブジェクトです。Ingress オブジェクトは、外部からのHTTP/HTTPSトラフィックをクラスタ内の Service にルーティングするためのルールを定義します。これにより、単一のIPアドレス(通常はロードバランサー)で複数のサービスへのアクセスを集約し、パスやホスト名に基づいてトラフィックを振り分けることができます。
Ingress Controller と Ingress-Nginx
Ingress オブジェクト自体は、トラフィックルーティングの「定義」に過ぎません。実際にその定義を読み取り、トラフィックを処理するコンポーネントが必要であり、これを Ingress Controller と呼びます。様々な Ingress Controller が存在しますが、中でも Ingress-Nginx は Nginx をベースとしており、高性能かつ豊富な機能を持ち、広くコミュニティに支持されています。
Ingress-Nginx Controller は、Kubernetes API サーバーを監視し、Ingress オブジェクトの作成、更新、削除を検知します。そして、それらの定義に基づいて内部の Nginx の設定ファイルを動的に生成し、リロードすることで、トラフィックルーティングルールをリアルタイムに反映します。
Annotation の重要性
Kubernetes の標準的な Ingress API 仕様は、基本的なホストベースおよびパスベースのルーティング、TLS 終端などをカバーしていますが、Nginx が持つ多様で高度な機能(認証、レートリミット、ヘッダー操作、カスタムリライトなど)をそのまま定義することはできません。
ここで Annotation が登場します。Annotation は、Kubernetes オブジェクトに任意の非構造化メタデータを付与するための仕組みです。Ingress-Nginx Controller は、Ingress オブジェクトに特定のキーを持つ Annotation が付与されている場合、それを特別な設定指示として解釈し、生成する Nginx 設定に反映します。
これにより、Ingress の標準的なフィールドでは表現できない、Ingress-Nginx Controller 特有の高度な設定を、各 Ingress オブジェクトごとに柔軟に適用することが可能になります。Annotation は事実上、Ingress オブジェクトを通じて基盤となる Nginx を細かくチューニングするための主要な手段と言えます。
2. Ingress-Nginx Annotation の基本的な使い方
Annotation は、Kubernetes マニフェストファイルの metadata
セクション内に、annotations
フィールドとしてキーバリュー形式で記述します。Ingress-Nginx が認識する Annotation は、通常 nginx.ingress.kubernetes.io/
というプレフィックスで始まります。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
namespace: default
annotations:
# ここに Ingress-Nginx の Annotation を記述
nginx.ingress.kubernetes.io/rewrite-target: / # 例: リライト設定
nginx.ingress.kubernetes.io/ssl-redirect: "true" # 例: SSL リダイレクト
spec:
ingressClassName: nginx # 使用する Ingress Controller を指定 (Kubernetes 1.18+)
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
tls:
- hosts:
- example.com
secretName: example-tls-secret
Annotation の値は文字列として記述されます。ブール値 (true
/false
) や数値も文字列として指定します。YAML の仕様上、真偽値や数値として解釈されうる文字列(例: "true"
, "false"
, "123"
, "0.5"
, "on"
, "off"
, "yes"
, "no"
) は、明示的に引用符 (""
) で囲むことが推奨されます。これにより、YAML パーサーによる意図しない型変換を防ぎ、Ingress-Nginx Controller が文字列として正しく解釈することを保証できます。
各 Annotation は、特定の機能や Nginx ディレクティブに対応しており、その効果は通常、その Annotation が記述された Ingress オブジェクト全体、あるいはその Ingress オブジェクト内の特定の rules
や paths
に適用されます。
3. 便利な Ingress-Nginx Annotation 設定集
ここからは、Ingress-Nginx が提供する数ある Annotation の中から、特に頻繁に利用され、様々なユースケースで役立つ便利な設定をカテゴリ別に詳しく解説していきます。
3.1. リライト・リダイレクト関連
外部からのリクエストURLを内部のサービスに合わせて書き換えたり、特定のURLに強制的にリダイレクトさせたりするための Annotation です。
nginx.ingress.kubernetes.io/rewrite-target
- 説明: リクエストURLのパスを書き換えます。特に、Ingress の
path
と Backend Service が期待するパス構造が異なる場合に使用します。 - Nginx 対応:
rewrite
ディレクティブ - 設定値: 書き換え後のパス文字列。Ingress の
path
フィールドで捕捉した正規表現グループ ($1
,$2
など) を利用できます。 - 解説: Ingress の
rules.http.paths.path
フィールドは、Incoming リクエストのパスとマッチングルールを定義しますが、そのパスを Backend Service にそのまま転送するとは限りません。rewrite-target
を使うと、Ingress にマッチしたパスを、Backend Service が処理しやすい形に変換できます。例えば、/app/v1/users/123
というパスでアクセスされたものを、Backend Service は/users/123
として受け取りたい場合などに利用します。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rewrite-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 # 正規表現の第2グループを使用
spec:
ingressClassName: nginx
rules:- host: example.com
http:
paths:- path: /app(/|$)(.) # /app または /app/ から始まるパスにマッチ。(/|$)(.) で後続部分を捕捉
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
``
/app/users/123
この例では、というリクエストは、
pathの正規表現
/app(/|$)(.)にマッチします。
(/|$)が第一グループ(ここでは空文字か
/にマッチ)、
(.)が第二グループ(ここでは
users/123)を捕捉します。
rewrite-target: /$2により、リクエストパスは
/users/123に書き換えられて
my-app-service` に転送されます。
- path: /app(/|$)(.) # /app または /app/ から始まるパスにマッチ。(/|$)(.) で後続部分を捕捉
- host: example.com
- 注意点:
path
フィールドに指定する正規表現とrewrite-target
の$N
の使い方が連携しているため、両者を正しく記述する必要があります。正規表現グループ化を理解しておくことが重要です。また、pathType: Exact
と組み合わせることは稀ですが、Prefix
やImplementationSpecific
で正規表現を利用する際に力を発揮します。
nginx.ingress.kubernetes.io/add-base-url
- 説明: Ingress の定義パスを Backend Service に転送する前に、リクエストパスの前に付加するかどうかを制御します。デフォルトでは有効 (
"true"
) です。 - Nginx 対応: Nginx の内部的なパス処理
- 設定値:
"true"
または"false"
- 解説: デフォルトでは、
/app
というpath
で定義されたルールに/app/users
というリクエストがマッチした場合、通常 Backend Service には/users
というパスで転送されます(つまり、Ingress のマッチングルールで使用された/app
というプレフィックスが取り除かれます)。この挙動を無効にし、/app/users
をそのまま Backend に転送したい場合に"false"
に設定します。これは、特に Backend Service が自身のベースパスを意識している場合に便利です。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: add-base-url-example
annotations:
nginx.ingress.kubernetes.io/add-base-url: “false”
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /v1
pathType: Prefix
backend:
service:
name: my-api-service
port:
number: 80
``
/v1/users/123
この例では、というリクエストは
my-api-serviceにも
/v1/users/123として転送されます。デフォルト (
“true”) の場合は
/users/123` として転送されることになります。
- path: /v1
- host: api.example.com
- 関連:
rewrite-target
とは排他的に利用されることが多いです。rewrite-target
はパス全体を能動的に書き換えるのに対し、add-base-url: "false"
はデフォルトのプレフィックス削除挙動を無効にする受動的な設定です。
nginx.ingress.kubernetes.io/permanent-redirect
/ nginx.ingress.kubernetes.io/temporal-redirect
- 説明: マッチしたリクエストを別のURLにリダイレクトします。前者は 301 Permanent Redirect、後者は 302 Found (Temporal Redirect) を返します。
- Nginx 対応:
return
ディレクティブ (301/302 ステータスコード) - 設定値: リダイレクト先のURL
- 解説: 特定の古いURLパスへのアクセスを新しいパスに移行させる場合や、一時的にメンテナンスページにリダイレクトさせたい場合などに使用します。
permanent-redirect
(301) はブラウザや検索エンジンに「このリソースは恒久的に移動した」ことを伝え、キャッシュされる傾向があります。temporal-redirect
(302) は一時的な移動を示唆し、キャッシュされにくいです。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: redirect-example
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: https://new-site.example.com/new-path$request_uri # リクエストURI全体を付けてリダイレクト
spec:
ingressClassName: nginx
rules:- host: old-site.example.com
http:
paths:- path: /old-path
pathType: Prefix
backend:
service: # リダイレクトの場合は backend はダミーでOK
name: dummy-service # 存在しなくても良い
port:
number: 80
``
old-site.example.com/old-path/…
この例では、へのリクエストは、
https://new-site.example.com/new-path/…へ 301 リダイレクトされます。
$request_uri` は Nginx の変数で、元のリクエストURI(クエリパラメータ含む)をそのまま引き継ぐために使われます。
- path: /old-path
- host: old-site.example.com
- 注意点: リダイレクト Annotation が設定されているパスには、Backend Service が指定されていても無視されます(リダイレクトが優先されます)。リダイレクト先のURLは完全なURL(スキーム、ホスト、パス)で指定することも、相対パスで指定することも可能です。
nginx.ingress.kubernetes.io/ssl-redirect
/ nginx.ingress.kubernetes.io/force-ssl-redirect
- 説明: HTTPでアクセスされたリクエストをHTTPSにリダイレクトします。
ssl-redirect
はデフォルト有効ですが、無効にしたり、特定の Ingress で強制的に有効にしたりできます。force-ssl-redirect
は、たとえ Ingress にtls
セクションが定義されていなくてもHTTPSにリダイレクトを強制する場合に使用します。 - Nginx 対応:
return
またはrewrite
ディレクティブ (301 Permanent Redirect) - 設定値:
"true"
または"false"
(ssl-redirect
)、"true"
(force-ssl-redirect
) - 解説: ウェブサイトやアプリケーションへのアクセスは、セキュリティのためにHTTPSを強制するのが一般的です。これらの Annotation はそのための簡易的な設定を提供します。Ingress Controller の ConfigMap でグローバルに
ssl-redirect: "true"
が設定されている場合、個別の Ingress で"false"
を指定することで無効化できます。
force-ssl-redirect: "true"
は、その Ingress にtls
セクションで証明書が定義されていなくても、HTTPアクセスをHTTPSにリダイレクトさせます。これは、TLS終端が Ingress Controller の手前(例: クラウドプロバイダーのロードバランサー)で行われ、Ingress Controller には常にHTTPでトラフィックが到達する場合(いわゆる “Proxy Protocol” や “TLS Passthrough” の手前段階とは異なる)に便利です。この場合、Ingress Controller はリクエストが元々HTTPSだったかどうかを示すヘッダー(例:X-Forwarded-Proto: https
)を見て判断します。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ssl-redirect-example
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: “true” # 明示的に有効化 (デフォルトは有効)
# nginx.ingress.kubernetes.io/force-ssl-redirect: “true” # tlsセクションが無くても強制
spec:
ingressClassName: nginx
rules:- host: secure.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-secure-service
port:
number: 80
tls: # ssl-redirect=”true” を機能させるには tls セクションが必要
- path: /
- hosts:
- secure.example.com
secretName: secure-tls-secret
“`
- secure.example.com
- host: secure.example.com
- 注意点:
ssl-redirect
を有効にするには、通常その Ingress に対応するtls
セクションが定義されている必要があります。force-ssl-redirect
はこの要件を緩和しますが、実際には後段でTLS終端される必要があります。ループを防ぐため、Ingress Controller や手前のロードバランサーがX-Forwarded-Proto
などのヘッダーを正しく設定しているか確認してください。
3.2. 認証・認可関連
Ingress レベルでアクセス認証や簡単な認可を行うための Annotation です。
nginx.ingress.kubernetes.io/auth-type
- 説明: 認証方法を指定します。主に
basic
(Basic認証) またはexternal
(外部認証サービスとの連携) を指定します。 - Nginx 対応:
auth_basic
,auth_request
ディレクティブ - 設定値:
"basic"
または"external"
- 解説: Ingress で保護したいエンドポイントに対し、追加の認証レイヤーを提供します。アプリケーション側で認証機能を実装する必要がなくなる場合や、共通の認証基盤で複数のサービスを保護したい場合に便利です。
- 関連:
auth-secret
,auth-realm
,auth-url
,auth-signin
,auth-response-headers
と組み合わせて使用します。
nginx.ingress.kubernetes.io/auth-secret
- 説明: Basic認証で使用するユーザー名とパスワードを含む Secret リソースの名前を指定します。
- Nginx 対応:
auth_basic_user_file
ディレクティブ - 設定値: Secret リソースの名前
- 解説:
auth-type: basic
と組み合わせて使用します。指定された Secret はtype: kubernetes.io/basic-auth
である必要があり、data
フィールドにauth
というキーでusername:hashed_password
の形式で記述されたファイル内容を持ちます。htpasswd
コマンドで生成した内容を Base64 エンコードして指定するのが一般的です。 - 設定例:
yaml
# ユーザー名 "admin", パスワード "password" の Secret を作成
# echo "admin:$(apr1-md5-crypt password)" | base64
# 上記コマンドは例です。適切なツールでハッシュ化してください。
apiVersion: v1
kind: Secret
metadata:
name: basic-auth-secret
namespace: default
type: kubernetes.io/basic-auth
data:
auth: YWRtaW46JGFwcjEtbWR1Z3NxcnUkdE9vTzlqQ3JpWklzV3F3QzdPcnJCLg== # "admin:hashed_password" の Base64 エンコード
“`yaml
# Ingress で上記 Secret を参照
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-auth-example
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth-secret # Secret の名前を指定
nginx.ingress.kubernetes.io/auth-realm: ‘Authentication Required – My App’ # プロンプトに表示されるレルム
spec:
ingressClassName: nginx
rules:- host: protected.example.com
http:
paths:- path: /private
pathType: Prefix
backend:
service:
name: my-protected-service
port:
number: 80
“`
- path: /private
- host: protected.example.com
- 注意点: Secret リソースは Ingress と同じ Namespace に作成する必要があります。パスワードのハッシュ化には
htpasswd
コマンドなどを使用し、安全な方法で行ってください。
nginx.ingress.kubernetes.io/auth-realm
- 説明: Basic認証のプロンプトに表示されるレルム(領域)のメッセージを指定します。
- Nginx 対応:
auth_basic
ディレクティブ - 設定値: 表示したい文字列
- 解説: ユーザーが認証を求められた際に表示されるダイアログボックスのタイトルや説明として機能します。どのサービスへのアクセスが保護されているのかをユーザーに伝えるために使用します。
- 関連:
auth-type: basic
と組み合わせて使用します。
nginx.ingress.kubernetes.io/auth-url
- 説明: 外部認証サービスのエンドポイントURLを指定します。
- Nginx 対応:
auth_request
ディレクティブ - 設定値: 認証サービスのエンドポイントURL (クラスタ内部の Service URL も可)
- 解説:
auth-type: external
と組み合わせて使用します。Incoming リクエストは、まず指定されたauth-url
のエンドポイントにサブ要求として転送されます。外部認証サービスは、Incoming リクエストのヘッダー(Cookie, Authorization ヘッダーなど)を基に認証・認可処理を行い、その結果を HTTP ステータスコードで返します。Ingress-Nginx Controller は、その応答コードを見て元のリクエストを Backend Service に転送するか、拒否するかを判断します。2xx
(特に200 OK
): 認証成功。元のリクエストを Backend に転送。401 Unauthorized
: 認証失敗。401 エラーを返すか、auth-signin
で指定されたページにリダイレクト。403 Forbidden
: 認可失敗。403 エラーを返すか、auth-signin
で指定されたページにリダイレクト。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-auth-example
annotations:
nginx.ingress.kubernetes.io/auth-type: external
nginx.ingress.kubernetes.io/auth-url: http://auth-service.default.svc.cluster.local/validate # 認証サービスの内部URL
nginx.ingress.kubernetes.io/auth-signin: https://auth.example.com/login # 認証失敗時のリダイレクト先
nginx.ingress.kubernetes.io/auth-response-headers: ‘X-Auth-Request-User,X-Auth-Request-UID’ # 認証サービスからの応答ヘッダーをBackendに転送
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /api/v2
pathType: Prefix
backend:
service:
name: my-api-service-v2
port:
number: 80
``
/api/v2/…
この例では、へのリクエストは全てまず
auth-serviceの
/validateエンドポイントに送られます。認証サービスが
2xxを返せば
my-api-service-v2にリクエストが渡されます。
401または
403の場合は、ユーザーは
https://auth.example.com/login` にリダイレクトされます。
- path: /api/v2
- host: api.example.com
- 注意点: 外部認証サービスは Ingress-Nginx Controller が期待する応答コードとヘッダーを返すように設計する必要があります。
auth-response-headers
は、認証サービスが認証成功時に付加したユーザー情報などのヘッダーを、Backend Service に引き継ぐために使用します。
nginx.ingress.kubernetes.io/auth-signin
- 説明: 外部認証 (
auth-type: external
) が失敗した場合(401または403応答時)に、ユーザーをリダイレクトするログインページなどのURLを指定します。 - Nginx 対応:
error_page
ディレクティブと内部リダイレクト - 設定値: リダイレクト先のURL
- 解説: 未認証のユーザーが保護されたリソースにアクセスしようとした際に、自動的にログインページに案内するための Annotation です。ユーザー体験を向上させます。
- 関連:
auth-type: external
,auth-url
と組み合わせて使用します。
nginx.ingress.kubernetes.io/auth-response-headers
- 説明: 外部認証サービスからの応答に含まれる特定のヘッダーを、Backend Service へのリクエストに引き継ぐように指定します。
- Nginx 対応:
auth_request_get_headers
ディレクティブ (または同等の機能) - 設定値: カンマ区切りのヘッダー名のリスト
- 解説: 外部認証サービスが認証・認可の成功を示すとともに、認証済みユーザーのIDやロールなどの情報をカスタムヘッダーとして返す場合に、その情報をBackend Service が利用できるようにします。これにより、Backend Service は認証ロジックを持つ必要がなく、Incoming リクエストヘッダーを見るだけでユーザーを特定したり、アクセス制御を行ったりできます。
- 関連:
auth-type: external
,auth-url
と組み合わせて使用します。
3.3. TLS/SSL 関連
HTTPS 通信の設定、リダイレクト、プロトコルや Cipher Suite の指定などを行うための Annotation です。
nginx.ingress.kubernetes.io/ssl-redirect
/ nginx.ingress.kubernetes.io/force-ssl-redirect
(解説済みのため、ここでは割愛しますが、TLS カテゴリにおいて重要なため再度言及しました。)
nginx.ingress.kubernetes.io/backend-protocol
- 説明: Backend Service との通信に使用するプロトコルを指定します。デフォルトは HTTP ですが、Backend Service が HTTPS でリスニングしている場合に
HTTPS
を指定します。 - Nginx 対応:
proxy_pass
ディレクティブのプロトコル指定 - 設定値:
"HTTP"
または"HTTPS"
- 解説: Ingress Controller でTLS終端を行い、Backend Service との通信は平文の HTTP で行うのが一般的です。しかし、エンドツーエンドの暗号化が必要な場合など、Backend Service も HTTPS で通信したい場合があります。その際にこの Annotation を使用します。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: https-backend-example
annotations:
nginx.ingress.kubernetes.io/backend-protocol: “HTTPS” # Backend と HTTPS で通信
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-backend-service # Backend Service が HTTPS (通常 443) でリスニングしていることを想定
port:
number: 443 # Backend Service の HTTPS ポート
tls:
- path: /
- hosts:
- api.example.com
secretName: api-tls-secret # Ingress Controller で TLS 終端
“`
- api.example.com
- host: api.example.com
- 注意点: Backend Service は指定されたポートで HTTPS を正しく処理できる必要があります。自己署名証明書を使用している場合は、Ingress Controller にその証明書を信頼させるための追加設定(ConfigMap や DaemonSet/Deployment の Volume Mount など)が必要になる場合があります。
nginx.ingress.kubernetes.io/ssl-passthrough
- 説明: TLS通信をIngress Controllerで終端せず、Backend Service にそのまま引き渡します。
- Nginx 対応:
stream
モジュール (通常の HTTP/HTTPS プロキシとは異なる) - 設定値:
"true"
- 解説: 通常、Ingress Controller はTLS証明書を配置し、HTTPSリクエストを復号化してBackend Service に平文のHTTPで転送します。しかし、Backend Service が独自のTLS証明書を持っており、アプリケーションレベルでTLS終端を行いたい場合(例: gRPC with TLS, Mutual TLS 認証など)にこの設定を使用します。このモードでは、Ingress Controller は TCP レベルで接続をそのままBackend Service に転送するだけになります。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ssl-passthrough-example
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: “true” # TLS パススルーを有効化
spec:
ingressClassName: nginx
rules:- host: grpc.example.com
http: # 注意: ssl-passthrough では通常 http セクションはあまり意味を持たない
paths:- path: / # パスベースルーティングは機能しない
pathType: Prefix
backend:
service:
name: my-grpc-service # Backend Service が TLS でリスニングしていることを想定
port:
number: 443 # TLS ポートを指定
tls: [] # tls セクションは不要 (Ingress Controller が TLS 終端しないため)
“`
- path: / # パスベースルーティングは機能しない
- host: grpc.example.com
- 注意点:
ssl-passthrough: "true"
が設定された Ingress では、パスベースやヘッダーベースのルーティング、認証、リライト、レートリミットなど、多くの HTTP レイヤーの機能は利用できません。Nginx の Stream モジュールによって TCP 接続がそのまま転送されるためです。ルーティングは主に SNI (Server Name Indication) に基づいて行われます。同じリスニングポート(通常443)で TLS パススルーと通常の TLS 終端を混在させる場合、SNI が必須となります。
nginx.ingress.kubernetes.io/ssl-ciphers
/ nginx.ingress.kubernetes.io/ssl-protocols
- 説明: TLS 接続で使用を許可する Cipher Suites (暗号スイート) および プロトコルバージョンを指定します。
- Nginx 対応:
ssl_ciphers
,ssl_protocols
ディレクティブ - 設定値: Nginx で有効な Cipher Suite 名 / プロトコル名のリスト
- 解説: セキュリティ要件に合わせて、古い/脆弱な暗号やプロトコルを無効化するために使用します。デフォルト設定は通常安全ですが、特定のコンプライアンス基準を満たす必要がある場合に調整します。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-security-example
annotations:
nginx.ingress.kubernetes.io/ssl-protocols: “TLSv1.2 TLSv1.3” # TLSv1.2 および TLSv1.3 のみ許可
nginx.ingress.kubernetes.io/ssl-ciphers: “EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH” # 推奨されるモダンな Cipher Suites の例
spec:
ingressClassName: nginx
rules:- host: secure.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-secure-service
port:
number: 443
tls:
- path: /
- hosts:
- secure.example.com
secretName: secure-tls-secret
“`
- secure.example.com
- host: secure.example.com
- 注意点: サポートされていない Cipher Suite 名やプロトコル名を指定すると、Nginx 設定の生成に失敗し、Ingress が正しく動作しなくなる可能性があります。指定する値は Nginx のバージョンと OpenSSL ライブラリのバージョンに依存するため、Ingress-Nginx Controller のバージョンに対応する Nginx 公式ドキュメントを参照することを推奨します。
3.4. レートリミット関連
Incoming リクエストに対して、接続数、リクエスト数、帯域幅などの制限をかけるための Annotation です。サービス保護やリソース枯渇防止に役立ちます。
nginx.ingress.kubernetes.io/limit-rps
/ nginx.ingress.kubernetes.io/limit-rpm
- 説明: 1秒あたり (rps: requests per second) または 1分あたり (rpm: requests per minute) のリクエスト数を制限します。
- Nginx 対応:
limit_req_zone
,limit_req
ディレクティブ - 設定値: 許可するリクエスト数 (整数)
- 解説: 短時間での大量リクエスト(例: DDoS攻撃、ボットによるクロール、バグのあるクライアント)から Backend Service を保護します。指定された閾値を超えたリクエストは、デフォルトで 503 Service Temporarily Unavailable エラーで拒否されます。制限は、デフォルトではクライアントのIPアドレス (
$binary_remote_addr
) ごとに適用されます。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rate-limit-example
annotations:
nginx.ingress.kubernetes.io/limit-rps: “10” # 1秒あたり10リクエストに制限
nginx.ingress.kubernetes.io/limit-burst: “20” # バーストを20まで許可
# nginx.ingress.kubernetes.io/limit-rpm: “600” # 1分あたり600リクエスト (rps: 10 と同じ)
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /limited-api
pathType: Prefix
backend:
service:
name: my-api-service
port:
number: 80
“`
- path: /limited-api
- host: api.example.com
- 関連:
limit-burst
,limit-connections
- 注意点:
limit-rps
とlimit-rpm
は同時に設定できません。どちらか一方を使用します。制限の単位はクライアントIP以外にも設定可能ですが、デフォルトではクライアントIPが使用されます。後述のlimit-by-key
Annotation (廃止予定の場合あり、ConfigMap のlimit-conn-zone
やlimit-req-zone
設定で代替) やconfiguration-snippet
で詳細な制御が可能です。
nginx.ingress.kubernetes.io/limit-burst
- 説明: レート制限 (
limit-rps
またはlimit-rpm
) を超えて一時的に許可するリクエスト数のバーストサイズを指定します。 - Nginx 対応:
limit_req
ディレクティブのburst
パラメータ - 設定値: 許可するバーストサイズ (整数)
- 解説: レート制限は厳密すぎると、瞬間的なトラフィック増加(例: ページ読み込み時の多数のリソースリクエスト)によって正当なリクエストまで拒否してしまう可能性があります。
limit-burst
は、平均的なレートは守りつつも、瞬間的なスパイクに対応するためのバッファを提供します。limit-rps: 10
,limit-burst: 20
の場合、通常は1秒あたり10リクエストに制限されますが、一時的には最大で20リクエストまで受け付け、超過分はキューイングされるか、キューがいっぱいの場合は拒否されます。 - 関連:
limit-rps
,limit-rpm
nginx.ingress.kubernetes.io/limit-connections
- 説明: クライアントIPアドレスごとに同時に確立できる接続数を制限します。
- Nginx 対応:
limit_conn_zone
,limit_conn
ディレクティブ - 設定値: 許可する接続数 (整数)
- 解説: クライアントからの大量の同時接続によって Backend Service や Ingress Controller のリソースが枯渇するのを防ぎます。HTTP/1.1 の Keep-Alive 接続など、一度確立されると長時間維持される接続に対して有効です。
- 関連:
limit-rps
,limit-rpm
nginx.ingress.kubernetes.io/limit-rate
/ nginx.ingress.kubernetes.io/limit-rate-after
- 説明: クライアントへの応答転送速度(帯域幅)を制限します。
limit-rate
は常に適用される制限、limit-rate-after
は指定したデータ量転送後に適用される制限です。 - Nginx 対応:
limit_rate
,limit_rate_after
ディレクティブ - 設定値: 帯域幅 (バイト/秒、例:
"1m"
は 1MB/秒) - 解説: 大容量ファイルのダウンロードなどによる帯域幅の過剰な消費を防ぎます。
limit-rate-after
と組み合わせることで、最初の一定量は高速に転送し、それ以降を制限するといった柔軟な制御が可能です。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bandwidth-limit-example
annotations:
nginx.ingress.kubernetes.io/limit-rate-after: “5m” # 最初の 5MB は無制限
nginx.ingress.kubernetes.io/limit-rate: “1m” # それ以降は 1MB/秒 に制限
spec:
ingressClassName: nginx
rules:- host: files.example.com
http:
paths:- path: /downloads
pathType: Prefix
backend:
service:
name: file-server-service
port:
number: 80
“`
- path: /downloads
- host: files.example.com
- 注意点: 帯域幅制限は Nginx Worker プロセスごとに適用されるため、クライアントの合計帯域幅は設定値 × Worker 数となる場合があります。これは主にダウンロード速度に影響します。
3.5. タイムアウト関連
Ingress Controller と Backend Service 間、あるいはクライアントと Ingress Controller 間の各種タイムアウトを設定します。
nginx.ingress.kubernetes.io/proxy-connect-timeout
- 説明: Nginx が Backend Service への接続を確立する際のタイムアウト時間を指定します。
- Nginx 対応:
proxy_connect_timeout
ディレクティブ - 設定値: タイムアウト時間 (秒、例:
"5"
) - 解説: Backend Service が応答しない、あるいはネットワークの問題で接続できない場合に、いつまで接続確立を待つかを制御します。この時間を短くしすぎると、一時的なネットワーク遅延でもエラーになる可能性があります。
nginx.ingress.kubernetes.io/proxy-send-timeout
- 説明: Nginx が Backend Service にリクエストを送信する際のタイムアウト時間を指定します。
- Nginx 対応:
proxy_send_timeout
ディレクティブ - 設定値: タイムアウト時間 (秒、例:
"10"
) - 解説: Nginx が Backend にリクエストボディなどを送信中に、Backend が一定時間データを受け付けなかった場合に発生するタイムアウトです。
nginx.ingress.kubernetes.io/proxy-read-timeout
- 説明: Nginx が Backend Service から応答を読み取る際のタイムアウト時間を指定します。
- Nginx 対応:
proxy_read_timeout
ディレクティブ - 設定値: タイムアウト時間 (秒、例:
"60"
) - 解説: Nginx が Backend から応答の最初のバイトを受け取ってから、最後のバイトを受け取るまでの間の、各読み取り操作に対するタイムアウト時間を指定します。Backend Service が処理に時間がかかっている場合などに、いつまで待つかを制御します。この時間を短くしすぎると、時間のかかるリクエスト(例: レポート生成、長時間ポーリング)が途中で切断される可能性があります。長時間処理が必要な場合は、この値を適切に長く設定するか、非同期処理への切り替えを検討します。
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout
- 説明: Backend Service へのリクエストが失敗した場合に、次の Upstream (Backend Pod) へのリクエストを試行する際の最大時間を指定します。
- Nginx 対応:
proxy_next_upstream_timeout
ディレクティブ - 設定値: タイムアウト時間 (秒または分、例:
"1m"
) - 解説: Backend Pod が複数ある場合、Ingress Controller はデフォルトで次の Pod にリクエストを再試行することがあります。この Annotation はその再試行全体の制限時間を設定します。
タイムアウト Annotation の設定例
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: timeout-example
annotations:
nginx.ingress.kubernetes.io/proxy-connect-timeout: "5" # 接続確立タイムアウト 5秒
nginx.ingress.kubernetes.io/proxy-send-timeout: "15" # 送信タイムアウト 15秒
nginx.ingress.kubernetes.io/proxy-read-timeout: "120" # 読み取りタイムアウト 120秒
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /long-process
pathType: Prefix
backend:
service:
name: processing-service
port:
number: 80
この例では、時間がかかる可能性のある /long-process
エンドポイントに対して、読み取りタイムアウトを長く設定しています。
3.6. ヘッダー操作関連
クライアントから Backend Service へのリクエストヘッダー、あるいは Backend Service からクライアントへのレスポンスヘッダーを操作(追加、削除、変更)するための Annotation です。
これらの操作の多くは、後述する configuration-snippet
を使用して Nginx の add_header
, proxy_set_header
, proxy_hide_header
, proxy_pass_request_headers
などのディレクティブを直接記述することで実現できます。しかし、Ingress-Nginx はいくつかの一般的なヘッダー操作を専用の Annotation で提供しています。
nginx.ingress.kubernetes.io/add-response-header
/ nginx.ingress.kubernetes.io/remove-response-header
- 説明: Backend Service からの応答に特定のヘッダーを追加したり、特定のヘッダーを削除したりします。
- Nginx 対応:
add_header
,proxy_hide_header
ディレクティブ - 設定値: ヘッダー名と値 (追加の場合、例:
"X-Frame-Options: SAMEORIGIN"
), ヘッダー名 (削除の場合、例:"Server"
) - 解説: セキュリティヘッダー(HSTS, X-Frame-Options, X-Content-Type-Optionsなど)を追加したり、Backend が返す不要なヘッダー(サーバー情報など)を削除したりするために使用します。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: header-example
annotations:
nginx.ingress.kubernetes.io/add-response-header: ‘Strict-Transport-Security: “max-age=31536000; includeSubDomains; preload”, X-Frame-Options: “SAMEORIGIN”, X-Content-Type-Options: “nosniff”‘
nginx.ingress.kubernetes.io/remove-response-header: ‘Server,X-Powered-By’
spec:
ingressClassName: nginx
rules:- host: www.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-web-service
port:
number: 80
“`
複数のヘッダーを指定する場合は、カンマ区切りで記述します。ヘッダーの値にコロンが含まれる場合は、値全体を引用符で囲む必要があります。
- path: /
- host: www.example.com
- 注意点:
add_header
は Backend からの応答コードが 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 の場合にのみ適用されます。それ以外のコード(例: 404, 500)には適用されません。全てのリクエストに対してヘッダーを追加したい場合は、後述のserver-snippet
またはconfiguration-snippet
でalways add_header
を使用する必要があります。
nginx.ingress.kubernetes.io/set-request-header
- 説明: Backend Service へのリクエストに特定のヘッダーを追加または変更します。
- Nginx 対応:
proxy_set_header
ディレクティブ - 設定値: ヘッダー名と値 (例:
"X-My-Header: my-value"
) - 解説: クライアントIP (
X-Forwarded-For
)、プロトコル (X-Forwarded-Proto
)、ホスト (Host
) など、プロキシによって変更される可能性があるヘッダーを Backend Service に正しく伝えるために使用します。Ingress-Nginx はデフォルトでこれらの重要なヘッダーを適切に設定しますが、独自のカスタムヘッダーを追加したい場合にも利用できます。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: request-header-example
annotations:
nginx.ingress.kubernetes.io/set-request-header: ‘X-Request-ID: $reqid, X-Backend-Target: $service_name’ # Nginx 変数も利用可能
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-api-service
port:
number: 80
``
$request_uri
この例では、リクエストごとに一意のIDと、ターゲットとなる Backend Service 名をヘッダーとして Backend に転送しています。Nginx が提供する様々な変数(,
$host,
$remote_addr` など)を値として利用できます。
- path: /
- host: api.example.com
3.7. カスタム Nginx 設定 (Snippet 関連)
Ingress-Nginx の既存の Annotation では実現できない高度な設定や、Nginx の特定のディレクティブを直接 Location, Server, HTTP コンテキストに注入するための強力な Annotation です。
nginx.ingress.kubernetes.io/location-snippet
- 説明: 生成される Nginx 設定のうち、該当する
location
ブロック内にカスタム設定を注入します。 - Nginx 対応: Nginx
location
コンテキスト内の任意ディレクティブ - 設定値: Nginx ディレクティブの文字列
- 解説: 特定のパスに対する詳細な設定(例: CORSヘッダー、特定の種類のファイルを直接配信、ユーザーエージェントによるアクセス制御など)を行いたい場合に最もよく使用されます。指定された内容は、Ingress-Nginx によって自動生成された
location
ブロックの中に追加されます。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: location-snippet-example
annotations:
nginx.ingress.kubernetes.io/location-snippet: | # 複数行の場合は | を使用
proxy_set_header X-Custom-Header “my-value”;
add_header Cache-Control “no-cache, no-store”;
if ($request_method = ‘OPTIONS’) {
add_header ‘Access-Control-Allow-Origin’ ‘‘;
add_header ‘Access-Control-Allow-Methods’ ‘GET, POST, OPTIONS’;
add_header ‘Access-Control-Allow-Headers’ ‘DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range’;
add_header ‘Access-Control-Max-Age’ 1728000;
return 204;
}
# CORS 設定の続き (GET, POST など)
add_header ‘Access-Control-Allow-Origin’ ‘‘;
spec:
ingressClassName: nginx
rules:- host: api.example.com
http:
paths:- path: /cors-enabled
pathType: Prefix
backend:
service:
name: my-api-service
port:
number: 80
``
/cors-enabled` パスに対して CORS (Cross-Origin Resource Sharing) 関連のヘッダーを追加し、OPTIONS リクエストを Nginx で直接処理する設定を注入しています。
この例では、
- path: /cors-enabled
- host: api.example.com
- 注意点: 注入する Nginx 設定は、Nginx の構文として正しく、かつ
location
コンテキスト内で有効なディレクティブである必要があります。構文エラーがあると Nginx のリロードが失敗し、Ingress が正しく動作しなくなる可能性があります。また、セキュリティリスク(例: 悪意のある Nginx ディレクティブの注入)にもなりうるため、Snippet の利用は信頼できるユーザーに限定すべきです。
nginx.ingress.kubernetes.io/server-snippet
- 説明: 生成される Nginx 設定のうち、該当する
server
ブロック内にカスタム設定を注入します。 - Nginx 対応: Nginx
server
コンテキスト内の任意ディレクティブ - 設定値: Nginx ディレクティブの文字列
- 解説: 特定のホスト名 (
server_name
) に対する共通設定や、server
コンテキストでしか設定できないディレクティブ(例: カスタムエラーページ、SNI ベースの設定、特定の IP アドレスからのアクセス拒否など)を設定したい場合に利用します。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: server-snippet-example
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
# カスタムエラーページ設定
error_page 404 /custom_404.html;
location = /custom_404.html {
root /usr/share/nginx/html; # Nginx コンテナ内の静的ファイルパス
internal; # 外部からの直接アクセスを禁止
}
# 特定のIPアドレスからのアクセス拒否
deny 192.168.1.0/24;
allow all;
spec:
ingressClassName: nginx
rules:- host: my-app.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
“`
- path: /
- host: my-app.example.com
- 注意点:
location-snippet
と同様、Nginx 構文の正確性が必須です。server
コンテキストで有効なディレクティブのみが使用可能です。location
ブロックが必要な設定(例: エラーページパスの設定)は、Snippet 内にlocation
ブロックごと記述する必要があります。
nginx.ingress.kubernetes.io/configuration-snippet
- 説明: 生成される Nginx 設定のうち、該当する
location
ブロック内の、Backend Service へのプロキシ設定の手前にカスタム設定を注入します。これはlocation-snippet
よりも限定されたスコープです。 - Nginx 対応: Nginx
location
コンテキスト内のプロキシ関連ディレクティブの前 - 設定値: Nginx ディレクティブの文字列
- 解説: 主にプロキシ設定に影響を与えるディレクティブ(例: バッファリング設定、キャッシュ設定、ヘッダー操作など)を注入するために使用します。
location-snippet
はlocation
ブロック内のより広い範囲に注入できますが、configuration-snippet
はプロキシ関連のディレクティブ群の直前に注入されるため、その周辺の設定に特化した用途に適しています。 - 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: config-snippet-example
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
# カスタムヘッダーの追加
proxy_set_header X-Custom-Header “ConfigSnippetValue”;
# バッファリングを無効化 (例: WebSocket など)
proxy_request_buffering off;
proxy_buffering off;
spec:
ingressClassName: nginx
rules:- host: ws.example.com
http:
paths:- path: /websocket
pathType: Prefix
backend:
service:
name: websocket-service
port:
number: 80
“`
- path: /websocket
- host: ws.example.com
- 注意点: 注入される位置が限定されているため、
location
ブロック全体の設定を変更するような用途には向きません。主にプロキシ関連の振る舞いを調整する際に使用します。他の Snippet Annotation と同様、Nginx 構文の正確性が必須です。
Snippet Annotation の使い分けと注意点:
* location-snippet
: 特定パス(Location)の幅広いカスタム設定(認証、リライト、ヘッダー、エラーページなど)。最も柔軟だが、Inject 位置に注意が必要。
* server-snippet
: 特定ホスト名(Server)の共通設定、Server コンテキスト固有の設定(証明書設定の補完など)。
* configuration-snippet
: 特定パス(Location)内の、プロキシ関連設定の直前。プロキシの振る舞い調整に特化。
* これらの Annotation を誤ったコンテキストのディレクティブに使用したり、Nginx 構文エラーを含んだりすると、Ingress-Nginx Controller が Nginx 設定をリロードできず、以下のような問題が発生します。
* 新しい設定が反映されない。
* Ingress Controller のログにエラーが出力される。
* Kubernetes Events に警告またはエラーが記録される(kubectl describe ingress <ingress-name>
で確認可能)。
* Ingress Controller Pod の nginx.conf
を確認し、生成された設定ファイルに問題がないかデバッグすることが重要です (kubectl exec <ingress-controller-pod-name> -- cat /etc/nginx/nginx.conf
)。
* Snippet Annotation は非常に強力ですが、Ingress-Nginx Controller の抽象化レイヤーを直接 Nginx の設定で上書きするため、Ingress-Nginx のバージョンアップによって内部の Nginx 設定構造が変わると、Snippet が意図通りに機能しなくなる可能性があります。また、セキュリティ上のリスク(Nginx 設定ミスによる情報漏洩やサービス停止)もあるため、利用は慎重に行い、変更管理を徹底することが推奨されます。
3.8. パフォーマンス・チューニング関連
圧縮設定やバッファリングなど、パフォーマンスに影響を与える設定を行うための Annotation です。
nginx.ingress.kubernetes.io/enable-gzip
- 説明: 応答の Gzip 圧縮を有効にします。
- Nginx 対応:
gzip
ディレクティブ - 設定値:
"true"
または"false"
- 解説: テキストベースの応答(HTML, CSS, JavaScript, JSON など)を圧縮して転送することで、帯域幅を削減し、コンテンツのダウンロード時間を短縮できます。CPUリソースを消費するため、CPU負荷と帯域幅のトレードオフを考慮して利用します。
nginx.ingress.kubernetes.io/gzip-level
- 説明: Gzip 圧縮レベルを指定します。
- Nginx 対応:
gzip_comp_level
ディレクティブ - 設定値: 1 から 9 までの整数
- 解説: 1が最も速く圧縮率が低い、9が最も遅く圧縮率が高い設定です。通常はデフォルト値(通常1)で十分な効果が得られますが、CPUリソースに余裕があり、さらなる圧縮率を追求したい場合に調整します。
nginx.ingress.kubernetes.io/proxy-buffer-size
/ nginx.ingress.kubernetes.io/proxy-buffers-number
- 説明: Backend Service からの応答をバッファリングするためのバッファサイズと数を指定します。
- Nginx 対応:
proxy_buffer_size
,proxy_buffers
ディレクティブ - 設定値: サイズ (単位付き, 例:
"8k"
) / 数 (整数, 例:"4"
) - 解説: Nginx は Backend Service から応答を受け取り、それを一旦内部のバッファに貯めてからクライアントに送信します。これにより、Backend が応答を生成する速度とクライアントが応答を消費する速度の違いを吸収し、Backend のコネクションを早期に解放してリソース効率を高めることができます。大きな応答を扱う場合や、Backend が応答を非常にゆっくり返すような場合に調整が必要になることがあります。
- 注意点: バッファリングはデフォルトで有効です。WebSocket や Server-Sent Events (SSE) のように、リアルタイム性が重要で低遅延が求められる通信では、バッファリングを無効化 (
proxy_buffering off;
を Snippet で設定) する必要があります。
パフォーマンス Annotation の設定例
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: performance-example
annotations:
nginx.ingress.kubernetes.io/enable-gzip: "true"
nginx.ingress.kubernetes.io/gzip-level: "5"
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" # デフォルトより大きくする例
nginx.ingress.kubernetes.io/proxy-buffers-number: "8" # デフォルトより多くする例
spec:
ingressClassName: nginx
rules:
- host: download.example.com
http:
paths:
- path: /assets
pathType: Prefix
backend:
service:
name: asset-server-service
port:
number: 80
3.9. ロギング・モニタリング関連
アクセスログやエラーログの出力制御に関する Annotation です。
nginx.ingress.kubernetes.io/enable-access-log
/ nginx.ingress.kubernetes.io/enable-error-log
- 説明: 特定の Ingress/Location に対する Nginx のアクセスログまたはエラーログの出力を有効または無効にします。
- Nginx 対応:
access_log
,error_log
ディレクティブ - 設定値:
"true"
または"false"
- 解説: デフォルトでは Ingress Controller 全体でアクセスログやエラーログが出力されますが、特定のトラフィック(例: ヘルスチェックエンドポイント)のログ量を減らしたい場合に、個別の Ingress や Location で無効化できます。逆に、特定の重要なトラフィックのログを確実に残したい場合に明示的に有効化することも考えられますが、通常はデフォルト設定で十分です。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: logging-example
annotations:
nginx.ingress.kubernetes.io/enable-access-log: “false” # このIngressのアクセスログを無効化
spec:
ingressClassName: nginx
rules:- host: healthcheck.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: healthcheck-service
port:
number: 80
“`
- path: /
- host: healthcheck.example.com
- 注意点: これらの Annotation はログの有効/無効を制御しますが、ログの出力先やフォーマットは通常 Ingress Controller の ConfigMap 設定によって制御されます。
3.10. その他の便利な Annotation
上記以外にも様々な Annotation が存在します。いくつか代表的なものを紹介します。
nginx.ingress.kubernetes.io/whitelist-source-range
- 説明: アクセスを許可するクライアントIPアドレス(CIDR形式)の範囲を指定します。
- Nginx 対応:
allow
,deny
ディレクティブ - 設定値: カンマ区切りのCIDRリスト (例:
"10.0.0.0/8,192.168.1.1/32"
) - 解説: 特定のネットワークからのアクセスのみを許可し、それ以外を拒否する場合に使用します。社内ネットワークやVPN経由でのみアクセス可能な内部アプリケーションなどに適用できます。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whitelist-example
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: “10.0.0.0/8,172.16.0.0/12” # 許可するIP範囲
spec:
ingressClassName: nginx
rules:- host: internal-app.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: internal-app-service
port:
number: 80
“`
- path: /
- host: internal-app.example.com
- 注意点: クライアントIPアドレスは、Ingress Controller が稼働しているネットワーク構成に依存します。手前にロードバランサーやプロキシがある場合、Ingress Controller が受け取るのはそれらのIPアドレスになります。実際のクライアントIPを取得するためには、手前のロードバランサーが
X-Forwarded-For
ヘッダーなどを正しく設定し、Ingress Controller の起動設定でuse-forwarded-headers
オプションが有効になっている必要があります。
nginx.ingress.kubernetes.io/affinity
/ nginx.ingress.kubernetes.io/session-cookie-name
etc.
- 説明: セッションアフィニティ(スティッキーセッション)を設定します。特定のクライアントからの連続するリクエストを同じ Backend Pod にルーティングします。
- Nginx 対応:
sticky
モジュール (通常 Ingress-Nginx に組み込まれている) - 設定値:
affinity
:"cookie"
(Cookieベースのアフィニティ) など,session-cookie-name
: Cookie名,session-cookie-expires
: 有効期限,session-cookie-samesite
: SameSite属性 など - 解説: ステートフルなアプリケーション(例: セッション情報を持つウェブアプリケーション)で、クライアントの状態を維持するために使用します。クライアントのブラウザに特定のCookieを発行し、そのCookieの値に基づいて常に同じ Backend Pod にリクエストを転送するようにします。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: affinity-example
annotations:
nginx.ingress.kubernetes.io/affinity: “cookie” # Cookie ベースのアフィニティを有効化
nginx.ingress.kubernetes.io/session-cookie-name: “MyAppSession” # Cookie 名
nginx.ingress.kubernetes.io/session-cookie-expires: “1h” # Cookie 有効期限 1時間
nginx.ingress.kubernetes.kubernetes.io/session-cookie-change-on-failure: “true” # Backend 失敗時に Cookie を再発行
spec:
ingressClassName: nginx
rules:- host: stateful-app.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: stateful-app-service
port:
number: 80
“`
- path: /
- host: stateful-app.example.com
- 注意点: セッションアフィニティは Backend Pod のローリングアップデートやオートスケーリングと相性が悪く、セッションが切断される可能性があります。可能な限り、アプリケーションはステートレスに設計することが推奨されます。
nginx.ingress.kubernetes.io/upstream-keepalive-connections
- 説明: Nginx と Backend Service 間で維持するアイドル状態の Keep-Alive コネクションの最大数を指定します。
- Nginx 対応:
keepalive
ディレクティブ (Upstream ブロック内) - 設定値: コネクション数 (整数)
- 解説: Backend Service との間に永続的なコネクションプールを維持することで、新しいリクエストごとにコネクションを確立するオーバーヘッドを削減し、パフォーマンスを向上させます。Backend Service が Keep-Alive 接続をサポートしている必要があります。
- 設定例:
“`yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keepalive-example
annotations:
nginx.ingress.kubernetes.io/upstream-keepalive-connections: “32” # Backend との間に最大32個の Keep-Alive コネクションを維持
spec:
ingressClassName: nginx
rules:- host: high-traffic-api.example.com
http:
paths:- path: /
pathType: Prefix
backend:
service:
name: high-traffic-api-service
port:
number: 80
“`
- path: /
- host: high-traffic-api.example.com
4. Annotation を使う上での注意点とデバッグ方法
Annotation のバージョン依存性
Ingress-Nginx Controller は活発に開発されており、バージョンアップによって Annotation の名前、挙動、あるいは廃止される Annotation があります。常に使用している Ingress-Nginx Controller のバージョンに対応する公式ドキュメントを参照することが極めて重要です。古いバージョンの Annotation を新しいバージョンで使用したり、その逆を行ったりすると、意図しない挙動になったり、設定が全く無視されたりする可能性があります。
構文エラーとデバッグ
Annotation の値、特に Snippet 系 Annotation に Nginx 構文エラーが含まれていると、Ingress-Nginx Controller は Nginx の設定ファイルを正しく生成・リロードできません。この場合、以下のような方法で問題を確認・デバッグできます。
- Kubernetes Events の確認:
kubectl describe ingress <ingress-name>
を実行し、Events セクションを確認します。Nginx 設定のリロード失敗に関する警告やエラーメッセージが出力されている可能性が高いです。 - Ingress Controller Pod のログ: Ingress-Nginx Controller Pod のログ (
kubectl logs <ingress-controller-pod-name> -n <namespace>
) を確認します。Nginx 設定ファイルの生成失敗やリロード失敗の詳細なエラーメッセージが記録されています。 - 生成された Nginx 設定ファイルの確認: Ingress Controller Pod に exec して、生成された Nginx 設定ファイル (
/etc/nginx/nginx.conf
) の内容を確認します。問題の Ingress に対応するserver
やlocation
ブロックを探し、Snippet の内容が正しく注入されているか、構文エラーがないかを確認します。
kubectl exec <ingress-controller-pod-name> -n <namespace> -- cat /etc/nginx/nginx.conf
Nginx コマンドラインツールで設定ファイルのテストも可能です。
kubectl exec <ingress-controller-pod-name> -n <namespace> -- nginx -t
ConfigMap 設定と Annotation の優先順位
Ingress-Nginx Controller には、クラスタ全体あるいはデフォルトの挙動を制御するための ConfigMap 設定も存在します。ConfigMap で設定された項目と、個別の Ingress Annotation で設定された項目が重複する場合、通常は Annotation の設定が ConfigMap の設定よりも優先 されます。
例えば、ConfigMap でグローバルに ssl-redirect: "true"
と設定されていても、特定の Ingress で nginx.ingress.kubernetes.io/ssl-redirect: "false"
を指定すれば、その Ingress では HTTP -> HTTPS リダイレクトは行われません。
ただし、Snippet Annotation (server-snippet
など) は、ConfigMap で定義されたデフォルト設定(例えば、デフォルトのエラーページ設定など)に 追加 される形で注入されることが多いです。優先順位や挙動の詳細は、Ingress-Nginx のバージョンごとのドキュメントで確認してください。
セキュリティ上の考慮事項
Snippet Annotation は非常に強力である反面、悪意のある設定や誤った設定によってセキュリティ上の脆弱性を生む可能性があります。
- 情報漏洩: サーバー情報、内部IPアドレス、設定パスなどを Nginx 設定を通じて露出させてしまう。
- サービス停止: 構文エラーや無限ループを引き起こす設定により、Nginx プロセスがクラッシュしたり、リソースを過剰消費したりする。
- 不正アクセス: 不適切な
allow
/deny
設定、認証設定の漏れなど。
Snippet Annotation の使用は最小限にとどめ、公式ドキュメントに記載されている専用の Annotation で実現できる機能は、そちらを優先して利用することを強く推奨します。また、Snippet を利用する場合は、注入する設定の内容を慎重にレビューし、信頼できるソースからのみ適用するように制御することが重要です(例: CI/CD パイプラインでの自動チェック、RBAC による Annotation 適用権限の制限)。
ドキュメント参照の重要性
Ingress-Nginx の Annotation は非常に多岐にわたります。この記事で紹介したのはその一部であり、また Ingress-Nginx のバージョンによって利用可能な Annotation やその挙動は変化します。常に最新かつ正確な情報を得るためには、公式ドキュメント(特に Annotation のリストと各バージョンのリリースノート)を参照することが最も重要です。
- Ingress-Nginx 公式ドキュメント: https://kubernetes.github.io/ingress-nginx/
- Annotation リファレンス: https://kubernetes.github.io/ingress-nginx/user-guide/annotations/
5. 実践的な利用シナリオ
API Gateway としての活用
マイクロサービスアーキテクチャにおいて、Ingress-Nginx を簡易的な API Gateway として利用するケースは多いです。この場合、以下のような Annotation が役立ちます。
- 認証:
auth-type
,auth-url
,auth-signin
を使って、共通の認証基盤によるAPIアクセスの保護。 - レートリミット:
limit-rps
,limit-burst
を使って、各クライアント(またはAPIキーなど)からのリクエスト頻度を制限し、Backend API の過負荷を防ぐ。 - ヘッダー操作:
set-request-header
で認証済みのユーザー情報を Backend API に伝えたり、add-response-header
で CORS ヘッダーを付与したりする。 - リライト:
rewrite-target
で、バージョン付きURL (/v1/users
) からバージョンなしの内部パス (/users
) に変換して Backend に転送する。
ウェブサイトのホスティング
静的サイトや動的ウェブアプリケーションのホスティングにも Ingress-Nginx Annotation は有効です。
- SSL/TLS:
ssl-redirect
,ssl-ciphers
,ssl-protocols
で安全な HTTPS アクセスを強制し、TLS 設定を最適化する。Let’s Encrypt と cert-manager を組み合わせることで、証明書の自動発行・更新も容易になります。 - リダイレクト:
permanent-redirect
で古いページから新しいページへユーザーと検索エンジンを誘導する。 - キャッシュ:
configuration-snippet
で Nginx のproxy_cache
関連ディレクティブを設定し、Backend へのリクエストを削減する。 - パフォーマンス:
enable-gzip
,gzip-level
で応答を圧縮し、ページの読み込み速度を向上させる。 - セキュリティヘッダー:
add-response-header
で HSTS, CSP, X-Frame-Options などのセキュリティヘッダーを追加し、様々なブラウザベースの攻撃からユーザーを保護する。
マイクロサービス間の通信 (East-West)
外部公開だけでなく、クラスタ内のマイクロサービス間通信(East-Westトラフィック)でも、Ingress は利用されることがあります。ただし、Service Mesh (Istio, Linkerd など) がより高度な機能(mTLS、回路遮断器など)を提供するため、シンプルなケースに限られます。
- リライト: Backend Service が期待するパス構造と異なる場合に
rewrite-target
で調整する。 - 認証: クラスタ内の共通認証サービスと連携して、サービス間の認証・認可を行う (
auth-type: external
)。 - タイムアウト:
proxy-read-timeout
などで、サービス間の通信におけるタイムアウトを設定し、障害時の挙動を制御する。
これらのシナリオでは、Ingress-Nginx Annotation が、Backend Service のコードを変更することなく、あるいは Backend Service に依存しない形で、共通の関心事(クロスファンクショナル要件)をIngress レベルで効率的に処理するための強力な手段となっていることがわかります。
6. まとめ
この記事では、Kubernetes 環境で広く使われている Ingress-Nginx Controller の核となる機能の一つである Annotation について、その基本的な使い方から、リライト、認証、TLS、レートリミット、タイムアウト、ヘッダー操作、カスタム設定、パフォーマンス関連など、多岐にわたる便利な設定とその詳細を解説しました。
Ingress-Nginx Annotation は、Kubernetes の標準 Ingress API だけでは実現できない高度なトラフィック管理機能を、柔軟かつ宣言的に定義するための強力なツールです。Backend Service の変更を最小限に抑えつつ、外部からのトラフィックに対して様々な処理(セキュリティ、パフォーマンス、ルーティング制御など)を適用できます。
しかし、その強力さゆえに、Annotation の設定ミスはサービスに大きな影響を与える可能性があります。特に Snippet 系の Annotation は、Nginx の内部設定に直接干渉するため、Nginx の構文やディレクティブに関する知識が要求され、慎重な利用と十分なテストが必要です。
この記事で紹介した Annotation は、Ingress-Nginx が提供する機能のほんの一部です。ご自身のユースケースに合わせて、公式ドキュメントを参照しながら、最適な Annotation を見つけ、Ingress-Nginx を最大限に活用してください。Kubernetes の運用において、Ingress-Nginx とその Annotation をマスターすることは、外部アクセスを安全かつ効率的に管理する上で不可欠なスキルとなるでしょう。
将来的に Kubernetes の Gateway API が成熟し、Ingress API を置き換える可能性もありますが、現状では Ingress-Nginx はデファクトスタンダードとして広く利用されており、その Annotation は今後も重要な役割を果たし続けると考えられます。