4.5. 外部およびイングレスルーティング
4.5.1. ルーティングの概要
Knative は OpenShift Container Platform TLS 終端を使用して Knative サービスのルーティングを提供します。Knative サービスが作成されると、OpenShift Container Platform ルートがサービス用に自動的に作成されます。このルートは OpenShift Serverless Operator によって管理されます。OpenShift Container Platform ルートは、OpenShift Container Platform クラスターと同じドメインで Knative サービスを公開します。
OpenShift Container Platform ルーティングの Operator 制御を無効にすることで、Knative ルートを TLS 証明書を直接使用するように設定できます。
Knative ルートは OpenShift Container Platform ルートと共に使用し、トラフィック分割などの詳細なルーティング機能を提供します。
4.5.1.1. 関連情報
4.5.2. ラベルとアノテーションのカスタマイズ
OpenShift Container Platform ルートは、Knative サービスの metadata
仕様を変更して設定できるカスタムラベルおよびアノテーションの使用をサポートします。カスタムラベルおよびアノテーションはサービスから Knative ルートに伝番され、次に Knative ingress に、最後に OpenShift Container Platform ルートに伝播されます。
4.5.2.1. OpenShift Container Platform ルートのラベルおよびアノテーションのカスタマイズ
前提条件
- OpenShift Serverless Operator および Knative Serving が OpenShift Container Platform クラスターにインストールされている必要があります。
-
OpenShift CLI (
oc
) をインストールしている。
手順
OpenShift Container Platform ルートに伝播するラベルまたはアノテーションが含まれる Knative サービスを作成します。
YAML を使用してサービスを作成するには、以下を実行します。
YAML を使用して作成されるサービスの例
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> labels: <label_name>: <label_value> annotations: <annotation_name>: <annotation_value> ...
Knative (
kn
) CLI を使用してサービスを作成するには、次のように入力します。kn
コマンドを使用して作成されるサービスの例$ kn service create <service_name> \ --image=<image> \ --annotation <annotation_name>=<annotation_value> \ --label <label_value>=<label_value>
以下のコマンドからの出力を検査して、OpenShift Container Platform ルートが追加したアノテーションまたはラベルで作成されていることを確認します。
検証のコマンドの例
$ oc get routes.route.openshift.io \ -l serving.knative.openshift.io/ingressName=<service_name> \ 1 -l serving.knative.openshift.io/ingressNamespace=<service_namespace> \ 2 -n knative-serving-ingress -o yaml \ | grep -e "<label_name>: \"<label_value>\"" -e "<annotation_name>: <annotation_value>" 3
4.5.3. Knative サービスのルートの設定
Knative サービスを OpenShift Container Platform で TLS 証明書を使用するように設定するには、OpenShift Serverless Operator によるサービスのルートの自動作成を無効にし、代わりにサービスのルートを手動で作成する必要があります。
以下の手順を完了すると、knative-serving-ingress
namespace のデフォルトの OpenShift Container Platform ルートは作成されません。ただし、アプリケーションの Knative ルートはこの namespace に引き続き作成されます。
4.5.3.1. OpenShift Container Platform ルートでの Knative サービスの設定
前提条件
- OpenShift Serverless Operator および Knative Serving コンポーネントが OpenShift Container Platform クラスターにインストールされている。
-
OpenShift CLI (
oc
) をインストールしている。
手順
serving.knative.openshift.io/disableRoute=true
アノテーションが含まれる Knative サービスを作成します。重要serving.knative.openshift.io/disableRoute=true
アノテーションは、OpenShift Serverless に対してルートを自動的に作成しないように指示します。ただし、サービスには URL が表示され、ステータスがReady
に達します。URL のホスト名と同じホスト名を使用して独自のルートを作成するまで、この URL は外部では機能しません。Service
サービスリソースを作成します。リソースの例
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> annotations: serving.knative.openshift.io/disableRoute: "true" spec: template: spec: containers: - image: <image> ...
Service
リソースを適用します。$ oc apply -f <filename>
オプション:
kn service create
コマンドを使用して Knative サービスを作成します。kn
コマンドの例$ kn service create <service_name> \ --image=gcr.io/knative-samples/helloworld-go \ --annotation serving.knative.openshift.io/disableRoute=true
サービス用に OpenShift Container Platform ルートが作成されていないことを確認します。
コマンドの例
$ $ oc get routes.route.openshift.io \ -l serving.knative.openshift.io/ingressName=$KSERVICE_NAME \ -l serving.knative.openshift.io/ingressNamespace=$KSERVICE_NAMESPACE \ -n knative-serving-ingress
以下の出力が表示されるはずです。
No resources found in knative-serving-ingress namespace.
knative-serving-ingress
namespace でRoute
リソースを作成します。apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/timeout: 600s 1 name: <route_name> 2 namespace: knative-serving-ingress 3 spec: host: <service_host> 4 port: targetPort: http2 to: kind: Service name: kourier weight: 100 tls: insecureEdgeTerminationPolicy: Allow termination: edge 5 key: |- -----BEGIN PRIVATE KEY----- [...] -----END PRIVATE KEY----- certificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- caCertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE---- wildcardPolicy: None
- 1
- OpenShift Container Platform ルートのタイムアウト値。
max-revision-timeout-seconds
設定と同じ値を設定する必要があります (デフォルトでは600s
)。 - 2
- OpenShift Container Platform ルートの名前。
- 3
- OpenShift Container Platform ルートの namespace。これは
knative-serving-ingress
である必要があります。 - 4
- 外部アクセスのホスト名。これを
<service_name>-<service_namespace>.<domain>
に設定できます。 - 5
- 使用する証明書。現時点で、
edge
termination のみがサポートされています。
Route
リソースを適用します。$ oc apply -f <filename>
4.5.4. グローバル HTTPS リダイレクト
HTTPS リダイレクトは、着信 HTTP リクエストのリダイレクトを提供します。これらのリダイレクトされた HTTP リクエストは暗号化されます。KnativeServing
カスタムリソース (CR) の httpProtocol
仕様を設定して、クラスターのすべてのサービスに対して HTTPS リダイレクトを有効にできます。
4.5.4.1. HTTPS リダイレクトのグローバル設定
HTTPS リダイレクトを有効にする KnativeServing
CR の例
apiVersion: operator.knative.dev/v1beta1 kind: KnativeServing metadata: name: knative-serving spec: config: network: httpProtocol: "redirected" ...
4.5.5. 外部ルートの URL スキーム
セキュリティーを強化するために、外部ルートの URL スキームはデフォルトで HTTPS に設定されています。このスキームは、KnativeServing
カスタムリソース (CR) 仕様の default-external-scheme
キーによって決定されます。
4.5.5.1. 外部ルートの URL スキームの設定
デフォルト仕様
... spec: config: network: default-external-scheme: "https" ...
default-external-scheme
キーを変更することにより、HTTP を使用するようにデフォルトの仕様をオーバーライドできます。
HTTP オーバーライド仕様
... spec: config: network: default-external-scheme: "http" ...
4.5.6. サービスごとの HTTPS リダイレクト
networking.knative.dev/http-option
アノテーションを設定することにより、サービスの HTTPS リダイレクトを有効または無効にできます。
4.5.6.1. サービスの HTTPS のリダイレクト
次の例は、Knative Service
YAML オブジェクトでこのアノテーションを使用する方法を示しています。
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example namespace: default annotations: networking.knative.dev/http-option: "redirected" spec: ...
4.5.7. クラスターローカルの可用性
デフォルトで、Knative サービスはパブリック IP アドレスに公開されます。パブリック IP アドレスに公開されているとは、Knative サービスがパブリックアプリケーションであり、一般にアクセス可能な URL があることを意味します。
一般にアクセス可能な URL は、クラスター外からアクセスできます。ただし、開発者は プライベートサービス と呼ばれるクラスター内からのみアクセス可能なバックエンドサービスをビルドする必要がある場合があります。開発者は、クラスター内の個々のサービスに networking.knative.dev/visibility=cluster-local
ラベルを使用してラベル付けし、それらをプライベートにすることができます。
OpenShift Serverless 1.15.0 以降のバージョンの場合には、serving.knative.dev/visibility
ラベルは利用できなくなりました。既存のサービスを更新して、代わりに networking.knative.dev/visibility
ラベルを使用する必要があります。
4.5.7.1. クラスターローカルへのクラスター可用性の設定
前提条件
- OpenShift Serverless Operator および Knative Serving がクラスターにインストールされている。
- Knative サービスを作成している。
手順
networking.knative.dev/visibility=cluster-local
ラベルを追加して、サービスの可視性を設定します。$ oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local
検証
以下のコマンドを入力して出力を確認し、サービスの URL の形式が
http://<service_name>.<namespace>.svc.cluster.local
であることを確認します。$ oc get ksvc
出力例
NAME URL LATESTCREATED LATESTREADY READY REASON hello http://hello.default.svc.cluster.local hello-tx2g7 hello-tx2g7 True
4.5.7.2. クラスターローカルサービスの TLS 認証の有効化
クラスターローカルサービスの場合、Kourier ローカルゲートウェイ kourier-internal
が使用されます。Kourier ローカルゲートウェイに対して TLS トラフィックを使用する場合は、ローカルゲートウェイで独自のサーバー証明書を設定する必要があります。
前提条件
- OpenShift Serverless Operator および Knative Serving がインストールされていること。
- 管理者権限がある。
-
OpenShift (
oc
) CLI がインストールされている。
手順
サーバー証明書を
knative-serving-ingress
namespace にデプロイします。$ export san="knative"
注記これらの証明書が
<app_name>.<namespace>.svc.cluster.local
への要求を処理できるように、Subject Alternative Name (SAN) の検証が必要です。ルートキーと証明書を生成します。
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \ -subj '/O=Example/CN=Example' \ -keyout ca.key \ -out ca.crt
SAN 検証を使用するサーバーキーを生成します。
$ openssl req -out tls.csr -newkey rsa:2048 -nodes -keyout tls.key \ -subj "/CN=Example/O=Example" \ -addext "subjectAltName = DNS:$san"
サーバー証明書を作成します。
$ openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") \ -days 365 -in tls.csr \ -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
Courier ローカルゲートウェイのシークレットを設定します。
前の手順で作成した証明書から、
knative-serving-ingress
namespace にシークレットをデプロイします。$ oc create -n knative-serving-ingress secret tls server-certs \ --key=tls.key \ --cert=tls.crt --dry-run=client -o yaml | oc apply -f -
KnativeServing
カスタムリソース (CR) 仕様を更新して、Kourier ゲートウェイによって作成されたシークレットを使用します。KnativeServing CR の例
... spec: config: kourier: cluster-cert-secret: server-certs ...
Kourier コントローラーはサービスを再起動せずに証明書を設定するため、Pod を再起動する必要はありません。
クライアントから ca.crt
をマウントして使用することにより、ポート 443
経由で TLS を使用して Kourier 内部サービスにアクセスできます。
4.5.8. Kourier Gateway サービスタイプ
Kourier Gateway は、デフォルトで ClusterIP
サービスタイプとして公開されます。このサービスタイプは、KnativeServing
カスタムリソース (CR) の service-type
入力仕様によって決定されます。
デフォルト仕様
... spec: ingress: kourier: service-type: ClusterIP ...
4.5.8.1. Kourier Gateway サービスタイプの設定
service-type
仕様を変更することで、デフォルトのサービスタイプをオーバーライドして、代わりにロードバランサーサービスタイプを使用できます。
LoadBalancer オーバーライド仕様
... spec: ingress: kourier: service-type: LoadBalancer ...
4.5.9. HTTP2 と gRPC の使用
OpenShift Serverless はセキュアでないルートまたは edge termination ルートのみをサポートします。非セキュアなルートまたは edge termination ルートは OpenShift Container Platform で HTTP2 をサポートしません。gRPC は HTTP2 によって転送されるため、これらのルートは gRPC もサポートしません。アプリケーションでこれらのプロトコルを使用する場合は、Ingress ゲートウェイを使用してアプリケーションを直接呼び出す必要があります。これを実行するには、Ingress ゲートウェイのパブリックアドレスとアプリケーションの特定のホストを見つける必要があります。
4.5.9.1. HTTP2 および gRPC を使用したサーバーレスアプリケーションとの対話
この方法は、OpenShift Container Platform 4.10 以降に適用されます。古いバージョンについては、以下のセクションを参照してください。
前提条件
- OpenShift Serverless Operator および Knative Serving をクラスターにインストールします。
-
OpenShift CLI (
oc
) をインストールしている。 - Knative サービスを作成します。
- OpenShift Container Platform 4.10 以降をアップグレードします。
- OpenShift Ingress コントローラーで HTTP/2 を有効にします。
手順
serverless.openshift.io/default-enable-http2=true
アノテーションをKnativeServing
カスタムリソースに追加します。$ oc annotate knativeserving <your_knative_CR> -n knative-serving serverless.openshift.io/default-enable-http2=true
アノテーションが追加されたら、Kourier サービスの
appProtocol
値がh2c
であることを確認できます。$ oc get svc -n knative-serving-ingress kourier -o jsonpath="{.spec.ports[0].appProtocol}"
出力例
h2c
以下のように、外部トラフィックに HTTP/2 プロトコルで gRPC フレームワークを使用できるようになりました。
import "google.golang.org/grpc" grpc.Dial( YOUR_URL, 1 grpc.WithTransportCredentials(insecure.NewCredentials())), 2 )
4.5.9.2. OpenShift Container Platform 4.9 以前での HTTP2 および gRPC を使用したサーバーレスアプリケーションとの対話
この方法は、LoadBalancer
サービスタイプを使用して Kourier Gateway を公開する必要があります。これは、以下の YAML を KnativeServing
カスタムリソース定義 (CRD) に追加して設定できます。
... spec: ingress: kourier: service-type: LoadBalancer ...
前提条件
- OpenShift Serverless Operator および Knative Serving をクラスターにインストールします。
-
OpenShift CLI (
oc
) をインストールしている。 - Knative サービスを作成します。
手順
- アプリケーションホストを検索します。サーバーレスアプリケーションのデプロイメントの確認の説明を参照してください。
Ingress ゲートウェイのパブリックアドレスを見つけます。
$ oc -n knative-serving-ingress get svc kourier
出力例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kourier LoadBalancer 172.30.51.103 a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com 80:31380/TCP,443:31390/TCP 67m
パブリックアドレスは
EXTERNAL-IP
フィールドで表示され、この場合はa83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
になります。HTTP 要求のホストヘッダーを手動でアプリケーションのホストに手動で設定しますが、Ingress ゲートウェイのパブリックアドレスに対して要求自体をダイレクトします。
$ curl -H "Host: hello-default.example.com" a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
出力例
Hello Serverless!
Ingress ゲートウェイに対して直接 gRPC 要求を行うこともできます。
import "google.golang.org/grpc" grpc.Dial( "a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com:80", grpc.WithAuthority("hello-default.example.com:80"), grpc.WithInsecure(), )
注記直前の例のように、それぞれのポート (デフォルトでは 80) を両方のホストに追加します。