第8章 ルートの作成
8.1. ルート設定
8.1.1. HTTP ベースのルートの作成
ルートを使用すると、公開された URL でアプリケーションをホストできます。これは、アプリケーションのネットワークセキュリティー設定に応じて、セキュリティー保護または保護なしを指定できます。HTTP ベースのルートとは、セキュアではないルートで、基本的な HTTP ルーティングプロトコルを使用してセキュリティー保護されていないアプリケーションポートでサービスを公開します。
以下の手順では、hello-openshift アプリケーションを例に、Web アプリケーションへのシンプルな HTTP ベースのルートを作成する方法を説明します。
前提条件
-
OpenShift CLI (
oc) がインストールされている。 - 管理者としてログインしている。
- あるポートを公開する Web アプリケーションと、そのポートでトラフィックをリッスンする TCP エンドポイントがあります。
手順
次のコマンドを実行して、
hello-openshiftというプロジェクトを作成します。$ oc new-project hello-openshift
以下のコマンドを実行してプロジェクトに Pod を作成します。
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
以下のコマンドを実行して、
hello-openshiftというサービスを作成します。$ oc expose pod/hello-openshift
次のコマンドを実行して、
hello-openshiftアプリケーションに対して、セキュアではないルートを作成します。$ oc expose svc hello-openshift
検証
作成した
routeリソースを確認するには、次のコマンドを実行します。$ oc get routes -o yaml <name of resource> 1- 1
- この例では、ルートの名前は
hello-openshiftです。
上記で作成されたセキュアでないルートの YAML 定義
apiVersion: route.openshift.io/v1 kind: Route metadata: name: hello-openshift spec: host: hello-openshift-hello-openshift.<Ingress_Domain> 1 port: targetPort: 8080 2 to: kind: Service name: hello-openshift
- 1
<Ingress_Domain>はデフォルトの Ingress ドメイン名です。ingresses.config/clusterオブジェクトはインストール中に作成され、変更できません。別のドメインを指定する場合は、appsDomainオプションを使用して別のクラスタードメインを指定できます。- 2
targetPortは、このルートが指すサービスによって選択される Pod のターゲットポートです。注記デフォルトの ingress ドメインを表示するには、以下のコマンドを実行します。
$ oc get ingresses.config/cluster -o jsonpath={.spec.domain}
8.1.2. ルートのタイムアウトの設定
Service Level Availability (SLA) で必要とされる、低タイムアウトが必要なサービスや、バックエンドでの処理速度が遅いケースで高タイムアウトが必要なサービスがある場合は、既存のルートに対してデフォルトのタイムアウトを設定することができます。
前提条件
- 実行中のクラスターでデプロイ済みの Ingress コントローラーが必要になります。
手順
oc annotateコマンドを使用して、ルートにタイムアウトを追加します。$ oc annotate route <route_name> \ --overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit> 1- 1
- サポートされる時間単位は、マイクロ秒 (us)、ミリ秒 (ms)、秒 (s)、分 (m)、時間 (h)、または日 (d) です。
以下の例では、2 秒のタイムアウトを
myrouteという名前のルートに設定します。$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
8.1.3. HTTP Strict Transport Security
HTTP Strict Transport Security (HSTS) ポリシーは、HTTPS トラフィックのみがルートホストで許可されるブラウザークライアントに通知するセキュリティーの拡張機能です。また、HSTS は、HTTP リダイレクトを使用せずに HTTPS トランスポートにシグナルを送ることで Web トラフィックを最適化します。HSTS は Web サイトとの対話を迅速化するのに便利です。
HSTS ポリシーが適用されると、HSTS はサイトから Strict Transport Security ヘッダーを HTTP および HTTPS 応答に追加します。HTTP を HTTPS にリダイレクトするルートで insecureEdgeTerminationPolicy 値を使用できます。HSTS を強制している場合は、要求の送信前にクライアントがすべての要求を HTTP URL から HTTPS に変更するため、リダイレクトの必要がなくなります。
クラスター管理者は、以下を実行するために HSTS を設定できます。
- ルートごとに HSTS を有効にします。
- ルートごとに HSTS を無効にします。
- ドメインごとに HSTS を適用するか、ドメインと組み合わせた namespace ラベルを使用します。
HSTS はセキュアなルート (edge-termination または re-encrypt) でのみ機能します。この設定は、HTTP またはパススルールートには適していません。
8.1.3.1. ルートごとの HTTP Strict Transport Security の有効化
HTTP 厳密なトランスポートセキュリティー (HSTS) は HAProxy テンプレートに実装され、haproxy.router.openshift.io/hsts_header アノテーションを持つ edge および re-encrypt ルートに適用されます。
前提条件
- プロジェクトの管理者権限があるユーザーで、クラスターにログインしている。
-
ocCLI をインストールしていること。
手順
ルートで HSTS を有効にするには、
haproxy.router.openshift.io/hsts_header値を edge-termed または re-encrypt ルートに追加します。これを実行するには、oc annotateツールを使用してこれを実行できます。$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000;\ 1 includeSubDomains;preload"- 1
- この例では、最長期間は
31536000ミリ秒 (約 8 時間および半分) に設定されます。
注記この例では、等号 (
=) が引用符で囲まれています。これは、annotate コマンドを正しく実行するために必要です。アノテーションで設定されたルートの例
apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload 1 2 3 ... spec: host: def.abc.com tls: termination: "reencrypt" ... wildcardPolicy: "Subdomain"- 1
- 必須。
max-ageは、HSTS ポリシーが有効な期間 (秒単位) を測定します。0に設定すると、これはポリシーを無効にします。 - 2
- オプション:
includeSubDomainsは、クライアントに対し、ホストのすべてのサブドメインにホストと同じ HSTS ポリシーを持つ必要があることを指示します。 - 3
- オプション:
max-ageが 0 より大きい場合、preloadをhaproxy.router.openshift.io/hsts_headerに追加し、外部サービスがこのサイトをそれぞれの HSTS プリロード一覧に含めることができます。たとえば、Google などのサイトはpreloadが設定されているサイトの一覧を作成します。ブラウザーはこれらの一覧を使用し、サイトと対話する前でも HTTPS 経由で通信できるサイトを判別できます。preloadを設定していない場合、ブラウザーはヘッダーを取得するために、HTTPS を介してサイトと少なくとも 1 回対話している必要があります。
8.1.3.2. ルートごとの HTTP Strict Transport Security の無効化
ルートごとに HSTS (HTTP Strict Transport Security) を無効にするには、ルートアノテーションの max-age の値を 0 に設定します。
前提条件
- プロジェクトの管理者権限があるユーザーで、クラスターにログインしている。
-
ocCLI をインストールしていること。
手順
HSTS を無効にするには、以下のコマンドを入力してルートアノテーションの
max-ageの値を0に設定します。$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
ヒントまたは、以下の YAML を適用して ConfigMap を作成できます。
ルートごとに HSTS を無効にする例
metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=0namespace のすべてのルートで HSTS を無効にするには、following コマンドを入力します。
$ oc annotate route --all -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
検証
すべてのルートのアノテーションをクエリーするには、以下のコマンドを入力します。
$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}'出力例
Name: routename HSTS: max-age=0
8.1.4. Cookie の使用によるルートのステートフル性の維持
Red Hat OpenShift Service on AWS は、すべてのトラフィックを同じエンドポイントにヒットさせることによりステートフルなアプリケーションのトラフィックを可能にするスティッキーセッションを提供します。ただし、エンドポイント Pod が再起動、スケーリング、または設定の変更などによって終了する場合、このステートフル性はなくなります。
Red Hat OpenShift Service on AWS は Cookie を使用してセッションの永続化を設定できます。Ingress コントローラーはユーザー要求を処理するエンドポイントを選択し、そのセッションの Cookie を作成します。Cookie は要求の応答として戻され、ユーザーは Cookie をセッションの次の要求と共に送り返します。Cookie は Ingress コントローラーに対し、セッションを処理しているエンドポイントを示し、クライアント要求が Cookie を使用して同じ Pod にルーティングされるようにします。
cookie は、HTTP トラフィックを表示できないので、パススルールートで設定できません。代わりに、ソース IP アドレスをベースに数が計算され、バックエンドを判断します。
バックエンドが変わると、トラフィックが間違ったサーバーに転送されてしまい、スティッキーではなくなります。ソース IP を非表示にするロードバランサーを使用している場合は、すべての接続に同じ番号が設定され、トラフィックは同じ Pod に送られます。
8.1.4.1. Cookie を使用したルートのアノテーション
ルート用に自動生成されるデフォルト名を上書きするために Cookie 名を設定できます。これにより、ルートトラフィックを受信するアプリケーションが Cookie 名を認識できるようになります。Cookie を削除すると、次の要求でエンドポイントの再選択が強制的に実行される可能性があります。そのためサーバーがオーバーロードしている場合には、クライアントからの要求を取り除き、それらの再分配を試行します。
手順
指定される cookie 名でルートにアノテーションを付けます。
$ oc annotate route <route_name> router.openshift.io/cookie_name="<cookie_name>"
ここでは、以下のようになります。
<route_name>- Pod の名前を指定します。
<cookie_name>- cookie の名前を指定します。
たとえば、ルート
my_routeに cookie 名my_cookieでアノテーションを付けるには、以下を実行します。$ oc annotate route my_route router.openshift.io/cookie_name="my_cookie"
変数でルートのホスト名を取得します。
$ ROUTE_NAME=$(oc get route <route_name> -o jsonpath='{.spec.host}')ここでは、以下のようになります。
<route_name>- Pod の名前を指定します。
cookie を保存してからルートにアクセスします。
$ curl $ROUTE_NAME -k -c /tmp/cookie_jar
ルートに接続する際に、直前のコマンドによって保存される cookie を使用します。
$ curl $ROUTE_NAME -k -b /tmp/cookie_jar
8.1.5. パスベースのルート
パスベースのルートは、URL に対して比較できるパスコンポーネントを指定します。この場合、ルートのトラフィックは HTTP ベースである必要があります。そのため、それぞれが異なるパスを持つ同じホスト名を使用して複数のルートを提供できます。ルーターは、最も具体的なパスの順に基づいてルートと一致する必要があります。ただし、これはルーターの実装によって異なります。
以下の表は、ルートのサンプルおよびそれらのアクセシビリティーを示しています。
表8.1 ルートの可用性
| ルート | 比較対象 | アクセス可能 |
|---|---|---|
| www.example.com/test | www.example.com/test | はい |
| www.example.com | いいえ | |
| www.example.com/test および www.example.com | www.example.com/test | はい |
| www.example.com | はい | |
| www.example.com | www.example.com/text | Yes (ルートではなく、ホストで一致) |
| www.example.com | はい |
パスが 1 つでセキュリティー保護されていないルート
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: route-unsecured
spec:
host: www.example.com
path: "/test" 1
to:
kind: Service
name: service-name
- 1
- パスは、パスベースのルートに唯一追加される属性です。
ルーターは TLS を終了させず、要求のコンテンツを読み込みことができないので、パスベースのルーティングは、パススルー TLS を使用する場合には利用できません。
8.1.6. ルート固有のアノテーション
Ingress コントローラーは、公開するすべてのルートのデフォルトオプションを設定できます。個別のルートは、アノテーションに個別の設定を指定して、デフォルトの一部を上書きできます。Red Hat では、ルートアノテーションの Operator 管理ルートへの追加はサポートしません。
複数のソース IP またはサブネットのホワイトリストを作成するには、スペースで区切られたリストを使用します。他の区切りタイプを使用すると、一覧が警告やエラーメッセージなしに無視されます。
表8.2 ルートアノテーション
| 変数 | 説明 | デフォルトで使用される環境変数 |
|---|---|---|
|
|
ロードバランシングアルゴリズムを設定します。使用できるオプションは、 |
パススルールートの |
|
|
関連の接続を追跡する cookie の使用を無効にします。 | |
|
| このルートに使用するオプションの cookie を指定します。名前は、大文字、小文字、数字、"_" または "-" を任意に組み合わせて指定する必要があります。デフォルトは、ルートのハッシュ化された内部キー名です。 | |
|
|
ルーターからバッキングされる Pod に対して許容される接続最大数を設定します。 | |
|
|
| |
|
|
同じソース IP アドレスで行われる同時 TCP 接続の数を制限します。数値を受け入れます。 | |
|
|
同じソース IP アドレスを持つクライアントが HTTP 要求を実行できるレートを制限します。数値を受け入れます。 | |
|
|
同じソース IP アドレスを持つクライアントが TCP 接続を確立するレートを制限します。数値を受け入れます。 | |
|
| ルートのサーバー側のタイムアウトを設定します。(TimeUnits) |
|
|
| このタイムアウトは、クリアテキスト、エッジ、再暗号化、またはパススルーのルートを介した Web Socket などトンネル接続に適用されます。cleartext、edge、または reencrypt のルートタイプでは、このアノテーションは、タイムアウト値がすでに存在するタイムアウトトンネルとして適用されます。パススルーのルートタイプでは、アノテーションは既存のタイムアウト値の設定よりも優先されます。 |
|
|
|
設定できるのは、Ingress Controller または ingress config です。このアノテーションでは、ルーターを再デプロイし、HA プロキシーが haproxy |
|
|
| バックエンドのヘルスチェックの間隔を設定します。(TimeUnits) |
|
|
| ルートのホワイトリストを設定します。ホワイトリストは、承認したソースアドレスの IP アドレスおよび CIDR 範囲の一覧をスペース区切りにします。ホワイトリストに含まれていない IP アドレスからの要求は破棄されます。 ホワイトリストの許可される IP アドレスおよび CIDR 範囲の最大数は 61 です。 | |
|
| edge terminated または re-encrypt ルートの Strick-Transport-Security ヘッダーを設定します。 | |
|
|
Syslog ヘッダーの | |
|
| バックエンドの要求の書き換えパスを設定します。 | |
|
| Cookie を制限するために値を設定します。値は以下のようになります。
この値は、re-encrypt および edge ルートにのみ適用されます。詳細は、SameSite cookie のドキュメント を参照してください。 | |
|
|
ルートごとに
|
|
環境変数を編集することはできません。
ルータータイムアウト変数
TimeUnits は数字、その後に単位を指定して表現します。 us *(マイクロ秒)、ms (ミリ秒、デフォルト)、s (秒)、m (分)、h *(時間)、d (日)
正規表現: [1-9][0-9]*(us\|ms\|s\|m\|h\|d)
| 変数 | デフォルト | 説明 |
|---|---|---|
|
|
| バックエンドでの後続の liveness チェックの時間の長さ。 |
|
|
| クライアントがルートに接続する場合の TCP FIN タイムアウトの期間を制御します。接続切断のために送信された FIN が指定の時間内に応答されない場合は、HAProxy が接続を切断します。小さい値を設定し、ルーターでリソースをあまり使用していない場合には、リスクはありません。 |
|
|
| クライアントがデータを確認するか、送信するための時間の長さ。 |
|
|
| 最大接続時間。 |
|
|
| ルーターからルートをバッキングする Pod の TCP FIN タイムアウトを制御します。 |
|
|
| サーバーがデータを確認するか、送信するための時間の長さ。 |
|
|
| TCP または WebSocket 接続が開放された状態で保つ時間数。このタイムアウト期間は、HAProxy が再読み込みされるたびにリセットされます。 |
|
|
|
新しい HTTP 要求が表示されるまで待機する最大時間を設定します。この値が低すぎる場合には、ブラウザーおよびアプリケーションの
有効なタイムアウト値には、想定した個別のタイムアウトではなく、特定の変数を合計した値に指定することができます。たとえば、 |
|
|
| HTTP 要求の伝送にかかる時間。 |
|
|
| ルーターがリロードし、新規の変更を受け入れる最小の頻度を許可します。 |
|
|
| HAProxy メトリクスの収集タイムアウト。 |
ルート設定のカスタムタイムアウト
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/timeout: 5500ms 1
...
- 1
- HAProxy 対応の単位 (
us、ms、s、m、h、d) で新規のタイムアウトを指定します。単位が指定されていない場合は、msがデフォルトになります。
パススルールートのサーバー側のタイムアウト値を低く設定し過ぎると、WebSocket 接続がそのルートで頻繁にタイムアウトする可能性があります。
特定の IP アドレスを 1 つだけ許可するルート
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
複数の IP アドレスを許可するルート
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12
IP アドレスの CIDR ネットワークを許可するルート
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24
IP アドレスと IP アドレスの CIDR ネットワークの両方を許可するルート
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8
書き換えターゲットを指定するルート
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/rewrite-target: / 1
...
- 1
- バックエンドの要求の書き換えパスとして
/を設定します。
ルートに haproxy.router.openshift.io/rewrite-target アノテーションを設定すると、要求をバックエンドアプリケーションに転送する前に Ingress コントローラーがこのルートを使用して HTTP 要求のパスを書き換える必要があることを指定します。spec.path で指定されたパスに一致する要求パスの一部は、アノテーションで指定された書き換えターゲットに置き換えられます。
以下の表は、spec.path、要求パス、および書き換えターゲットの各種の組み合わせについてのパスの書き換え動作の例を示しています。
表8.3 rewrite-target の例:
| Route.spec.path | 要求パス | 書き換えターゲット | 転送された要求パス |
|---|---|---|---|
| /foo | /foo | / | / |
| /foo | /foo/ | / | / |
| /foo | /foo/bar | / | /bar |
| /foo | /foo/bar/ | / | /bar/ |
| /foo | /foo | /bar | /bar |
| /foo | /foo/ | /bar | /bar/ |
| /foo | /foo/bar | /baz | /baz/bar |
| /foo | /foo/bar/ | /baz | /baz/bar/ |
| /foo/ | /foo | / | 該当なし (要求パスがルートパスに一致しない) |
| /foo/ | /foo/ | / | / |
| /foo/ | /foo/bar | / | /bar |
8.1.7. Ingress オブジェクトを介してデフォルトの証明書を使用してルートを作成する
TLS 設定を指定せずに Ingress オブジェクトを作成すると、Red Hat OpenShift Service on AWS は安全でないルートを生成します。デフォルトの Ingress 証明書を使用してセキュアなエッジ終端ルートを生成する Ingress オブジェクトを作成するには、次のように空の TLS 設定を指定できます。
前提条件
- 公開したいサービスがあります。
-
OpenShift CLI (
oc) にアクセスできる。
手順
Ingress オブジェクトの YAML ファイルを作成します。この例では、ファイルの名前は
example-ingress.yamlです。Ingress オブジェクトの YAML 定義
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frontend ... spec: rules: ... tls: - {} 1- 1
- この正確な構文を使用して、カスタム証明書を指定せずに TLS を指定します。
次のコマンドを実行して、Ingress オブジェクトを作成します。
$ oc create -f example-ingress.yaml
検証
次のコマンドを実行して、Red Hat OpenShift Service on AWS が Ingress オブジェクトの想定されるルートを作成したことを確認します。
$ oc get routes -o yaml
出力例
apiVersion: v1 items: - apiVersion: route.openshift.io/v1 kind: Route metadata: name: frontend-j9sdd 1 ... spec: ... tls: 2 insecureEdgeTerminationPolicy: Redirect termination: edge 3 ...
8.1.8. Ingress アノテーションでの宛先 CA 証明書を使用したルート作成
route.openshift.io/destination-ca-certificate-secret アノテーションを Ingress オブジェクトで使用して、カスタム宛先 CA 証明書でルートを定義できます。
前提条件
- PEM エンコードされたファイルで証明書/キーのペアを持つことができます。ここで、証明書はルートホストに対して有効となっています。
- 証明書チェーンを完了する PEM エンコードされたファイルの別の CA 証明書が必要です。
- PEM エンコードされたファイルの別の宛先 CA 証明書が必要です。
- 公開する必要のあるサービスが必要です。
手順
route.openshift.io/destination-ca-certificate-secretを Ingress アノテーションに追加します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frontend annotations: route.openshift.io/termination: "reencrypt" route.openshift.io/destination-ca-certificate-secret: secret-ca-cert 1 ...- 1
- アノテーションは kubernetes シークレットを参照します。
このアノテーションで参照されているシークレットは、生成されたルートに挿入されます。
出力例
apiVersion: route.openshift.io/v1 kind: Route metadata: name: frontend annotations: route.openshift.io/termination: reencrypt route.openshift.io/destination-ca-certificate-secret: secret-ca-cert spec: ... tls: insecureEdgeTerminationPolicy: Redirect termination: reencrypt destinationCACertificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- ...