ACK クラスター内でサービスを要求すると、CORS ポリシーによってブロックされました エラーが発生します。これは、ブラウザが同一オリジンポリシーを適用しており、Web ページが同じプロトコル、ドメイン、およびポートからのみリソースにアクセスすることを許可しているためです。たとえば、https://example.com のサイトは、https://api.example.com のような別のドメインのリソースに直接アクセスできません。Nginx Ingress のアノテーションを設定することで、特定のクロスオリジンリクエストを許可するクロスオリジンリソース共有 (CORS) ポリシーを有効化できます。
仕組み
CORS は、シンプルリクエストとプリフライトリクエストの 2 種類のリクエストを処理します。シンプルリクエストはサーバーに直接送信されます。プリフライトリクエストでは、ブラウザがメインリクエストを送信する前に、まず事前の OPTIONS リクエストを送信して権限を取得する必要があります。
リクエストが次のいずれかの条件を満たす場合、それはプリフライトリクエストです。
-
リクエストが
GET、HEAD、またはPOST以外のメソッドを使用している場合。 -
リクエストが
POSTメソッドを使用しており、Content-Typeがtext/plain、application/x-www-form-urlencoded、またはmultipart/form-dataではない場合。 -
カスタムヘッダーが含まれている場合。
ブラウザが Nginx Ingress にシンプルリクエストを送信すると、次のプロセスが実行されます。
-
ブラウザはリクエストに
Originヘッダーを追加します。Originヘッダーには、対応するリソースのオリジンが含まれます (例:Origin: https://example.com)。 -
Nginx Ingress コントローラーは、リクエストの HTTP メソッドと
Originヘッダーの値を CORS 設定と比較して一致を検索します。一致が見つかった場合、応答にAccess-Control-Allow-Originヘッダーを追加します。Access-Control-Allow-Originヘッダーには、元のリクエストからのOriginヘッダーの値が含まれます。 -
ブラウザは応答を受信し、
Access-Control-Allow-Originの値がリクエストのオリジンと一致するかどうかを確認します。一致する場合、リクエストは成功します。一致しない場合、または応答にAccess-Control-Allow-Originヘッダーが含まれていない場合、リクエストは失敗します。
プリフライトリクエストは、まず次のステップを完了します。成功した場合、シンプルリクエストと同様に進みます。
-
ブラウザは、実際のリクエストのメソッド (
Access-Control-Request-Method) とヘッダー (Access-Control-Request-Headers) を含むOPTIONSリクエストを送信します。 -
プリフライトリクエストのメソッドまたはヘッダーが許可されていない場合、リクエストは失敗し、メインリクエストは送信されません。
操作手順
ステップ 1: CORS の設定
-
ACK コンソールにログインします。ACK コンソールの左側のナビゲーションウィンドウで、クラスターリスト を選択します。
-
クラスターリスト ページで、対象のクラスターの名前をクリックし、左側のナビゲーションウィンドウで を選択します。
-
ルーティング ページで、対象の Ingress を見つけ、操作 列にある YAML の編集 をクリックします。
-
ユースケースに基づいて Nginx Ingress を設定します。一般的な設定については、「一般的な Nginx Ingress CORS アノテーション」をご参照ください。
認証情報または Cookie を伴うリクエスト
これは、一般的なフロントエンドとバックエンドの分離シナリオに適用されます。フロントエンドアプリケーション (https://example.com または https://app.example.com) が、Cookie や Authorization リクエストヘッダーなどの認証情報を含めてバックエンド API (https://api.example.com) にアクセスする必要がある場合です。
次の例に示すように、annotations 設定を YAML ファイルに追加します。この例では、example.com および app.example.com オリジンからの GET や POST などのメソッドに対するクロスオリジンアクセスを有効にします。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress-secure
annotations:
# Enable CORS.
nginx.ingress.kubernetes.io/enable-cors: "true"
# Allow requests with credentials, such as cookies and Authorization headers.
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
# Specify the exact origins allowed to make cross-origin requests. Do not use "*" in credentialed mode.
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com, https://app.example.com"
# Specify the allowed HTTP methods.
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
# Specify the allowed request headers. You must include any custom headers required by your application, such as Authorization.
nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type, Authorization"
# Specify which custom response headers are exposed to the browser.
nginx.ingress.kubernetes.io/cors-expose-headers: "X-Request-ID, Content-Length, Content-Range"
# Set the maximum cache duration for preflight requests in seconds. The example value is 86400, which is 24 hours.
nginx.ingress.kubernetes.io/cors-max-age: "86400"
...
認証情報なしのリクエスト
このシナリオは、認証を必要としない公開の読み取り専用リクエスト用です。
YAML で、次の annotations 設定を追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress-secure
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
# When cors-allow-origin is "*", cors-allow-credentials must be "false".
nginx.ingress.kubernetes.io/cors-allow-credentials: "false"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, HEAD"
...
ステップ 2: CORS 設定の検証
curl を使用して、ブラウザが OPTIONS プリフライトリクエストを送信するのをシミュレートします。
curl -i -X OPTIONS 'https://api.example.com/your/path' \
-H 'Origin: https://app.example.com' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization'
期待される出力:成功したリクエストは 2xx 状態コードを返します。通常は 204 No Content または 200 OK です。
HTTP/2 204
date: Fri, 12 Sep 2025 03:51:12 GMT
access-control-allow-origin: https://example.com, https://app.example.com
access-control-allow-credentials: true
access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
access-control-allow-headers: Content-Type, Authorization
応答ヘッダーの access-control-allow-* の値が、Ingress リソースで設定された nginx.ingress.kubernetes.io/cors-* の値と一致するかどうかを確認します。
一般的な Nginx Ingress CORS アノテーション
|
アノテーション |
説明 |
対応する HTTP ヘッダー |
例 |
|
|
CORS を有効にするかどうかを指定します。 |
N/A |
|
|
|
リソースへのアクセスを許可するオリジンを指定します。複数のオリジンはコンマで区切ります。 |
Access-Control-Allow-Origin |
|
|
|
GET、POST、PUT などの許可されたメソッドを指定します。 |
Access-Control-Allow-Methods |
|
|
|
許可されたカスタムリクエストヘッダーを指定します。 |
Access-Control-Allow-Headers |
|
|
|
Cookie や HTTP 認証情報など、認証情報を伴うリクエストを許可するかどうかを指定します。 |
Access-Control-Allow-Credentials |
|
|
|
ブラウザがアクセスできる応答ヘッダーを指定します。 このアノテーションには、Nginx Ingress コントローラー v0.44 以降が必要です。 |
Access-Control-Expose-Headers |
|
|
|
ブラウザがプリフライト応答をキャッシュできる最大時間 (秒単位) です。キャッシュ時間を長くすると、プリフライトリクエストの数が減ります。より厳格なセキュリティのためには、より低い値を使用できます。 |
Access-Control-Max-Age |
|
よくある質問
クロスオリジンエラーのトラブルシューティング
ブラウザの開発者ツールでネットワークリクエストを確認するか、Nginx Ingress コントローラーのログを確認します。リクエストのオリジン、メソッド、およびヘッダーが Ingress CORS 設定によって許可されていることを確認します。
次の例は、典型的なクロスオリジンエラー出力です。リクエストは POST メソッドを使用しましたが、このメソッドは Access-Control-Allow-Methods 応答ヘッダーで許可されていません。
-
Method POST is not allowed by Access-Control-Allow-Methods in preflight response -
Access to fetch at 'https://api.example.com/data' from origin 'https://app.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: xxxx.
nginx.ingress.kubernetes.io/cors-allow-credentials: "true" を設定した後、nginx.ingress.kubernetes.io/cors-allow-origin を "*" に設定できますか?
いいえ、できません。これは W3C 仕様とブラウザのセキュリティポリシーによって強制されています。リクエストが認証情報 (Cookie など) を送信する必要がある場合、サーバーは信頼するオリジンを明示的に指定する必要があり、ワイルドカード * を使用することはできません。これは、悪意のあるウェブサイトがユーザーのログイン認証情報を使用してサーバーにリクエストを送信するのを防ぎ、潜在的なセキュリティリスクを回避するためです。
同じドメイン上の異なるパス (例: /api/public/* や /api/private/*) に対して、異なる CORS ポリシーを設定するにはどうすればよいですか?
Nginx Ingress では、CORS アノテーションは Ingress リソースレベルで適用され、パスレベルの設定はサポートされていません。標準的な方法としては、異なる CORS ポリシーを必要とするパスのグループごとに個別の Ingress リソースを作成します。たとえば、api-public-ingress.yaml と api-private-ingress.yaml を作成し、それぞれに異なる CORS アノテーションを設定します。
カスタムレスポンスヘッダーへのアクセス
デフォルトでは、クロスオリジンリクエストを処理する際、ブラウザは Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma を含む標準レスポンスヘッダーにのみアクセスできます。サーバーから返される X-Request-ID などのカスタムヘッダーフィールドは、設定なしではクライアントサイド JavaScript からは可視ではありません。
nginx.ingress.kubernetes.io/cors-expose-headers アノテーションは、Access-Control-Expose-Headers HTTP レスポンスヘッダーを設定するために使用され、クライアントサイド JavaScript コードがアクセスできる非標準レスポンスヘッダーフィールドを決定します。具体的な設定については、「認証情報または Cookie を伴うクロスオリジンシナリオ」をご参照ください。
参考文献
-
このトピックでは、Nginx Ingress コントローラーの一般的な CORS アノテーションのみを扱っています。詳細については、Enable CORS の公式ドキュメントをご参照ください。
-
「Nginx Ingress の問題のトラブルシューティング」をご参照ください。